<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <style> body { margin: 0; overflow: hidden; } #map { width: 100%; height: 100%; } #data { position: absolute; left: 0; bottom: 0; right: 0; height: 64px; padding: 0; border: 0; background: rgba(0, 0, 0, 0.5); font-family: Consolas; font-size: 8px; color: rgb(255, 255, 255); overflow: auto; z-index: 1000; } #data:focus { outline: none; } .flag { position: absolute; width: 8px; height: 8px; margin-left: -4px; margin-top: -4px; -moz-border-radius: 1px; -webkit-border-radius: 1px; -moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, 128); -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 128); } .flag:hover { width: 16px; height: 16px; margin-left: -8px; margin-top: -8px; opacity: 0.5; -moz-border-radius: 2px; -webkit-border-radius: 2px; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 128); -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 128); } .rect { position: absolute; border: 1px solid rgb(255, 255, 255); z-index: 1; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 128); -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 128); } </style> <script src="../../../build/Ox.js"></script> <script src="http://maps.google.com/maps/api/js?sensor=false"></script> <script> /* this adds the properties area, east, lat, lng, north, south, west */ Ox.load('UI', {debug: true}, function() { Ox.getJSON('../json/geo.json', function(geo) { var $body = $('body'), $map = $('<img>') .attr({ id: 'map', src: '../png/map.png' }) .appendTo($body), $data = $('<textarea>') .attr({ id: 'data' }) .appendTo($body), geocoder = new google.maps.Geocoder(), json = [], logs = [], timeout = 2000; // fixme: getJSON fails in jQuery 1.5 $.ajax({ url: '../json/countries.json', dataType: 'json', success: function(countries) { callGetData(); function callGetData() { getData(countries.shift(), function(country) { addFlag(country); delete country.googleQuery; json.push(country); $data.html( JSON.stringify(json, null, 4) ); window.status = json.length + '/' + countries.length + ' ' + country.name; Ox.print(logs); if (countries.length) { setTimeout(callGetData, timeout); } else { alert('Done'); } }); } } }); function addFlag(country) { var $div, center = Ox.getXYByLatLng({lat: country.lat, lng: country.lng}), crossesDateline = country.west > country.east, height = $map.height(), northEast = Ox.getXYByLatLng({lat: country.north, lng: country.east}), southWest = Ox.getXYByLatLng({lat: country.south, lng: country.west}), width = $map.width(); if (crossesDateline) { $div = [ $('<div>') .addClass('rect') .css({ left: '-16px', top: (height * northEast.y) + 'px', right: (width - width * northEast.x) + 'px', bottom: (height - height * southWest.y) + 'px', }) .hide() .appendTo($body), $('<div>') .addClass('rect') .css({ left: (width * southWest.x) + 'px', top: (height * northEast.y) + 'px', right: '-16px', bottom: (height - height * southWest.y) + 'px', }) .hide() .appendTo($body), ]; } else { $div = [ $('<div>') .addClass('rect') .css({ left: ($map.width() * southWest.x) + 'px', top: ($map.height() * northEast.y) + 'px', right: ($map.width() - $map.width() * northEast.x) + 'px', bottom: ($map.height() - $map.height() * southWest.y) + 'px', }) .hide() .appendTo($body) ]; } $('<img>') .attr({ src: '../png/icons/16/' + country.code + '.png', title: country.name + ' ((' + country.south + ", " + country.west + "), (" + country.north + ", " + country.east + "))" }) .addClass('flag') .css({ left: (center.x * 100) + '%', top: (center.y * 100) + '%' }) .mouseenter(function() { $(this).css({ zIndex: Ox.uid() }); $.each($div, function() { $(this).show(); }); }) .mouseleave(function() { $.each($div, function() { $(this).hide(); }); }) .appendTo($body); } function toFixed(num) { return parseFloat(num.toFixed(8)); } function geocode(address, callback) { Ox.print('geocode', address) var bounds = geo.coordinates[address]; if (Ox.isUndefined(bounds)) { geocoder.geocode({ language: 'en', address: address }, function(results, status) { if (results && results.length) { var result = results[0]; callback({ bounds: result.geometry.bounds || result.geometry.viewport, location: result.geometry.location }) } else { logs.push([address, status]) callback(null); } }); } else { bounds = new google.maps.LatLngBounds( new google.maps.LatLng(bounds.south, bounds.west), new google.maps.LatLng(bounds.north, bounds.east) ); callback({ bounds: bounds, location: bounds.getCenter() }); } } function getData(country, callback) { if (country.lat) { callback(country); return; } Ox.print('getData', geo.google_query[country.name] || [country.name]) var addresses = geo.google_query[country.name] || [country.name], length = addresses.length, union; getImageURLs(country, function(imageURLs) { // this might be too much data /* Ox.extend(country, { imageURLs: imageURLs }); */ callGeocode(); }); function callGeocode() { geocode(addresses.shift(), function(data) { var center, lat, lng, northEast, southWest, east, north, south, west; if (data) { union = !union ? data.bounds : union.union(data.bounds); if (addresses.length == 0) { if (length == 1) { lat = data.location.lat(); lng = data.location.lng(); } else { center = union.getCenter(); lat = center.lat(); lng = center.lng(); } northEast = union.getNorthEast(); southWest = union.getSouthWest(); east = northEast.lng(); north = northEast.lat(); south = southWest.lat(); west = southWest.lng(); callback($.extend(country, { area: Ox.getArea( {lat: south, lng: west}, {lat: north, lng: east} ), east: toFixed(east), lat: toFixed(lat), lng: toFixed(lng), north: toFixed(north), south: toFixed(south), west: toFixed(west) })); } } else { callback(country); } }); if (addresses.length) { setTimeout(callGeocode, timeout); } } } function getImageURLs(country, callback) { Ox.print(country, '../png/icon/16/' + country.code + '.png') var image = new Image(); image.onload = function() { callback({ icon16: Ox.canvas(image).canvas.toDataURL() }); }; image.src = '../png/icons/16/' + country.code + '.png'; } }); }); </script> </head> <body></body> </html>