From 45ba3ddf0159621bec710305839306a205024e61 Mon Sep 17 00:00:00 2001 From: Imanuel Pundoko Date: Sat, 19 Oct 2019 04:59:14 +0800 Subject: [PATCH] [+] keep old id for rest from diffential; trigger draw.create onStop; [*] import module; --- example/src/data/data.json | 111 ++++++++++------------------ example/src/scripts/index.js | 8 +- src/index.js | 78 +++++++++++-------- src/utils/differenceAtPoint.js | 32 ++++---- src/utils/polygonCoordinateFixer.js | 15 ---- 5 files changed, 114 insertions(+), 130 deletions(-) delete mode 100644 src/utils/polygonCoordinateFixer.js diff --git a/example/src/data/data.json b/example/src/data/data.json index c222fd1..937d825 100644 --- a/example/src/data/data.json +++ b/example/src/data/data.json @@ -9,55 +9,24 @@ "coordinates": [ [ [ - -122.42113805424486, - 37.77338298377752 - ], - [ - -122.4210736812288, - 37.77213209981771 - ], - [ - -122.41907811772174, - 37.77208969660036 - ], - [ - -122.4190995753936, - 37.77327697748309 - ], - [ - -122.42113805424486, - 37.77338298377752 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.83565092086792, - 1.4731321659327465 + 124.83344078063965, + 1.472435021968824 ], [ - 124.83809709548949, - 1.4731321659327465 + 124.84086513519287, + 1.472435021968824 ], [ - 124.83809709548949, - 1.4757598604506188 + 124.84086513519287, + 1.4785698813567398 ], [ - 124.83565092086792, - 1.4757598604506188 + 124.83344078063965, + 1.4785698813567398 ], [ - 124.83565092086792, - 1.4731321659327465 + 124.83344078063965, + 1.472435021968824 ] ] ] @@ -71,24 +40,24 @@ "coordinates": [ [ [ - 124.8336124420166, - 1.4740009142594124 + 124.8310160636902, + 1.4742368705365223 ], [ - 124.83699202537537, - 1.4740009142594124 + 124.83824729919434, + 1.4742368705365223 ], [ - 124.83699202537537, - 1.4751806953948565 + 124.83824729919434, + 1.4770254428252843 ], [ - 124.8336124420166, - 1.4751806953948565 + 124.8310160636902, + 1.4770254428252843 ], [ - 124.8336124420166, - 1.4740009142594124 + 124.8310160636902, + 1.4742368705365223 ] ] ] @@ -102,24 +71,24 @@ "coordinates": [ [ [ - 124.83495354652403, - 1.4699789284209208 + 124.82977151870728, + 1.4681019992156614 ], [ - 124.83812928199768, - 1.4699789284209208 + 124.8433756828308, + 1.4681019992156614 ], [ - 124.83812928199768, - 1.4720381860765859 + 124.8433756828308, + 1.4705473695261786 ], [ - 124.83495354652403, - 1.4720381860765859 + 124.82977151870728, + 1.4705473695261786 ], [ - 124.83495354652403, - 1.4699789284209208 + 124.82977151870728, + 1.4681019992156614 ] ] ] @@ -133,24 +102,24 @@ "coordinates": [ [ [ - 124.83344078063965, - 1.4708155020727454 + 124.83440637588501, + 1.4670509181722702 ], [ - 124.83912706375122, - 1.4708155020727454 + 124.8393201828003, + 1.4670509181722702 ], [ - 124.83912706375122, - 1.4715448224364003 + 124.8393201828003, + 1.4714911959471828 ], [ - 124.83344078063965, - 1.4715448224364003 + 124.83440637588501, + 1.4714911959471828 ], [ - 124.83344078063965, - 1.4708155020727454 + 124.83440637588501, + 1.4670509181722702 ] ] ] diff --git a/example/src/scripts/index.js b/example/src/scripts/index.js index 196245f..3c711fb 100644 --- a/example/src/scripts/index.js +++ b/example/src/scripts/index.js @@ -26,7 +26,6 @@ const map = new MapboxGL.Map({ const modes = MapboxGLDraw.modes; modes.shape_builder = ShapeBuilder; -console.dir(modes.shape_builder); const draw = new MapboxGLDraw({ modes }); @@ -37,4 +36,9 @@ map.addControl(draw); map.on('load', function () { draw.add(data); }); - +map.on('draw.create', function (e) { + console.log(e); +}); +map.on('click', function (e) { + console.log(map.queryRenderedFeatures(e.point)); +}); diff --git a/src/index.js b/src/index.js index bffeeb9..962253e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,14 +1,35 @@ -import _ from 'lodash'; +import _map from 'lodash/map'; +import _chunk from 'lodash/chunk'; +import _get from 'lodash/get'; +import _concat from 'lodash/concat'; +import _filter from 'lodash/filter'; +import _assign from 'lodash/assign'; +import _unset from 'lodash/unset'; import * as turf from '@turf/turf'; -import pcf from './utils/polygonCoordinateFixer'; +import { polygon as turfPolygon } from '@turf/helpers'; +import turfBooleanOverlap from '@turf/boolean-overlap'; import differenceAtPoint from './utils/differenceAtPoint'; const ShapeBuilder = { onSetup: function () { + console.log(this); this.updateUIClasses({ mouse: 'add' }); - return {}; + const selected = this.getSelected(); + const feature = this.newFeature(turfPolygon([])); + return { + selected, + feature, + changed: [] + }; + }, + + onMouseMove: function (state) { + if (state.selected && state.selected.length !== 2) { + this.changeMode('simple_select'); + return {}; + } }, onTap: function (state, e) { @@ -16,55 +37,49 @@ const ShapeBuilder = { }, onClick: function (state, e) { - if (this.getSelected().length !== 2) { + if (state.selected && state.selected.length !== 2) { this.changeMode('simple_select'); return; } - const coord = [_(e).get('lngLat.lng'), _(e).get('lngLat.lat')]; - const compFeature = _.map(this.getSelected(), function (v) { - const coordinates = pcf(v).coordinates; - const properties = _.create(v.properties, { id: v.id }); - const polygon = turf.polygon(coordinates, properties); - return _.create(polygon); + const coord = [_get(e, 'lngLat.lng'), _get(e, 'lngLat.lat')]; + const features = _map(state.selected, function (v) { + return _assign({}, v.toGeoJSON()); }); - if (!turf.booleanOverlap(...compFeature)) { + if (!turfBooleanOverlap(...features)) { this.changeMode('simple_select'); return; } - const contain = _.chain(compFeature) - .filter(function (v) { - const point = turf.point(coord); - return turf.booleanPointInPolygon(point, v); - }).chunk(2).get('[0]').value(); - + let contain = _filter(features, function (v) { + const point = turf.point(coord); + return turf.booleanPointInPolygon(point, v); + }); + contain = _chunk(contain, 2)[0]; let feature, poly1, poly2; switch (contain.length) { case 1: poly1 = contain[0]; - poly2 = _.chain(compFeature) - .filter(function (v) { - return _(v).get('properties.id') !== _(poly1).get('properties.id'); - }).get('[0]').value(); + poly2 = _filter(features, function (v) { + return v.id !== poly1.id; + })[0]; feature = differenceAtPoint(poly1, poly2, turf.point(coord)); - this.deleteFeature(poly1.properties.id); - let drawPoly1 = _.create(feature); + this.deleteFeature(poly1.id); + let drawPoly1 = _assign({}, feature); drawPoly1 = turf.transformScale(drawPoly1, 1.00000001); drawPoly1 = turf.difference(poly1, drawPoly1); + drawPoly1.id = poly1.id; drawPoly1 = this.newFeature(drawPoly1); this.addFeature(drawPoly1); + state.changed.push(drawPoly1.toGeoJSON()); break; case 2: feature = turf.intersect(...contain); break; default: break; } - let drawFeature = _.create(feature); - _.unset(drawFeature, 'properties.id'); - drawFeature = this.newFeature(drawFeature); - this.addFeature(drawFeature); - this.clearSelectedFeatures(); + state.feature.setCoordinates(_get(feature, 'geometry.coordinates')); + this.addFeature(state.feature); this.changeMode('direct_select', { - featureId: _(drawFeature).get('id') + featureId: state.feature.id }); }, @@ -79,6 +94,11 @@ const ShapeBuilder = { }, onStop: function (state, e) { + if (state.feature.isValid()) { + this.map.fire('draw.create', { + features: _concat([state.feature.toGeoJSON()], state.changed) + }); + } this.updateUIClasses({ mouse: 'none' }); diff --git a/src/utils/differenceAtPoint.js b/src/utils/differenceAtPoint.js index a3050ee..a627ea6 100644 --- a/src/utils/differenceAtPoint.js +++ b/src/utils/differenceAtPoint.js @@ -1,17 +1,23 @@ -import * as turf from '@turf/turf'; -import _ from 'lodash'; +import { polygon } from '@turf/helpers'; +import { getType } from '@turf/invariant'; +import difference from '@turf/difference'; +import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; +import _assign from 'lodash/assign'; +import _find from 'lodash/find'; +import _map from 'lodash/map'; +import _get from 'lodash/get'; export default function (PolyA, PolyB, point) { - let feature = turf.difference(PolyA, PolyB); - if (turf.getType(feature) === 'MultiPolygon') { - feature = _.chain(feature).get('geometry.coordinates') - .map(function (v) { - const properties = _(feature).get('properties'); - return turf.polygon(v, properties); - }) - .filter(function (v) { - return turf.booleanPointInPolygon(point, v); - }).get('[0]').value(); + let feature = difference(PolyA, PolyB); + if (getType(feature) === 'MultiPolygon') { + feature = _get(feature, 'geometry.coordinates'); + feature = _map(feature, function (v) { + const properties = _get(feature, 'properties'); + return polygon(v, properties); + }); + feature = _find(feature, function (v) { + return booleanPointInPolygon(point, v); + }); } - return _.create(feature); + return _assign({}, feature); } diff --git a/src/utils/polygonCoordinateFixer.js b/src/utils/polygonCoordinateFixer.js deleted file mode 100644 index bee1110..0000000 --- a/src/utils/polygonCoordinateFixer.js +++ /dev/null @@ -1,15 +0,0 @@ -import _ from 'lodash'; - -export default function (raw) { - if (_(raw).get('type') !== 'Polygon') { - return raw; - } - let polygon = _.create(raw); - let coordinates = _(polygon).get('coordinates[0]'); - - if (!_.isEqual(_(coordinates).head(), _(coordinates).last())) { - coordinates.push(_(coordinates).head()); - polygon = _.set(polygon, 'coordinates[0]', coordinates); - } - return polygon; -}