Skip to content

Commit

Permalink
OutlinePolygon
Browse files Browse the repository at this point in the history
  • Loading branch information
johannesbrandenburger committed Dec 24, 2022
1 parent 55b18fa commit fc3be95
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 7 deletions.
86 changes: 86 additions & 0 deletions src/components/OutlinePolygon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React from "react";
import { Polygon } from "react-leaflet";

class OutlinePolygon extends React.Component {
constructor(props) {
super(props);
this.state = {
polyLatLngs: [],
};
}

async componentDidUpdate(prevProps) {
if (this.props.placeName === prevProps.placeName) return;
this.setState({ polyLatLngs: [] });

// fetch the polygon outline from the OpenStreetMap API (Nominatim)
// this is not done in the main component because loading the polygon outline
// takes more time than the normal API call
const response = await fetch(
// eslint-disable-next-line max-len
`https://nominatim.openstreetmap.org/search?q=${this.props.placeName}&format=json&limit=1&polygon_geojson=1&polygon_threshold=0.0005`,
);
// check if the response is suited for a polygon outline
const data = await response.json();
if (
data[0]?.geojson?.coordinates === undefined ||
data[0]?.geojson?.type === undefined ||
data[0]?.boundingbox === undefined ||
(data[0]?.geojson?.type !== "Polygon" && data[0]?.geojson?.type !== "MultiPolygon") ||
(data[0]?.class !== "boundary" && data[0]?.class !== "place" && data[0]?.class !== "landuse")
) {
this.setState({ polyLatLngs: [] });
return;
}

const latLngs = this.convertGeoJsonCoordsToLeafletLatLng(data[0].geojson.coordinates);
this.setState({ polyLatLngs: latLngs });
}

/**
* Converts the coordinates of a GeoJSON polygon to the format used by Leaflet
* @param {number[]} coords The coordinates of the GeoJSON polygon
* @returns {number[]} The coordinates for the Leaflet polygon
*/
convertGeoJsonCoordsToLeafletLatLng = coords => {
if (coords === undefined) return [];

const transformCoords = coords => {
if (
Array.isArray(coords) &&
coords.length === 2 &&
typeof coords[0] === "number" &&
typeof coords[1] === "number"
) {
return { lat: coords[1], lng: coords[0] };
}
return coords.map(transformCoords);
};

const latLngs = transformCoords(coords);

return latLngs;
};

render() {
if (this.state.polyLatLngs.length === 0) return null;

return (
<Polygon
positions={this.state.polyLatLngs}
color="blue"
weight={1}
opacity={0.2}
fillOpacity={0.05}
smoothFactor={1}
/>
);
}
}

// define the types of the properties that are passed to the component
OutlinePolygon.prototype.props = /** @type { {
placeName: string,
} } */ ({});

export default OutlinePolygon;
17 changes: 10 additions & 7 deletions src/pages/home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "leaflet/dist/leaflet.css";
import SnappingSheet from "../components/SnappingSheet";
import LocationMarker from "../components/LocationMarker";
import AccuracyCircle from "../components/AccuracyCircle";
import OutlinePolygon from "../components/OutlinePolygon";

const SEARCH_BAR_HEIGHT = 70;

Expand Down Expand Up @@ -72,15 +73,16 @@ class Home extends React.Component {
}, 5000);
}

/*
/**
* Search for a place by text or coordinates
* @param {string} searchText
*/
updatePlaceBySearch = async () => {
const coords = this.getCoordsFromSearchText(this.state.searchText);
updatePlaceBySearch = async searchText => {
const coords = this.getCoordsFromSearchText(searchText);

let place = {};
if (coords !== undefined) place = await this.getPlaceByCoords(coords);
else place = await this.getPlaceByText(this.state.searchText);
else place = await this.getPlaceByText(searchText);

console.log("place in updatePlaceBySearch", place);

Expand Down Expand Up @@ -237,7 +239,7 @@ class Home extends React.Component {
const latDiff = Math.abs(lat1 - lat2);
const lngDiff = Math.abs(lng1 - lng2);
const maxDiff = Math.max(latDiff, lngDiff);
const zoom = Math.round(Math.log(360 / maxDiff) / Math.log(2));
const zoom = Math.min(Math.round(Math.log(360 / maxDiff) / Math.log(2)), 18);
return zoom;
}

Expand Down Expand Up @@ -336,6 +338,7 @@ class Home extends React.Component {
anchor={{ x: 20, y: 40 }}
/>
<this.MapHook />
<OutlinePolygon placeName={this.state.place.name} />
</MapContainer>

<SnappingSheet
Expand All @@ -356,7 +359,7 @@ class Home extends React.Component {
}}
onSubmit={event => {
event.target.blur(); // hide keyboard TODO: this is not working yet
this.updatePlaceBySearch();
this.updatePlaceBySearch(this.state.searchText);
}}
onClickClear={() => {
this.setState({ searchText: "", showSearchSuggestions: false, searchSuggestions: [] });
Expand All @@ -374,7 +377,7 @@ class Home extends React.Component {
title={suggestion["displayName"]}
onClick={() => {
this.setState({ searchText: suggestion["displayName"], showSearchSuggestions: false });
this.updatePlaceBySearch();
this.updatePlaceBySearch(suggestion["displayName"]);
}}
style={{ cursor: "pointer" }}
/>
Expand Down

0 comments on commit fc3be95

Please sign in to comment.