Skip to content

Commit

Permalink
use mapbox layers to color points within circle
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Rueckstiess authored and rueckstiess committed Jul 24, 2017
1 parent 01926ef commit 6d5f22f
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 49 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@
"@mongodb-js/compass-deployment-awareness": "3.1.1",
"@mongodb-js/compass-document-validation": "4.0.3",
"@mongodb-js/compass-serverstats": "9.0.2",
"@turf/along": "^3.10.0",
"@turf/destination": "^3.10.0",
"@turf/distance": "^3.10.0",
"@turf/line-distance": "^3.10.0",
"ampersand-collection": "^1.5.0",
"ampersand-collection-filterable": "^0.2.1",
"ampersand-dom-bindings": "^3.7.0",
Expand Down Expand Up @@ -231,11 +235,7 @@
"reflux-state-mixin": "mongodb-js/reflux-state-mixin",
"semver": "^5.1.0",
"storage-mixin": "^0.8.1",
"turf-destination": "^1.2.1",
"turf-distance": "^1.1.0",
"turf-point": "^2.0.1",
"@turf/along": "^3.7.5",
"@turf/line-distance": "^3.7.5",
"uuid": "^3.0.0",
"vega": "^3.0.0-beta.30",
"vega-lite": "^2.0.0-beta.4"
Expand Down
2 changes: 1 addition & 1 deletion src/internal-packages/query/lib/action/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const QueryAction = Reflux.createActions({
/**
* sets a $geoWithin query with center and distance.
*/
'setGeoWithinValue': {sync: true},
'setGeoWithinValue': {sync: false},

/* Execution */

Expand Down
126 changes: 82 additions & 44 deletions src/internal-packages/schema/lib/d3/coordinates.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ const d3 = require('d3');
const _ = require('lodash');
const shared = require('./shared');
const app = require('hadron-app');
const turfDistance = require('turf-distance');
const turfDistance = require('@turf/distance');
const turfPoint = require('turf-point');
const turfDestination = require('turf-destination');
const turfAlong = require('turf-along');
const turfLineDistance = require('turf-line-distance');
const turfDestination = require('@turf/destination');
// const turfAlong = require('@turf/along');
// const turfLineDistance = require('@turf/line-distance');
const mapboxgl = require('mapbox-gl/dist/mapbox-gl.js');
const geojsonValidation = require('geojson-validation');

// const metrics = require('mongodb-js-metrics')();
const debug = require('debug')('mongodb-compass:minicharts:geo');
// const debug = require('debug')('mongodb-compass:minicharts:coordinates');

const SELECTED_COLOR = '#F68A1E';
const UNSELECTED_COLOR = '#43B1E5';
Expand Down Expand Up @@ -45,7 +45,7 @@ const minicharts_d3fns_geo = function() {
let circleSelected = false; // have we completed the circle?
let svg;
let render;
let dots;
// let dots;

const margin = shared.margin;

Expand Down Expand Up @@ -85,10 +85,10 @@ const minicharts_d3fns_geo = function() {
}
}

function distance(ll0, ll1) {
function distanceSqr(ll0, ll1) {
const p0 = project(ll0);
const p1 = project(ll1);
const dist = Math.sqrt((p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p0.y) * (p1.y - p0.y));
const dist = (p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p0.y) * (p1.y - p0.y);
return dist;
}

Expand Down Expand Up @@ -142,7 +142,7 @@ const minicharts_d3fns_geo = function() {
container = g;
}
if (!circleCenter || !circleOuter) return;
const dist = distance(circleCenter, circleOuter);
const dist = Math.sqrt(distanceSqr(circleCenter, circleOuter));
const circleLasso = container.selectAll('circle.lasso').data([dist]);
circleLasso.enter().append('circle')
.classed('lasso', true)
Expand Down Expand Up @@ -277,7 +277,7 @@ const minicharts_d3fns_geo = function() {

this.distance = function(ll) {
if (!ll) ll = circleOuter;
return distance(circleCenter, ll);
return distanceSqr(circleCenter, ll);
};

d3.rebind(this, dispatch, 'on');
Expand Down Expand Up @@ -308,47 +308,51 @@ const minicharts_d3fns_geo = function() {

function chart(selection) {
selection.each(function(data) {
// construct featureCollection once
if (_.isUndefined(featureCollection)) {
var features = _.map(data, function(d) {
const features = _.map(data, function(d, i) {
// support both GeoJSON features and Geometries
if (geojsonValidation.isFeature(d)) {
return d;
} else if (geojsonValidation.isGeometryObject(d)) {
return {
type: 'Feature',
properties: null,
properties: {
id: i
},
geometry: d
};
}

});
featureCollection = {
type: 'FeatureCollection',
features: features
};
}
if (Array.isArray(features)){
for (var i=0; i<features.length; i++){
if (geojsonValidation.isLineString(features[i].geometry)) {
// Convert to real number
for (var x=0; x<features[i].geometry.coordinates.length; x++){
features[i].geometry.coordinates[x] = [features[i].geometry.coordinates[x][0].valueOf(),
features[i].geometry.coordinates[x][1].valueOf()
];
}
var lineDistance = turfLineDistance(features[i], 'kilometers');
if (lineDistance < 2) { break; }
var arc = [];
for (var j = 0; j < lineDistance; j++) {

var segment = turfAlong(features[i], j/1000 *lineDistance, 'kilometers');
arc.push(segment.geometry.coordinates);
}
features[i].geometry.coordinates = arc;
}
}
// if (Array.isArray(featureCollection.features)) {
// for (let i = 0; i < featureCollection.features.length; i++) {
// if (geojsonValidation.isLineString(featureCollection.features[i].geometry)) {
// // Convert to real number
// for (let x = 0; x < featureCollection.features[i].geometry.coordinates.length; x++) {
// featureCollection.features[i].geometry.coordinates[x] = [
// featureCollection.features[i].geometry.coordinates[x][0].valueOf(),
// featureCollection.features[i].geometry.coordinates[x][1].valueOf()
// ];
// }
// const lineDistance = turfLineDistance(featureCollection.features[i], 'kilometers');
// if (lineDistance < 2) {
// break;
// }
// const arc = [];
// for (let j = 0; j < lineDistance; j++) {
// const segment = turfAlong(featureCollection.features[i], j / 1000 * lineDistance, 'kilometers');
// arc.push(segment.geometry.coordinates);
// }
// featureCollection.features[i].geometry.coordinates = arc;
// }
// }
// }
}


function getLL(d) {
if (d instanceof mapboxgl.LngLat) return d;
return new mapboxgl.LngLat(+d[0], +d[1]);
Expand Down Expand Up @@ -413,7 +417,7 @@ const minicharts_d3fns_geo = function() {
container: innerDiv[0][0],
// not allowed to whitelabel the map without enterprise license
// attributionControl: false,
style: 'mapbox://styles/mapbox/dark-v9',
style: 'mapbox://styles/mapbox/light-v9',
center: bounds.getCenter()
});
map.dragPan.enable();
Expand All @@ -435,16 +439,39 @@ const minicharts_d3fns_geo = function() {

// when lasso changes, update point selections
circleControl.on('update', function() {
svg.selectAll('circle.dot').style({
fill: function(d) {
const thisDist = circleControl.distance(d);
const circleDist = circleControl.distance();
if (thisDist < circleDist) {
return SELECTED_COLOR;
}
return UNSELECTED_COLOR;
// first get bounding box of the circle
// const bb = circleControl.getBoundingBox();
// now get all features in the bounding box
const features = map.queryRenderedFeatures({layers: ['points']});
// [[10, 20], [30, 50]],
// { layers: ['my-layer-name'] }
// );
const filter = ['in', 'id'];
const circleDist = circleControl.distance();
// now check for feature if it's inside the circle
_.each(features, (feature) => {
const geom = feature.geometry;
if (geom.type !== 'Point') {
return;
}
geom.coordinates = _.map(geom.coordinates, (c) => c.valueOf());
const thisDist = circleControl.distance(getLL(geom.coordinates));
if (thisDist < circleDist) {
filter.push(feature.properties.id);
}
});
map.setFilter('points-selected', filter);
// debug('filter', filter);
// svg.selectAll('circle.dot').style({
// fill: function(d) {
// const thisDist = circleControl.distance(d);
// const circleDist = circleControl.distance();
// if (thisDist < circleDist) {
// return SELECTED_COLOR;
// }
// return UNSELECTED_COLOR;
// }
// });
});

circleControl.on('clear', function() {
Expand Down Expand Up @@ -513,6 +540,17 @@ const minicharts_d3fns_geo = function() {
},
filter: ['==', '$type', 'Point']
});

map.addLayer({
id: 'points-selected',
type: 'circle',
source: 'features',
paint: {
'circle-radius': 4,
'circle-color': SELECTED_COLOR
},
filter: ['in', 'id', '']
}); // Place polygon under these labels.
});

_.defer(function() {
Expand Down

0 comments on commit 6d5f22f

Please sign in to comment.