From 673738bb27bda4b4156360183e22200a3f7c6f24 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Paour Date: Mon, 9 Nov 2020 20:13:17 +0100 Subject: [PATCH 1/5] Add support for Geojson layers --- src/Geojson.js | 141 +++++++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 3 ++ 2 files changed, 144 insertions(+) create mode 100644 src/Geojson.js diff --git a/src/Geojson.js b/src/Geojson.js new file mode 100644 index 00000000..00a65b92 --- /dev/null +++ b/src/Geojson.js @@ -0,0 +1,141 @@ +import React from 'react'; +import MapView from './index'; + +export const makeOverlays = features => { + const points = features + .filter( + f => + f.geometry && + (f.geometry.type === 'Point' || f.geometry.type === 'MultiPoint') + ) + .map(feature => + makeCoordinates(feature).map(coordinates => + makeOverlay(coordinates, feature) + ) + ) + .reduce(flatten, []) + .map(overlay => ({ ...overlay, type: 'point' })); + + const lines = features + .filter( + f => + f.geometry && + (f.geometry.type === 'LineString' || + f.geometry.type === 'MultiLineString') + ) + .map(feature => + makeCoordinates(feature).map(coordinates => + makeOverlay(coordinates, feature) + ) + ) + .reduce(flatten, []) + .map(overlay => ({ ...overlay, type: 'polyline' })); + + const multipolygons = features + .filter(f => f.geometry && f.geometry.type === 'MultiPolygon') + .map(feature => + makeCoordinates(feature).map(coordinates => + makeOverlay(coordinates, feature) + ) + ) + .reduce(flatten, []); + + const polygons = features + .filter(f => f.geometry && f.geometry.type === 'Polygon') + .map(feature => makeOverlay(makeCoordinates(feature), feature)) + .reduce(flatten, []) + .concat(multipolygons) + .map(overlay => ({ ...overlay, type: 'polygon' })); + + return points.concat(lines).concat(polygons); +}; + +const flatten = (prev, curr) => prev.concat(curr); + +const makeOverlay = (coordinates, feature) => { + let overlay = { + feature, + }; + if ( + feature.geometry.type === 'Polygon' || + feature.geometry.type === 'MultiPolygon' + ) { + overlay.coordinates = coordinates[0]; + if (coordinates.length > 1) { + overlay.holes = coordinates.slice(1); + } + } else { + overlay.coordinates = coordinates; + } + return overlay; +}; + +const makePoint = c => ({ lat: c[1], lng: c[0] }); + +const makeLine = l => l.map(makePoint); + +const makeCoordinates = feature => { + const g = feature.geometry; + if (g.type === 'Point') { + return [makePoint(g.coordinates)]; + } else if (g.type === 'MultiPoint') { + return g.coordinates.map(makePoint); + } else if (g.type === 'LineString') { + return [makeLine(g.coordinates)]; + } else if (g.type === 'MultiLineString') { + return g.coordinates.map(makeLine); + } else if (g.type === 'Polygon') { + return g.coordinates.map(makeLine); + } else if (g.type === 'MultiPolygon') { + return g.coordinates.map(p => p.map(makeLine)); + } else { + return []; + } +}; + +const Geojson = props => { + const overlays = makeOverlays(props.geojson.features); + return ( + + {overlays.map((overlay, index) => { + if (overlay.type === 'point') { + return ( + + ); + } + if (overlay.type === 'polygon') { + return ( + + ); + } + if (overlay.type === 'polyline') { + return ( + + ); + } + })} + + ); +}; + +export default Geojson; diff --git a/src/index.js b/src/index.js index dab5f226..d8a23ea0 100755 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,7 @@ import { withGoogleMap, GoogleMap } from 'react-google-maps'; import Marker from './Marker'; import Polyline from './Polyline'; import Callout from './Callout'; +import Geojson from './Geojson'; const GoogleMapContainer = withGoogleMap(props => ( @@ -102,6 +103,8 @@ class MapView extends Component { MapView.Marker = Marker; MapView.Polyline = Polyline; MapView.Callout = Callout; +MapView.Geojson = Geojson; +export { Geojson }; const styles = StyleSheet.create({ container: { From 71e059dd433c2c079a4bc0120e1761472b16b050 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Paour Date: Tue, 17 Nov 2020 19:27:50 +0100 Subject: [PATCH 2/5] Implement getMapBoundaries --- src/index.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/index.js b/src/index.js index d8a23ea0..182ee5b5 100755 --- a/src/index.js +++ b/src/index.js @@ -10,6 +10,13 @@ const GoogleMapContainer = withGoogleMap(props => ( )); +function googleToReact(point) { + return { + latitude: point.lat(), + longitude: point.lng(), + }; +} + class MapView extends Component { state = { center: null, @@ -39,14 +46,19 @@ class MapView extends Component { }); } + async getMapBoundaries() { + const bounds = this.map.getBounds(); + return { + northEast: googleToReact(bounds.getNorthEast()), + southWest: googleToReact(bounds.getSouthWest()), + }; + } + onDragEnd = () => { const { onRegionChangeComplete } = this.props; if (this.map && onRegionChangeComplete) { const center = this.map.getCenter(); - onRegionChangeComplete({ - latitude: center.lat(), - longitude: center.lng(), - }); + onRegionChangeComplete(googleToReact(center)); } }; From 7651e810dda86232b5e018c6d2da514fc052e9a6 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Paour Date: Fri, 20 Nov 2020 08:59:48 +0100 Subject: [PATCH 3/5] Export non-namespaced components --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 182ee5b5..ef19f06c 100755 --- a/src/index.js +++ b/src/index.js @@ -116,7 +116,7 @@ MapView.Marker = Marker; MapView.Polyline = Polyline; MapView.Callout = Callout; MapView.Geojson = Geojson; -export { Geojson }; +export { Marker, Polyline, Callout, Geojson }; const styles = StyleSheet.create({ container: { From fcb1218a5013dff813f697dd48c99647aaff4810 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Paour Date: Thu, 26 Nov 2020 16:53:16 +0100 Subject: [PATCH 4/5] Prettier fixes --- src/Geojson.js | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/src/Geojson.js b/src/Geojson.js index 00a65b92..3567a689 100644 --- a/src/Geojson.js +++ b/src/Geojson.js @@ -3,41 +3,22 @@ import MapView from './index'; export const makeOverlays = features => { const points = features - .filter( - f => - f.geometry && - (f.geometry.type === 'Point' || f.geometry.type === 'MultiPoint') - ) - .map(feature => - makeCoordinates(feature).map(coordinates => - makeOverlay(coordinates, feature) - ) - ) + .filter(f => f.geometry && (f.geometry.type === 'Point' || f.geometry.type === 'MultiPoint')) + .map(feature => makeCoordinates(feature).map(coordinates => makeOverlay(coordinates, feature))) .reduce(flatten, []) .map(overlay => ({ ...overlay, type: 'point' })); const lines = features .filter( - f => - f.geometry && - (f.geometry.type === 'LineString' || - f.geometry.type === 'MultiLineString') - ) - .map(feature => - makeCoordinates(feature).map(coordinates => - makeOverlay(coordinates, feature) - ) + f => f.geometry && (f.geometry.type === 'LineString' || f.geometry.type === 'MultiLineString') ) + .map(feature => makeCoordinates(feature).map(coordinates => makeOverlay(coordinates, feature))) .reduce(flatten, []) .map(overlay => ({ ...overlay, type: 'polyline' })); const multipolygons = features .filter(f => f.geometry && f.geometry.type === 'MultiPolygon') - .map(feature => - makeCoordinates(feature).map(coordinates => - makeOverlay(coordinates, feature) - ) - ) + .map(feature => makeCoordinates(feature).map(coordinates => makeOverlay(coordinates, feature))) .reduce(flatten, []); const polygons = features @@ -56,10 +37,7 @@ const makeOverlay = (coordinates, feature) => { let overlay = { feature, }; - if ( - feature.geometry.type === 'Polygon' || - feature.geometry.type === 'MultiPolygon' - ) { + if (feature.geometry.type === 'Polygon' || feature.geometry.type === 'MultiPolygon') { overlay.coordinates = coordinates[0]; if (coordinates.length > 1) { overlay.holes = coordinates.slice(1); From 5682a4f9a84ac9fa0b202ce1a73ee6aab1ef1802 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Paour Date: Mon, 30 Nov 2020 13:21:05 +0100 Subject: [PATCH 5/5] Fix animateToRegion --- src/index.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/index.js b/src/index.js index ef19f06c..3ff5a50f 100755 --- a/src/index.js +++ b/src/index.js @@ -17,6 +17,13 @@ function googleToReact(point) { }; } +function reactToGoogle(point) { + return { + lat: point.latitude, + lng: point.longitude, + }; +} + class MapView extends Component { state = { center: null, @@ -37,12 +44,12 @@ class MapView extends Component { animateCamera(camera) { this.setState({ zoom: camera.zoom }); - this.setState({ center: camera.center }); + this.setState({ center: reactToGoogle(camera.center) }); } animateToRegion(coordinates) { this.setState({ - center: { lat: coordinates.latitude, lng: coordinates.longitude }, + center: reactToGoogle(coordinates), }); } @@ -71,16 +78,10 @@ class MapView extends Component { ? { center } : region ? { - center: { - lat: region.latitude, - lng: region.longitude, - }, + center: reactToGoogle(region), } : { - defaultCenter: { - lat: initialRegion.latitude, - lng: initialRegion.longitude, - }, + defaultCenter: reactToGoogle(initialRegion), }; const zoom = defaultZoom ||