more accurate marker positioning on map, and a reasonable custom projection
This commit is contained in:
150
template.html
150
template.html
@@ -22,6 +22,65 @@
|
||||
debug: false
|
||||
};
|
||||
|
||||
// our custom projection maps Latitude to Y, and Longitude to X as normal,
|
||||
// but it maps the range [0.0, 1.0] to [0, tileSize] in both directions
|
||||
// so it is easier to position markers, etc. based on their position
|
||||
// (find their position in the lowest-zoom image, and divide by tileSize)
|
||||
function MCMapProjection() {
|
||||
this.inverseTileSize = 1.0 / config.tileSize;
|
||||
}
|
||||
|
||||
MCMapProjection.prototype.fromLatLngToPoint = function(latLng) {
|
||||
var x = latLng.lng() * config.tileSize;
|
||||
var y = latLng.lat() * config.tileSize;
|
||||
return new google.maps.Point(x, y);
|
||||
};
|
||||
|
||||
MCMapProjection.prototype.fromPointToLatLng = function(point) {
|
||||
var lng = point.x * this.inverseTileSize;
|
||||
var lat = point.y * this.inverseTileSize;
|
||||
return new google.maps.LatLng(lat, lng);
|
||||
};
|
||||
|
||||
// helper to get map LatLng from world coordinates
|
||||
// takes arguments in X, Y, Z order
|
||||
// (arguments are *out of order*, because within the function we use
|
||||
// the axes like the rest of Minecraft Overviewer -- with the Z and Y
|
||||
// flipped from normal minecraft usage.)
|
||||
function fromWorldToLatLng(x, z, y)
|
||||
{
|
||||
// the width and height of all the highest-zoom tiles combined, inverted
|
||||
var perPixel = 1.0 / (config.tileSize * Math.pow(2, config.maxZoom));
|
||||
|
||||
// This information about where the center column is may change with a different
|
||||
// drawing implementation -- check it again after any drawing overhauls!
|
||||
|
||||
// point (0, 0, 127) is at (0.5, 0.0) of tile (tiles/2 - 1, tiles/2)
|
||||
// so the Y coordinate is at 0.5, and the X is at 0.5 - ((tileSize / 2) / (tileSize * 2^maxZoom))
|
||||
// or equivalently, 0.5 - (1 / 2^(maxZoom + 1))
|
||||
var lng = 0.5 - (1.0 / Math.pow(2, config.maxZoom + 1));
|
||||
var lat = 0.5;
|
||||
|
||||
// the following metrics mimic those in ChunkRenderer.chunk_render in "chunk.py"
|
||||
|
||||
// each block on X axis adds 12px to x and subtracts 6px from y
|
||||
lng += 12 * x * perPixel;
|
||||
lat -= 6 * x * perPixel;
|
||||
|
||||
// each block on Y axis adds 12px to x and adds 6px to y
|
||||
lng += 12 * y * perPixel;
|
||||
lat += 6 * y * perPixel;
|
||||
|
||||
// each block down along Z adds 12px to y
|
||||
lat += 12 * (128 - z) * perPixel;
|
||||
|
||||
// add on 12 px to the X coordinate and 18px to the Y to center our point
|
||||
lng += 12 * perPixel;
|
||||
lat += 18 * perPixel;
|
||||
|
||||
return new google.maps.LatLng(lat, lng);
|
||||
}
|
||||
|
||||
var MCMapOptions = {
|
||||
getTileUrl: function(tile, zoom) {
|
||||
var url = config.path;
|
||||
@@ -52,6 +111,7 @@
|
||||
var MCMapType = new google.maps.ImageMapType(MCMapOptions);
|
||||
MCMapType.name = "MC Map";
|
||||
MCMapType.alt = "Minecraft Map";
|
||||
MCMapType.projection = new MCMapProjection();
|
||||
|
||||
function CoordMapType() {
|
||||
}
|
||||
@@ -75,61 +135,30 @@
|
||||
};
|
||||
|
||||
var map;
|
||||
var prot;
|
||||
|
||||
var markersInit = false;
|
||||
|
||||
function convertCoords (x,y,z) {
|
||||
|
||||
var imgx = 0;
|
||||
var imgy = 0;
|
||||
|
||||
imgx = imgx + (12*x);
|
||||
imgy = imgy - (6*x);
|
||||
|
||||
imgx = imgx + (12 * y);
|
||||
imgy = imgy + (6* y);
|
||||
|
||||
imgy = imgy - (12*z);
|
||||
|
||||
// this math is mysterious. i don't fully understand it
|
||||
// but the idea is to assume that block 0,0,0 in chunk 0,0
|
||||
// is drawn in the very middle of the gmap at (192,192)
|
||||
return [192*Math.pow(2,config.maxZoom)+imgx, 192*Math.pow(2,config.maxZoom)+imgy+768+768];
|
||||
}
|
||||
|
||||
function initMarkers() {
|
||||
if (markersInit) { return; }
|
||||
if (markersInit) { return; }
|
||||
|
||||
markersInit = true;
|
||||
markersInit = true;
|
||||
|
||||
prot = map.getProjection();
|
||||
for (i in markerData) {
|
||||
var item = markerData[i];
|
||||
|
||||
for (i in markerData) {
|
||||
var item = markerData[i];
|
||||
|
||||
var converted = convertCoords(item.x-16, item.z, item.y);
|
||||
|
||||
|
||||
var x = converted[0] / Math.pow(2, config.maxZoom);
|
||||
var y = converted[1] / Math.pow(2, config.maxZoom);
|
||||
var p = new google.maps.Point(x,y);
|
||||
var marker = new google.maps.Marker({
|
||||
position: prot.fromPointToLatLng(p),
|
||||
map: map,
|
||||
title:item.msg
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
var converted = fromWorldToLatLng(item.x, item.y, item.z);
|
||||
var marker = new google.maps.Marker({
|
||||
position: converted,
|
||||
map: map,
|
||||
title: item.msg
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
var mapOptions = {
|
||||
zoom: config.defaultZoom,
|
||||
center: new google.maps.LatLng(-45, 90),
|
||||
center: new google.maps.LatLng(0.5, 0.5),
|
||||
navigationControl: true,
|
||||
scaleControl: false,
|
||||
mapTypeControl: false,
|
||||
@@ -139,34 +168,27 @@ title:item.msg
|
||||
|
||||
if(config.debug) {
|
||||
map.overlayMapTypes.insertAt(0, new CoordMapType(new google.maps.Size(config.tileSize, config.tileSize)));
|
||||
|
||||
google.maps.event.addListener(map, 'click', function(event) {
|
||||
console.log("latLng; " + event.latLng.lat() + ", " + event.latLng.lng());
|
||||
|
||||
var pnt = map.getProjection().fromLatLngToPoint(event.latLng);
|
||||
console.log("point: " + pnt);
|
||||
|
||||
var pxx = pnt.x * config.tileSize * Math.pow(2, config.maxZoom);
|
||||
var pxy = pnt.y * config.tileSize * Math.pow(2, config.maxZoom);
|
||||
console.log("pixel: " + pxx + ", " + pxy);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Now attach the coordinate map type to the map's registry
|
||||
map.mapTypes.set('mcmap', MCMapType);
|
||||
|
||||
// We can now set the map to use the 'coordinate' map type
|
||||
map.setMapTypeId('mcmap');
|
||||
|
||||
prot = map.getProjection();
|
||||
|
||||
if (config.debug)
|
||||
google.maps.event.addListener(map, 'click', function(event) {
|
||||
console.log("latLng: " + event.latLng.lat() + ", " + event.latLng.lng());
|
||||
var pnt = prot.fromLatLngToPoint(event.latLng);
|
||||
|
||||
console.log("point: " + pnt);//
|
||||
var pxx = pnt.x * Math.pow(2,config.maxZoom);
|
||||
var pxy = pnt.y * Math.pow(2,config.maxZoom);
|
||||
console.log("pixel: " + pxx + ", " + pxy);
|
||||
});
|
||||
|
||||
google.maps.event.addListener(map, 'projection_changed', function(event) {
|
||||
initMarkers();
|
||||
});
|
||||
|
||||
|
||||
// initialize the markers
|
||||
initMarkers();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
Reference in New Issue
Block a user