In my recent project, one of its important feature was to be able to display all seaports that currently have ISO Tanks in the world map. To do that, first I need to have a database of seaports complete with the longitude & latitude position. Below is the data-entry form I created.
You can slowly insert the data one-by-one, or you can just scrape the web 🙂
Since Google Map is using decimal Latitude/Longitude value, we need to create a method to convert from degree (e.g. 103° 50′ N) to decimal value (e.g. 103.833) . Here’s my code in C#:
// ---- Code SNIP ------- //Declare the Regex as part of the class member private Regex rgxLatLon = new Regex("((?<degree>[0-9]+)°)((\\ )(?<minute>[0-9]+)')?((\\ )(?<second>[0-9]+)\")?((\\ )(?<dir>(E|S|N|W)))"); // ---- Code SNIP ------- private bool convDegDec(String raw, out double result) { result = 0; var mLat = rgxLatLon.Match(raw); if (mLat.Success) { foreach (var g in mLat.Groups) { var deg = mLat.Groups["degree"].Value; if (!String.IsNullOrEmpty(deg)) result = double.Parse(deg); var min = mLat.Groups["minute"].Value; if (!String.IsNullOrEmpty(min)) result += (double.Parse(min) / 60); var sec = mLat.Groups["second"].Value; if (!String.IsNullOrEmpty(sec)) result += (double.Parse(sec) / 3600); var dir = mLat.Groups["dir"].Value; if (dir == "S" || dir == "W") result = result * (-1); } } return mLat.Success; } // ---- Code SNIP -------
Final step is to actually render Google Maps, add the markers according to Seaports’ position, and display the necessary information when the marker is clicked. I won’t explain on how to use the Google Maps API because they already have a very good official guide.
Anyway, here’s how I render the map, markers and information window:
var map, info = {}; function initialize() { // Centralize the map to Singapore var mapOptions = { center : new google.maps.LatLng(1.2666666666666666, 103.83333333333333), zoom : 6 }; // I have a div with id='map-canvas' as the map's placeholder map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions); //get the Seaports and its Tanks count $.ajax({ // the JSON webservice, add tick to prevent caching url : '/Tank/MapData?_tick=' + Math.random(), dataType : 'json' }).always(function (resp) { var obj = {}; eval("obj = " + resp.responseText); /* Sample JSON object returned by /Tank/MapData: { data : [{ "CurPort" : "PKL", "CurrentPort" : "Port Klang", "decLat" : 3.0, "decLon" : 101.4, "TankCount" : 41 }, { "CurPort" : "SIN", "CurrentPort" : "Singapore", "decLat" : 1.2666666666666666, "decLon" : 103.83333333333333, "TankCount" : 44 }, { "CurPort" : "JKT", "CurrentPort" : "Jakarta", "decLat" : -6.1, "decLon" : 106.86666666666666, "TankCount" : 18 }, { "CurPort" : "KUA", "CurrentPort" : "Kuantan ", "decLat" : 3.9666666666666668, "decLon" : 103.43333333333334, "TankCount" : 47 } ], total : 4 } */ if (obj.data) { $.each(obj.data, function (i, p) { // set marker's position var myLatlng = new google.maps.LatLng(p.decLat, p.decLon); // the info window to show if the marker is clicked // the info window contains a hyperlink to SeaPort's details var infowindow = new google.maps.InfoWindow({ content : "<div class='winInfo'><strong><a href='#' class='liPort' data-port='" + p.CurPort + "'>" + p.CurrentPort.toUpperCase() + "</a></strong><div>Tanks : " + p.TankCount + "</div></div>", disableAutoPan : true }); // create the marker var marker = new google.maps.Marker({ position : myLatlng, map : map, title : p.CurPort }); // add the info window to global collection info[p.CurPort] = infowindow; // if marker is clicked, show the info window google.maps.event.addListener(marker, 'click', function () { info[marker.title].open(map, marker); }); // by default, show the info window infowindow.open(map, marker); }); // bind the click event on the document and use selector // to ensure any new info window's hyperlink is clickable $(document).on('click', '.liPort', {}, function () { var port = $(this).attr('data-port'); var title = $(this).text(); top.Northwind.addTab({ url : '/Tank/Overview?port=' + port, title : title, icon : 'icon-database' }); }); // refresh the map data every 30 seconds setInterval(function () { $.ajax({ url : '/Tank/MapData?_tick=' + Math.random(), dataType : 'json' }).always(function (resp) { var obj = {}; eval("obj = " + resp.responseText); if (obj.data) { $.each(obj.data, function (ii, pp) { var dPort = $(".liPort[data-port='" + pp.CurPort + "']"); if (dPort.length > 0) { dPort.parent().next().html("<div>Tanks : " + pp.TankCount + "</div>"); } }); } }); }, 30000); } }); } // call initialize() when map is fully loaded google.maps.event.addDomListener(window, 'load', initialize);
Here’s how the map will look like:
Good luck on your implementation. I hope it helps, cheers!
loading...
About Hardono
Incoming Search
asp.net, c#, google, javascript, jquery, map, mvc