Merge pull request #3829 from spalger/tilemap-zoom-precision

Tilemap zoom precision
This commit is contained in:
Rashid Khan 2015-05-15 13:25:33 -07:00
commit 423954da0f
7 changed files with 88 additions and 26 deletions

View file

@ -3,7 +3,7 @@ define(function (require) {
var _ = require('lodash');
var moment = require('moment');
var BucketAggType = Private(require('components/agg_types/buckets/_bucket_agg_type'));
var defaultPrecision = 3;
var defaultPrecision = 2;
function getPrecision(precision) {
var maxPrecision = _.parseInt(config.get('visualization:tileMap:maxPrecision'));
@ -29,10 +29,23 @@ define(function (require) {
name: 'field',
filterFieldTypes: 'geo_point'
},
{
name: 'autoPrecision',
default: true,
write: _.noop
},
{
name: 'precision',
default: defaultPrecision,
editor: require('text!components/agg_types/controls/precision.html'),
controller: function ($scope) {
$scope.$watchMulti([
'agg.params.autoPrecision',
'outputAgg.params.precision'
], function (cur, prev) {
if (cur[1]) $scope.agg.params.precision = cur[1];
});
},
deserialize: getPrecision,
write: function (aggConfig, output) {
output.params.precision = getPrecision(aggConfig.params.precision);
@ -41,4 +54,4 @@ define(function (require) {
]
});
};
});
});

View file

@ -1,5 +1,5 @@
<div class="vis-editor-agg-form-row">
<div class="form-group">
<div class="vis-editor-agg-form-row" ng-controller="agg.type.params.byName.precision.controller">
<div ng-if="!agg.params.autoPrecision" class="form-group">
<label>Precision</label>
<div class="vis-editor-agg-form-row">
<input
@ -16,4 +16,14 @@
</div>
</div>
</div>
</div>
</div>
<div class="vis-option-item">
<label>
<input type="checkbox"
name="autoPrecision"
ng-model="agg.params.autoPrecision">
Change precision on map zoom
</label>
</div>

View file

@ -1,5 +1,5 @@
define(function (require) {
return function TileMapFactory(d3, Private) {
return function TileMapFactory(d3, Private, config) {
var _ = require('lodash');
var $ = require('jquery');
var L = require('leaflet');
@ -11,8 +11,8 @@ define(function (require) {
require('css!components/vislib/styles/main');
var mapCenter = [15, 5];
var mapZoom = 2;
var defaultMapCenter = [15, 5];
var defaultMapZoom = 2;
/**
* Tile Map Visualization: renders maps
@ -62,14 +62,11 @@ define(function (require) {
var worldBounds = L.latLngBounds([-90, -220], [90, 220]);
return function (selection) {
selection.each(function (data) {
if (self._attr.mapZoom) {
mapZoom = self._attr.mapZoom;
}
if (self._attr.mapCenter) {
mapCenter = self._attr.mapCenter;
}
self._attr.mapZoom = self._attr.mapZoom || defaultMapZoom;
self._attr.mapCenter = self._attr.mapCenter || defaultMapCenter;
selection.each(function (data) {
var mapData = data.geoJson;
var div = $(this).addClass('tilemap');
@ -101,8 +98,8 @@ define(function (require) {
minZoom: 1,
maxZoom: 18,
layers: tileLayer,
center: mapCenter,
zoom: mapZoom,
center: self._attr.mapCenter,
zoom: self._attr.mapZoom,
noWrap: true,
maxBounds: worldBounds,
scrollWheelZoom: false,
@ -126,8 +123,9 @@ define(function (require) {
});
map.on('moveend', function setZoomCenter() {
mapZoom = self._attr.mapZoom = map.getZoom();
mapCenter = self._attr.mapCenter = map.getCenter();
self._attr.mapZoom = map.getZoom();
self._attr.mapCenter = map.getCenter();
featureLayer.clearLayers();
featureLayer = self.markerType(map, mapData).addTo(map);
});
@ -155,14 +153,21 @@ define(function (require) {
});
});
map.on('zoomend', function () {
self.events.emit('mapZoomEnd', {
data: mapData,
zoom: map.getZoom()
});
});
// add label for splits
if (mapData.properties.label) {
self.addLabel(mapData.properties.label, map);
}
var fitContainer = L.DomUtil.create('div', 'leaflet-control leaflet-bar leaflet-control-zoom leaflet-control-fit');
if (mapData && mapData.features.length > 0) {
var fitContainer = L.DomUtil.create('div', 'leaflet-control leaflet-bar leaflet-control-zoom leaflet-control-fit');
// Add button to fit container to points
var FitControl = L.Control.extend({
options: {
@ -245,7 +250,6 @@ define(function (require) {
* @return {Leaflet object} featureLayer
*/
TileMap.prototype.fitBounds = function (map, featureLayer) {
map.fitBounds(featureLayer.getBounds());
};

View file

@ -11,9 +11,10 @@
</div>
<div class="vis-option-item">
</br>
<label>
<input type="checkbox" value="{{isDesaturated}}" ng-model="vis.params.isDesaturated" name="isDesaturated" ng-checked="vis.params.isDesaturated">
<input type="checkbox"
name="isDesaturated"
ng-model="vis.params.isDesaturated">
Desaturate map tiles
</label>
</div>
</div>

View file

@ -1,5 +1,5 @@
define(function (require) {
return function TileMapVisType(Private, getAppState) {
return function TileMapVisType(Private, getAppState, courier, config) {
var VislibVisType = Private(require('plugins/vis_types/vislib/_vislib_vis_type'));
var Schemas = Private(require('plugins/vis_types/_schemas'));
var geoJsonConverter = Private(require('components/agg_response/geo_json/geo_json'));
@ -31,6 +31,38 @@ define(function (require) {
filter.geo_bounding_box[field] = event.bounds;
pushFilter(filter, false, indexPatternName);
},
mapZoomEnd: function (event) {
var agg = _.deepGet(event, 'data.properties.agg.geo');
if (!agg || !agg.params.autoPrecision) return;
// zoomPrecision maps event.zoom to a geohash precision value
// event.limit is the configurable max geohash precision
// default max precision is 7, configurable up to 12
var zoomPrecision = {
1: 2,
2: 2,
3: 2,
4: 3,
5: 3,
6: 4,
7: 4,
8: 5,
9: 5,
10: 6,
11: 6,
12: 7,
13: 7,
14: 8,
15: 9,
16: 10,
17: 11,
18: 12
};
agg.params.precision = Math.min(zoomPrecision[event.zoom], config.get('visualization:tileMap:maxPrecision'));
courier.fetch();
}
},
responseConverter: geoJsonConverter,

View file

@ -19,6 +19,7 @@ define(function (require) {
template: require('text!plugins/visualize/editor/agg.html'),
require: 'form',
link: function ($scope, $el, attrs, kbnForm) {
$scope.$bind('outputAgg', 'outputVis.aggs.byId[agg.id]', $scope);
$scope.editorOpen = !!$scope.agg.brandNew;
if (!$scope.editorOpen) {
$scope.$evalAsync(kbnForm.$setTouched);

View file

@ -14,6 +14,7 @@ define(function (require) {
controllerAs: 'sidebar',
controller: function ($scope) {
$scope.$bind('vis', 'editableVis');
$scope.$bind('outputVis', 'vis');
this.section = _.get($scope, 'vis.type.requiresSearch') ? 'data' : 'options';
}
};