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


