remove addLatLng, replace with _getLatLng

- don't mutate the geoJson properties in tilemap, also remove the leaflet deps in tilemap
- _getLatLng will get leaflet latLng from a feature
- _getLatLng is memoized, so this work only happens once per geo point
- _getLatLng result is only required for heatmap currently, less leaflet work, faster maps
This commit is contained in:
Joe Fleming 2015-06-24 19:43:41 -07:00
parent c1543c63ca
commit 4129ae8cf8
2 changed files with 32 additions and 34 deletions

View file

@ -79,6 +79,23 @@ define(function (require) {
}
};
/**
* returns a memoized Leaflet latLng for given geoJson feature
*
* @method addLatLng
* @param feature {geoJson Object}
* @return {Leaflet latLng Object}
*/
HeatmapMarker.prototype._getLatLng = _.memoize(function (feature) {
return L.latLng(
feature.geometry.coordinates[1],
feature.geometry.coordinates[0]
);
}, function (feature) {
// turn coords into a string for the memoize cache
return [feature.geometry.coordinates[1], feature.geometry.coordinates[0]].join(',');
});
/**
* Finds nearest feature in mapData to event latlng
*
@ -86,22 +103,25 @@ define(function (require) {
* @param point {Leaflet latLng Object}
* @return nearestPoint {Leaflet Object}
*/
HeatmapMarker.prototype.nearestFeature = function (point) {
var distance = Infinity;
HeatmapMarker.prototype.nearestFeature = function (latLng) {
var self = this;
var nearest;
if (point.lng < -180 || point.lng > 180) {
if (latLng.lng < -180 || latLng.lng > 180) {
return;
}
for (var i = 0; i < this.geoJson.features.length; i++) {
var dist = point.distanceTo(this.geoJson.features[i].properties.latLng);
_.reduce(this.geoJson.features, function (distance, feature) {
var featureLatLng = self._getLatLng(feature);
var dist = latLng.distanceTo(featureLatLng);
if (dist < distance) {
distance = dist;
nearest = this.geoJson.features[i];
nearest = feature;
return dist;
}
}
nearest.properties.eventDistance = distance;
return distance;
}, Infinity);
return nearest;
};
@ -118,6 +138,7 @@ define(function (require) {
if (!feature) return;
var showTip = false;
var featureLatLng = this._getLatLng(feature);
// zoomScale takes map zoom and returns proximity value for tooltip display
// domain (input values) is map zoom (min 1 and max 18)
@ -128,20 +149,18 @@ define(function (require) {
.range([1000000, 300000, 100000, 15000, 2000, 150, 50]);
var proximity = zoomScale(this.map.getZoom());
var distance = latlng.distanceTo(feature.properties.latLng);
var distance = latlng.distanceTo(featureLatLng);
// maxLngDif is max difference in longitudes
// to prevent feature tooltip from appearing 360°
// away from event latlng
var maxLngDif = 40;
var lngDif = Math.abs(latlng.lng - feature.properties.latLng.lng);
var lngDif = Math.abs(latlng.lng - featureLatLng.lng);
if (distance < proximity && lngDif < maxLngDif) {
showTip = true;
}
delete feature.properties.eventDistance;
var testScale = d3.scale.pow().exponent(0.2)
.domain([1, 18])
.range([1500000, 50]);

View file

@ -2,9 +2,6 @@ define(function (require) {
return function TileMapFactory(d3, Private) {
var _ = require('lodash');
var $ = require('jquery');
var L = require('leaflet');
require('leaflet-heat');
require('leaflet-draw');
require('css!components/vislib/styles/main');
var Chart = Private(require('components/vislib/visualizations/_chart'));
@ -63,9 +60,6 @@ define(function (require) {
return function (selection) {
selection.each(function () {
// add leaflet latLngs to properties for tooltip
self.addLatLng(mapData);
var container = $(this).addClass('tilemap');
var map = new Map(container, self._chartData, {
@ -94,21 +88,6 @@ define(function (require) {
};
};
/**
* add Leaflet latLng to mapData properties
*
* @method addLatLng
* @return undefined
*/
TileMap.prototype.addLatLng = function () {
this.geoJson.features.forEach(function (feature) {
feature.properties.latLng = L.latLng(
feature.geometry.coordinates[1],
feature.geometry.coordinates[0]
);
});
};
/**
* Invalidate the size of the map, so that leaflet will resize to fit.
* then moves to center