diff --git a/web_assets/index.html b/web_assets/index.html
index 961dd75..14c6666 100644
--- a/web_assets/index.html
+++ b/web_assets/index.html
@@ -3,17 +3,13 @@
-
-
-
-
-
+
+
+
-
+
diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js
new file mode 100644
index 0000000..3b10189
--- /dev/null
+++ b/web_assets/overviewer.js
@@ -0,0 +1,706 @@
+var overviewer = {
+ 'map': null,
+ 'collections': {
+ 'markerDatas': [],
+ 'markers': {},
+ 'regionDatas': [],
+ 'regions': {},
+ 'overlays': [],
+ 'mapTypes': {},
+ 'infoWindow': null
+ },
+ 'util': {
+ 'initialize': function() {
+ overviewer.util.initializeClassPrototypes();
+ overviewer.util.initializeMapTypes();
+ overviewer.util.initializeMap();
+ overviewer.util.initializeMarkers();
+ overviewer.util.initializeRegions();
+ overviewer.util.createMapControls();
+ },
+ 'initializeClassPrototypes': function() {
+ overviewer.classes.MapProjection.prototype.fromLatLngToPoint = function(latLng) {
+ var x = latLng.lng() * overviewerConfig.CONST.tileSize;
+ var y = latLng.lat() * overviewerConfig.CONST.tileSize;
+ return new google.maps.Point(x, y);
+ };
+
+ overviewer.classes.MapProjection.prototype.fromPointToLatLng = function(point) {
+ var lng = point.x * this.inverseTileSize;
+ var lat = point.y * this.inverseTileSize;
+ return new google.maps.LatLng(lat, lng);
+ };
+
+ overviewer.classes.CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
+ var div = ownerDocument.createElement('DIV');
+ div.innerHTML = '(' + coord.x + ', ' + coord.y + ', ' + zoom + ')';
+ div.innerHTML += '
';
+ div.innerHTML += overviewer.collections.mapTypes[0].getTileUrl(coord, zoom);
+ div.style.width = this.tileSize.width + 'px';
+ div.style.height = this.tileSize.height + 'px';
+ div.style.fontSize = '10';
+ div.style.borderStyle = 'solid';
+ div.style.borderWidth = '1px';
+ div.style.borderColor = '#AAAAAA';
+ return div;
+ };
+ },
+ /**
+ * I think this was old code that was replaced by stuff that is now
+ * in initializeMap()
+ */
+ 'initializeMapTypes': function() {
+ var mapOptions = {};
+ for (i in overviewerConfig.mapTypes) {
+ var view = overviewerConfig.mapTypes[i];
+ var imageFormat = view.imgformat ? view.imgformat : 'png';
+ mapOptions[view.label] = {
+ 'getTileUrl': overviewer.gmap.getTileUrlGenerator(view.path,
+ view.base, imageFormat),
+ 'tileSize': new google.maps.Size(
+ overviewerConfig.CONST.tileSize,
+ overviewerConfig.CONST.tileSize),
+ 'maxZoom': overviewerConfig.map.maxZoom,
+ 'minZoom': overviewerConfig.map.minZoom,
+ 'isPng': imageFormat.toLowerCase() == 'png'
+ }
+ overviewer.collections.mapTypes[view.label] = new google.maps.ImageMapType(
+ mapOptions[view.label]);
+ overviewer.collections.mapTypes[view.label].name = view.label;
+ overviewer.collections.mapTypes[view.label].alt = 'Minecraft ' +
+ view.label + ' Map';
+ overviewer.collections.mapTypes[view.label].projection =
+ new overviewer.classes.MapProjection();
+ if (view.overlay) {
+ overviewer.collections.overlays.push(
+ overviewer.collections.mapTypes[view.label]);
+ } else {
+ overviewer.collections.mapTypeIds.push(
+ overviewerConfig.CONST.mapDivId + view.label);
+ }
+ }
+ },
+ 'initilizeMap': function() {
+ var defaultCenter = overviewer.util.fromWorldToLatLng(
+ overviewerConfig.map.center[0], overviewerConfig.map.center[1],
+ overviewerConfig.map.center[2]);
+ var lat = defaultCenter.lat();
+ var lng = defaultCenter.lng();
+ var zoom = overviewerConfig.map.defaultZoom;
+ var mapcenter;
+ queryParams = overviewer.util.parseQueryString();
+ if (queryParams.lat) {
+ lat = parseFloat(queryParams.lat);
+ }
+ if (queryParams.lng) {
+ lng = parseFloat(queryParams.lng);
+ }
+ if (queryParams.zoom) {
+ if (queryParams.zoom == 'max') {
+ zoom = overviewerConfig.map.maxZoom;
+ } else if (queryParams.zoom == 'min') {
+ zoom = overviewerConfig.map.minZoom;
+ } else {
+ zoom = parseInt(queryParams.zoom);
+ if (zoom < 0 && zoom + overvierConfig.map.maxZoom >= 0) {
+ //if zoom is negative, try to treat as "zoom out from max zoom"
+ zoom += overviewerConfig.map.maxZoom;
+ } else {
+ //fall back to default zoom
+ zoom = overviewerConfig.map.defaultZoom;
+ }
+ }
+ }
+ if (queryParams.x && queryParams.y && queryParams.z) {
+ mapcenter = overviewer.util.fromWorldToLatLng(queryParams.x,
+ queryParams.y, queryParams.z);
+ // Add a market indicating the user-supplied position
+ overviewer.collections.markers.push({
+ 'msg': 'Coordinates ' + queryParams.x + ', ' +
+ queryParams.y + ', ' + queryParams.z,
+ 'y': parseFloat(queryParams.y),
+ 'x': parseFloat(queryParams.x),
+ 'z': parseFloat(queryParams.z),
+ 'type': 'querypos'});
+ } else {
+ mapcenter = new google.maps.LatLng(lat, lng);
+ }
+ var mapOptions = {
+ zoom: zoom,
+ center: mapcenter,
+ navigationControl: overviewerConfig.map.controls.navigation,
+ scaleControl: false,
+ mapTypeControl: overviewer.collections.mapTypeIds.length > 1,
+ mapTypeControlOptions: {
+ mapTypeIds: overviewer.collections.mapTypeIds
+ },
+ mapTypeId: overviewer.util.getDefaultMapTypeId(),
+ streetViewControl: false
+ };
+ overviewer.map = new google.maps.Map(document.getElementById(
+ overviewerConfig.CONST.mapDivId), mapOptions);
+
+ if (overviewerConfig.map.debug) {
+ overviewer.map.overlayMapTypes.insertAt(0,
+ new CoordMapType(new google.maps.Size(
+ overviewerConfig.CONST.tileSize,
+ overviewerConfig.CONST.tileSize)));
+ google.maps.event.addListener(overviewer.map, 'click', function(event) {
+ overviewer.util.debug('latLng: (' + event.latLng.lat() +
+ ', ' + event.latLng.lng() + ')');
+ var pnt = overviewer.map.getProjection().fromLatLngToPoint(event.latLng);
+ overviewer.util.debug('point: ' + pnt);
+ var pxx = pnt.x * config.tileSize * Math.pow(2, config.maxZoom);
+ var pxy = pnt.y * config.tileSize * Math.pow(2, config.maxZoom);
+ overviewer.util.debug('pixel: (' + pxx + ', ' + pxy + ')');
+ });
+ }
+
+ // Now attach the coordinate map type to the map's registry
+ for (i in overviewer.collections.mapTypes) {
+ overviewer.map.mapTypes.set(overviewerConfig.CONST.mapDivId +
+ overviewer.collections.mapTypes[i].name,
+ overviewer.collections.mapTypes[i]);
+ }
+
+ // Make the link again whenever the map changes
+ google.maps.event.addListener(overviewer.map, 'zoom_changed', function() {
+ overviewer.util.setViewUrl();
+ });
+ google.maps.event.addListener(overviewer.map, 'center_changed', function() {
+ overviewer.util.setViewUrl();
+ });
+ google.maps.event.addListener(overviewer.map, 'maptypeid_changed', function() {
+ var newType = overviewer.map.getMapTypeId();
+ for(i in overviewerConfig.mapTypes) {
+ if( overviewerConfig.CONST.mapDivId +
+ overviewerConfig.mapTypes[i].label == newType ) {
+ $('#'+overviewerConfig.CONST.mapDivId).css(
+ 'background-color', overviewerConfig.mapTypes[i].bg_color);
+ break;
+ }
+ }
+ });
+ // We can now set the map to use the 'coordinate' map type
+ overviewer.map.setMapTypeId(overviewer.util.getDefaultMapTypeId());
+ },
+ 'initializeMarkers': function() {
+ //first, give all collections an empty array to work with
+ for (i in overviewerConfig.objectGroups.markers) {
+ overviewer.collections.markers[
+ overviewerConfig.objectGroups.markers[i].label] = [];
+ }
+ for (i in overviewer.collections.markerDatas) {
+ var markerData = overviewer.collections.markerDatas[i];
+ for (j in markerData) {
+ var item = markerData[j];
+ // a default:
+ var iconURL = '';
+ if (item.type == 'spawn') {
+ // don't filter spawn, always display
+ var marker = new google.maps.Marker({
+ 'position': overviewer.util.fromWorldToLatLng(item.x,
+ item.y, item.z),
+ 'map': overviewer.map,
+ 'title': jQuery.trim(item.msg),
+ 'icon': overviewerConfig.CONST.image.spawnMarker
+ });
+ continue;
+ }
+
+ if (item.type == 'querypos') {
+ // Set on page load if MC x/y/z coords are given in the
+ // query string
+ var marker = new google.maps.Marker({
+ 'position': overviewer.util.fromWorldToLatLng(item.x,
+ item.y, item.z),
+ 'map': overviewer.map,
+ 'title': jQuery.trim(item.msg),
+ 'icon': overviewerConfig.CONST.image.queryMarker
+ });
+ continue;
+ }
+
+ var matched = false;
+ for (j in overviewerConfig.objectGroups.signs) {
+ var signGroup = overviewerConfig.objectGroups.signs[j];
+ var label = signGroup.label;
+ if (signGroup.match(item)) {
+ matched = true;
+ // can add custom types of images for externally defined
+ // item types, like 'command' here.
+ if (item.type == 'sign') {
+ iconURL = overviewerConfig.CONST.image.signMarker;
+ }
+ overviewer.util.debug('Sign icon: ' + signGroup.icon);
+ if (signGroup.icon) {
+ iconURL = signGroup.icon;
+ }
+ var converted = fromWorldToLatLng(item.x, item.y, item.z);
+ var marker = new google.maps.Marker({
+ 'position': overviewer.util.fromWorldToLatLng(item.x,
+ item.y, item.z),
+ 'map': overviewer.map,
+ 'title': jQuery.trim(item.msg),
+ 'icon': iconURL,
+ 'visible': false
+ });
+ overviewer.collections.markers[label].push(marker);
+ if (item.type == 'sign') {
+ overviewer.util.createMarkerInfoWindow(marker);
+ }
+ }
+ }
+
+ if (!matched) {
+ // is this signpost doesn't match any of the groups in
+ // config.js, add it automatically to the "__others__" group
+ if (item.type == 'sign') {
+ iconURL = overviewerConfig.CONST.image.signMarker;
+ }
+ var marker = new google.maps.Marker({position: converted,
+ 'position': overviewer.util.fromWorldToLatLng(item.x,
+ item.y, item.z),
+ 'map': overviewer.map,
+ 'title': jQuery.trim(item.msg),
+ 'icon': iconURL,
+ 'visible': false
+ });
+ if (overviewer.collections.markers['__others__']) {
+ overviewer.collections.markers['__others__'].push(marker);
+ } else {
+ overviewer.collections.markers['__others__'] = [marker];
+ }
+ if (item.type == 'sign') {
+ overviewer.util.createMarkerInfoWindow(marker, item);
+ }
+ }
+ }
+ }
+ },
+ 'initializeRegions': function() {
+ for (i in overviewerConfig.objectGroups.regions) {
+ overviewer.collections.regions[overviewerConfig.objectGroups.regions[i].label] = [];
+ }
+ for (i in overviewer.collections.regionDatas) {
+ var regionData = overviewer.collections.regionDatas[i];
+ for (j in regionData) {
+ var region = regionData[j];
+ // pull all the points out of the regions file.
+ var converted = new google.maps.MVCArray();
+ for (k in region.path) {
+ var point = region.path[k];
+ converted.push(overviewer.util.fromWorldToLatLng(
+ point.x, point.y, point.z));
+
+ }
+ for (k in overviewerConfig.objectGroups.regions) {
+ var regionGroup = overviewerConfig.objectGroups.regions[k];
+ var clickable = regionGroup.clickable;
+ var label = regionGroup.label;
+
+ if(region.label) {
+ var name = region.label
+ } else {
+ var name = 'rawr';
+ clickable = false; // if it doesn't have a name, we dont have to show it.
+ }
+
+ if (region.closed) {
+ var shape = new google.maps.Polygon({
+ 'name': name,
+ 'clickable': clickable,
+ 'geodesic': false,
+ 'map': null,
+ 'strokeColor': region.color,
+ 'strokeOpacity': region.opacity,
+ 'strokeWeight': overviewerConfig.CONST.regionStrokeWeight,
+ 'fillColor': region.color,
+ 'fillOpacity': region.opacity * 0.25,
+ 'zIndex': j,
+ 'paths': converted
+ });
+ } else {
+ var shape = new google.maps.Polyline({
+ 'name': name,
+ 'clickable': clickable,
+ 'geodesic': false,
+ 'map': null,
+ 'strokeColor': region.color,
+ 'strokeOpacity': region.opacity,
+ 'strokeWeight': overviewerConfig.CONST.regionStrokeWeight,
+ 'zIndex': j,
+ 'path': converted
+ });
+ }
+ overviewer.collections.regions[label].push(shape);
+
+ if (clickable) {
+ overviewer.util.createRegionInfoWindow(shape);
+ }
+ }
+ }
+ }
+ },
+ 'debug': function(msg) {
+ if (overviewerConfig.map.debug) {
+ console.log(msg);
+ }
+ },
+ 'parseQueryString': function() {
+ var results = {};
+ var queryString = location.search.substring(1);
+ var pairs = queryString.split('&');
+ for (i in pairs) {
+ var pos = pairs[i].indexOf('=');
+ var key = pairs[i].substring(0,pos).toLowerCase();
+ var value = pairs[i].substring(pos+1).toLowerCase();
+ overviewer.util.debug( 'Found GET paramter: ' + key + ' = ' + value);
+ results[key] = value;
+ }
+ return results;
+ },
+ 'setViewUrl': function() {
+ var displayZoom = overviewer.map.getZoom();
+ if (displayZoom == overviewerConfig.map.maxZoom) {
+ displayZoom = 'max';
+ } else {
+ displayZoom -= overviewerConfig.map.maxZoom;
+ }
+ var point;
+ var point = overviewer.util.fromLatLngToWorld(
+ overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng());
+ var viewUrl = location.href.substring(0, location.href.lastIndexOf(
+ location.search))
+ + '?x=' + Math.floor(point.x)
+ + '&y=' + Math.floor(point.y)
+ + '&z=' + Math.floor(point.z)
+ + '&zoom=' + displayZoom;
+ document.getElementById('link').innerHTML = viewUrl;
+
+ },
+ 'getDefaultMapTypeId': function() {
+ return overviewer.collections.mapTypeIds[0];
+ },
+ 'fromWorldToLatLng': function(x, z, y) {
+ // the width and height of all the highest-zoom tiles combined,
+ // inverted
+ var perPixel = 1.0 / (overviewerConfig.CONST.tileSize *
+ Math.pow(2, overviewerConfig.map.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, overviewerConfig.map.maxZoom + 1));
+ var lat = 0.5;
+
+ // the following metrics mimic those in ChunkRenderer.chunk_render
+ // in "chunk.py" or, equivalently, chunk_render in src/iterate.c
+
+ // 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 to center our point
+ lng += 12 * perPixel;
+
+ return new google.maps.LatLng(lat, lng);
+ },
+ 'fromLatLngToWorld': function(lat, lng) {
+ // Initialize world x/y/z object to be returned
+ var point = Array();
+ point.x = 0;
+ point.y = 64;
+ point.z = 0;
+
+ // the width and height of all the highest-zoom tiles combined,
+ // inverted
+ var perPixel = 1.0 / (overviewerConfig.CONST.tileSize *
+ Math.pow(2, overviewerConfig.map.maxZoom));
+
+ // Revert base positioning
+ // See equivalent code in fromWorldToLatLng()
+ lng -= 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1));
+ lat -= 0.5;
+
+ // I'll admit, I plugged this into Wolfram Alpha:
+ // a = (x * 12 * r) + (z * 12 * r), b = (z * 6 * r) - (x * 6 * r)
+ // And I don't know the math behind solving for for X and Z given
+ // A (lng) and B (lat). But Wolfram Alpha did. :) I'd welcome
+ // suggestions for splitting this up into long form and documenting
+ // it. -RF
+ point.x = (lng - 2 * lat) / (24 * perPixel)
+ point.z = (lng + 2 * lat) / (24 * perPixel)
+
+ // Adjust for the fact that we we can't figure out what Y is given
+ // only latitude and longitude, so assume Y=64.
+ point.x += 64 + 1;
+ point.z -= 64 + 2;
+
+ return point;
+ },
+ 'createMapControls': function() {
+ // viewstate link (little link to where you're looking at the map,
+ // normally bottom left)
+ var viewStateDiv = document.createElement('DIV');
+ viewStateDiv.id='link';
+ // add it to the map, bottom left.
+ map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(viewStateDiv);
+
+ // compass rose, in the top right corner
+ var compassDiv = document.createElement('DIV');
+ compassDiv.style.padding = '5px';
+ var compassImg = document.createElement('IMG');
+ compassImg.src = overviewerConfig.CONST.image.compass;
+ compassDiv.appendChild(compassImg);
+ compassDiv.index = 0;
+ // add it to the map, top right.
+ map.controls[google.maps.ControlPosition.TOP_RIGHT].push(compassDiv);
+
+ // Spawn button
+ var homeControlDiv = document.createElement('DIV');
+ var homeControl = new overviewer.classes.HomeControl(homeControlDiv);
+ homeControlDiv.id = 'customControl';
+ homeControlDiv.index = 1;
+ overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv);
+
+ // only need to create the control if there are items in the list.
+ // as defined in config.js
+ if (overviewerConfig.objectGroups.signs.length > 0) {
+ // signpost display control
+ var items = [];
+ for (i in overviewerConfig.objectGroups.signs) {
+ var signGroup = overviewerConfig.objectGroups.signs[i];
+ var iconURL = signGroup.icon;
+ if(!iconURL) {
+ iconURL = overviewerConfig.CONST.image.defaultMarker;
+ }
+ items.push({
+ 'label': signGroup.label,
+ 'checked': signGroup.checked,
+ 'icon': iconURL,
+ 'action': function(n, item, checked) {
+ jQuery.each(overviewer.collections.markers[item.label],
+ function(i,elem) {
+ elem.setVisible(checked);
+ }
+ );
+ overviewer.util.debug('Adding sign item: ' + item.label);
+ }
+ });
+ }
+ overviewer.util.createDropDown('Signposts', items);
+ }
+
+ // if there are any regions data, lets show the option to hide/show them.
+ if (overviewerConfig.objectGroups.regions.length > 0) {
+ // region display control
+ var items = [];
+ for (i in overviewerConfig.objectGroups.regions) {
+ var regionGroup = overviewerConfig.objectGroups.regions[i];
+ items.push({
+ 'label': regionGroup.label,
+ 'checked': regionGroup.checked,
+ 'action': function(n, item, checked) {
+ jQuery.each(overviewer.collections.regions[item.label],
+ function(i,elem) {
+ // Thanks to LeastWeasel for this line!
+ elem.setMap(checked ? overviewer.map : null);
+ }
+ );
+ }
+ });
+ }
+ overviewer.util.createDropDown('Regions', items);
+ }
+
+ if (overviewer.collections.overlays.length > 0) {
+ // overlay maps control
+ var items = [];
+ for (i in overviewer.collections.overlays) {
+ var overlay = overviewer.collections.overlays[i];
+ items.push({
+ 'label': overlay.name,
+ 'checked': false,
+ 'overlay': overlay,
+ 'action': function(i, item, checked) {
+ if (checked) {
+ overviewer.map.overlayMapTypes.push(item.overlay);
+ } else {
+ var idx_to_delete = -1;
+ overviewer.map.overlayMapTypes.forEach(function(e, j) {
+ if (e == item.overlay) { idx_to_delete = j; }
+ });
+ if (idx_to_delete >= 0) {
+ overviewer.map.overlayMapTypes.removeAt(idx_to_delete);
+ }
+ }
+ }
+ });
+ }
+ overviewer.util.createDropDown('Overlays', items);
+ }
+ },
+ 'createDropDown': function(title, items) {
+ var control = document.createElement('DIV');
+ // let's let a style sheet do most of the styling here
+ control.id = 'customControl';
+
+ var controlText = document.createElement('DIV');
+ controlText.innerHTML = title;
+
+ var controlBorder = document.createElement('DIV');
+ controlBorder.id='top';
+ control.appendChild(controlBorder);
+ controlBorder.appendChild(controlText);
+
+ var dropdownDiv = document.createElement('DIV');
+ dropdownDiv.id='dropDown';
+ control.appendChild(dropdownDiv);
+ dropdownDiv.innerHTML='';
+
+ // add the functionality to toggle visibility of the items
+ $(controlText).click(function() {
+ $(dropdownDiv).toggle();
+ });
+
+ // add that control box we've made back to the map.
+ overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(control);
+
+ for(i in items) {
+ // create the visible elements of the item
+ var item = items[i];
+ overviewer.util.debug(item);
+ var itemDiv = document.createElement('div');
+ var itemInput = document.createElement('input');
+ itemInput.type='checkbox';
+
+ // give it a name
+ $(itemInput).data('label',item.label);
+ jQuery(itemInput).click((function(local_idx, local_item) {
+ return function(e) {
+ item.action(local_idx, local_item, e.target.checked);
+ };
+ })(i, item));
+
+ // if its checked, its gotta do something, do that here.
+ if (item.checked) {
+ itemInput.checked = true;
+ item.action(i, item.label, item.checked);
+ }
+ dropdownDiv.appendChild(itemDiv);
+ itemDiv.appendChild(itemInput);
+ var textNode = document.createElement('text');
+ if(item.icon) {
+ textNode.innerHTML = '
' + item.label + '
';
+ } else {
+ textNode.innerHTML = item.label + '
';
+ }
+
+ itemDiv.appendChild(textNode);
+ }
+ },
+ 'createRegionInfoWindow': function(shape) {
+ var infowindow = new google.maps.InfoWindow();
+ google.maps.event.addListener(shape, 'click', function(event, i) {
+ if (overviewer.collections.infoWindow) {
+ overviewer.collections.infoWindow.close();
+ }
+ // Replace our Info Window's content and position
+ var contentString = 'Region: ' + shape.name + '
' +
+ 'Clicked Location:
' + event.latLng.lat() + ', ' +
+ event.latLng.lng() + '
';
+ infowindow.setContent(contentString);
+ infowindow.setPosition(event.latLng);
+ infowindow.open(overviewer.map);
+ overviewer.collections.infoWindow = infowindow;
+ });
+ },
+ 'createMarkerInfoWindow': function(marker) {
+ var windowContent = '
' + marker.title.replace(/\n/g,'
') + '
';
+ var infowindow = new google.maps.InfoWindow({
+ 'content': windowContent
+ });
+ google.maps.event.addListener(marker, 'click', function() {
+ if (overviewer.collections.infoWindow) {
+ overviewer.collections.infoWindow.close();
+ }
+ infowindow.open(overviewer.map, marker);
+ overviewer.collections.infoWindow = infowindow;
+ });
+ }
+ },
+ 'classes': {
+ 'HomeControl': function(controlDiv) {
+ controlDiv.style.padding = '5px';
+ // Set CSS for the control border
+ var control = document.createElement('DIV');
+ control.id='top';
+ control.title = 'Click to center the map on the Spawn';
+ controlDiv.appendChild(control);
+
+ // Set CSS for the control interior
+ var controlText = document.createElement('DIV');
+ controlText.innerHTML = 'Spawn';
+ controlText.id='button';
+ control.appendChild(controlText);
+
+ // Setup the click event listeners: simply set the map to map center
+ // as definned below
+ google.maps.event.addDomListener(control, 'click', function() {
+ overviewer.map.panTo(fromWorldToLatLng(
+ overviewerConfig.map.center[0],
+ overviewerConfig.map.center[1],
+ overviewerConfig.map.center[2]));
+ });
+ },
+ 'MapProjection' : function() {
+ this.inverseTileSize = 1.0 / overviewerConfig.CONST.tileSize;
+ },
+ //Looks like this is only used for debugging
+ 'CoordMapType': function(tileSize) {
+ this.tileSize = tileSize;
+ }
+ },
+ 'gmap': {
+ 'getTileUrlGenerator': function(path, pathBase, pathExt) {
+ return function(tile, zoom) {
+ var url = path;
+ var urlBase = ( pathBase ? pathBase : '' );
+ if(tile.x < 0 || tile.x >= Math.pow(2, zoom) ||
+ tile.y < 0 || tile.y >= Math.pow(2, zoom)) {
+ url += '/blank';
+ } else if(zoom == 0) {
+ url += '/base';
+ } else {
+ for(var z = zoom - 1; z >= 0; --z) {
+ var x = Math.floor(tile.x / Math.pow(2, z)) % 2;
+ var y = Math.floor(tile.y / Math.pow(2, z)) % 2;
+ url += '/' + (x + 2 * y);
+ }
+ }
+ url = url + '.' + pathExt;
+ if(overviewerConfig.map.cacheMinutes > 0) {
+ var d = new Date();
+ url += '?c=' + Math.floor(d.getTime() /
+ (1000 * 60 * overviewerConfig.map.cacheMinutes));
+ }
+ return(urlBase + url);
+ }
+ }
+ }
+};
\ No newline at end of file
diff --git a/web_assets/overviewerConfig.js b/web_assets/overviewerConfig.js
new file mode 100644
index 0000000..a0e8f33
--- /dev/null
+++ b/web_assets/overviewerConfig.js
@@ -0,0 +1,38 @@
+var overviewerConfig = {
+ //These will probably never change
+ 'CONST': {
+ 'tileSize': 384,
+ 'image': {
+ 'defaultMarker': 'signpost.png',
+ 'signMarker': 'signpost_icon.png',
+ 'compass': 'compass.png',
+ 'spawnMarker': 'http://google-maps-icons.googlecode.com/files/home.png',
+ 'queryMarker': 'http://google-maps-icons.googlecode.com/files/regroup.png'
+ },
+ 'mapDivId': 'mcmap',
+ 'regionStrokeWeight': 2
+ },
+ 'map': {
+ 'controls': {
+ 'navigation': true
+ },
+ 'defaultZoom': 0,
+ 'minZoom': {minzoom},
+ 'maxZoom': {maxzoom},
+ 'center': {spawn_coords},
+ 'cacheMinutes': 0,
+ 'debug': false,
+ },
+ 'objectGroups': {
+ 'signs': [
+ {
+ 'label': 'All',
+ 'match': function(sign) {
+ return true;
+ }
+ }
+ ],
+ 'regions': []
+ },
+ 'mapTypes': {maptypedata}
+};
\ No newline at end of file