Skip to content

Commit

Permalink
finish point for geocoder
Browse files Browse the repository at this point in the history
  • Loading branch information
dhcole committed May 1, 2012
1 parent 7dd362e commit ff2b86b
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 93 deletions.
215 changes: 126 additions & 89 deletions ext/mmg.js
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;
}
}
5 changes: 2 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,10 @@ <h2>See your neighborhood</h2>
zoomRange: [0, 15],
features: [
'tooltips',
'zoombox',
'zoompan',
'legend',
'bwdetect',
'share',
'zoombox'
'share'
]
});

Expand Down
5 changes: 4 additions & 1 deletion script.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ MB.geocoder = function(el, m, opt) {
new MM.Location(r.boundingbox[1], r.boundingbox[2]),
new MM.Location(r.boundingbox[0], r.boundingbox[3])
]);

if (MB.maps[m].getZoom() === MB.maps[m].coordLimits[1].zoom) {
var point = { 'type': 'FeatureCollection',
'features': [{ 'type': 'Feature',
Expand All @@ -173,13 +174,15 @@ MB.geocoder = function(el, m, opt) {
}]};

if (MB.maps[m].geocodeLayer) {
MB.maps[m].geocodeLayer.removeAllMarkers();
MB.maps[m].geocodeLayer.geojson(point);
} else {
MB.maps[m].geocodeLayer = mmg()
.map(MB.maps[m])
.geojson(point);
MB.maps[m].addLayer(MB.maps[m].geocodeLayer);
}

MB.maps[m].setCenter(new MM.Location(r.lat, r.lon));
}
}
}
Expand Down

0 comments on commit ff2b86b

Please sign in to comment.