-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
132 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,132 +1,169 @@ | ||
// from mapbox/spots | ||
// Array.indexOf polyfill courtesy of Mozilla MDN: | ||
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf | ||
if (!Array.prototype.indexOf) { | ||
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { | ||
"use strict"; | ||
if (this === void 0 || this === null) { | ||
throw new TypeError(); | ||
} | ||
var t = Object(this); | ||
var len = t.length >>> 0; | ||
if (len === 0) { | ||
return -1; | ||
} | ||
var n = 0; | ||
if (arguments.length > 0) { | ||
n = Number(arguments[1]); | ||
if (n !== n) { // shortcut for verifying if it's NaN | ||
n = 0; | ||
} else if (n !== 0 && n !== Infinity && n !== -Infinity) { | ||
n = (n > 0 || -1) * Math.floor(Math.abs(n)); | ||
} | ||
} | ||
if (n >= len) { | ||
return -1; | ||
} | ||
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); | ||
for (; k < len; k++) { | ||
if (k in t && t[k] === searchElement) { | ||
return k; | ||
} | ||
} | ||
return -1; | ||
}; | ||
} | ||
|
||
function mmg() { | ||
var l = {}, | ||
geojson = {}, | ||
// a list of our markers | ||
markers = [], | ||
// the absolute position of the parent element | ||
position = null, | ||
factory = null, | ||
_id = 0, | ||
_zoom, | ||
selection = {}, | ||
map; | ||
// map bounds | ||
left = null, | ||
right = null; | ||
|
||
var parent = document.createElement('div'); | ||
parent.style.cssText = 'position: absolute; top: 0px;' + | ||
'left: 0px; width: 100%; height: 100%; margin: 0; padding: 0; z-index: 1'; | ||
|
||
var level = parent.appendChild(document.createElement('div')); | ||
level.style.cssText = 'position: absolute; top: 0px;' + | ||
'left: 0px; width: 100%; height: 100%; margin: 0; padding: 0; z-index: 0'; | ||
|
||
function defaultFactory(feature) { | ||
var d = document.createElement('div'); | ||
d.className = 'mmg-default'; | ||
return d; | ||
} | ||
|
||
l.gen_id = function() { | ||
return _id++; | ||
}; | ||
|
||
l.correct = function(force) { | ||
if (_zoom !== Math.round(map.coordinate.zoom) || force) { | ||
_zoom = Math.round(map.coordinate.zoom); | ||
level.innerHTML = ''; | ||
for (var i = 0; i < geojson.features.length; i++) { | ||
var feature = geojson.features[i]; | ||
|
||
feature.elem = factory(feature); | ||
level.appendChild(feature.elem); | ||
|
||
var coord = map.locationCoordinate(new MM.Location( | ||
feature.geometry.coordinates[1], | ||
feature.geometry.coordinates[0])); | ||
|
||
coord = coord.zoomTo(map.coordinate.zoom); | ||
|
||
var tx = coord.column * map.tileSize.x - 10, | ||
ty = coord.row * map.tileSize.y - 25; | ||
|
||
// TODO: pass only scale or only w/h | ||
MM.moveElement(feature.elem, { | ||
x: tx, | ||
y: ty | ||
}); | ||
} | ||
} | ||
}; | ||
function fLocation (feature) { | ||
// GeoJSON | ||
var geom = feature.geometry; | ||
// coerce the lat and lon values, just in case | ||
var lon = Number(geom.coordinates[0]), | ||
lat = Number(geom.coordinates[1]); | ||
return new MM.Location(lat, lon); | ||
} | ||
|
||
function clean(x) { | ||
var clean_features = []; | ||
for (var i = 0; i < geojson.features.length; i++) { | ||
clean_features.push({ | ||
type: 'Feature', | ||
geometry: { | ||
type: 'Point', | ||
coordinates: geojson.features[i].geometry.coordinates | ||
}, | ||
properties: geojson.features[i].properties | ||
}); | ||
// Reposition al markers | ||
function repositionAllMarkers() { | ||
left = l.map.pointLocation(new MM.Point(0, 0)); | ||
right = l.map.pointLocation(new MM.Point(l.map.dimensions.x, 0)); | ||
for (var i = 0; i < markers.length; i++) { | ||
repositionMarker(markers[i]); | ||
} | ||
return { | ||
type: "FeatureCollection", | ||
features: clean_features | ||
}; | ||
} | ||
|
||
l.byid = function() { | ||
var x = {}; | ||
var c = clean(geojson); | ||
for (var i = 0; i < c.features.length; i++) { | ||
x[c.features[i].properties.id] = c.features[i]; | ||
// reposition a single marker element | ||
function repositionMarker(marker) { | ||
// remember the tile coordinate so we don't have to reproject every time | ||
if (!marker.coord) marker.coord = l.map.locationCoordinate(marker.location); | ||
var pos = l.map.coordinatePoint(marker.coord); | ||
var pos_loc; | ||
if (pos.x < 0) { | ||
pos_loc = new MM.Location(marker.location.lat, marker.location.lon); | ||
pos_loc.lon += Math.ceil((left.lon - marker.location.lon) / 360) * 360; | ||
pos = l.map.locationPoint(pos_loc); | ||
} else if (pos.x > l.map.dimensions.x) { | ||
pos_loc = new MM.Location(marker.location.lat, marker.location.lon); | ||
pos_loc.lon -= Math.ceil((marker.location.lon - right.lon) / 360) * 360; | ||
pos = l.map.locationPoint(pos_loc); | ||
} | ||
return x; | ||
}; | ||
if (pos_loc) { | ||
marker.coord = l.map.locationCoordinate(pos_loc); | ||
} | ||
pos.scale = 1; | ||
pos.width = pos.height = 0; | ||
MM.moveElement(marker, pos); | ||
} | ||
|
||
l.rm = function(id) { | ||
for (var i = 0; i < geojson.features.length; i++) { | ||
if (geojson.features[i].properties.id === id) { | ||
geojson.features.splice(i, 1); | ||
} | ||
/** | ||
* Add an HTML element as a marker, located at the position of the | ||
* provided GeoJSON feature, Location instance (or {lat,lon} object | ||
* literal), or "lat,lon" string. | ||
*/ | ||
var first = true; | ||
l.addMarker = function(marker, feature) { | ||
if (!marker || !feature) { | ||
return null; | ||
} | ||
// convert the feature to a Location instance | ||
marker.location = fLocation(feature); | ||
// position: absolute | ||
marker.style.position = 'absolute'; | ||
// update the marker's position | ||
if (l.map) repositionMarker(marker); | ||
// append it to the DOM | ||
parent.appendChild(marker); | ||
|
||
// add it to the list | ||
markers.push(marker); | ||
|
||
return marker; | ||
}; | ||
|
||
l.geojson = function(x) { | ||
if (!arguments.length) return clean(geojson); | ||
|
||
geojson = x; | ||
l.correct(true); | ||
l.draw(); | ||
if (!x) return markers; | ||
|
||
return l; | ||
for (var i = 0; i < x.features.length; i++) { | ||
l.addMarker(factory(x.features[i]), x.features[i]); | ||
} | ||
return this; | ||
}; | ||
|
||
l.draw = function() { | ||
var theCoord = map.coordinate.copy(); | ||
var center = new MM.Point(map.dimensions.x/2, map.dimensions.y/2); | ||
repositionAllMarkers(); | ||
}; | ||
|
||
MM.moveElement(level, { | ||
x: -(theCoord.column * 256) + center.x, | ||
y: -(theCoord.row * 256) + center.y | ||
}); | ||
/** | ||
* Remove the element marker from the layer and the DOM. | ||
*/ | ||
l.removeMarker = function(marker) { | ||
var index = markers.indexOf(marker); | ||
if (index > -1) { | ||
markers.splice(index, 1); | ||
} | ||
if (marker.parentNode == parent) { | ||
parent.removeChild(marker); | ||
} | ||
return marker; | ||
}; | ||
|
||
l.correct(); | ||
// remove all markers | ||
l.removeAllMarkers = function() { | ||
while (markers.length > 0) { | ||
this.removeMarker(markers[0]); | ||
} | ||
}; | ||
|
||
l.factory = function(x) { | ||
if (!x) return factory; | ||
factory = x; | ||
return l; | ||
}; | ||
|
||
l.map = function(x) { | ||
if (!x) return map; | ||
map = x; | ||
return l; | ||
return this; | ||
}; | ||
|
||
l.parent = parent; | ||
|
||
l.factory(defaultFactory); | ||
|
||
|
||
return l; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters