diff --git a/package-lock.json b/package-lock.json index 4623ccc..4f290a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "react-test-renderer": "^16.8.6" }, "engines": { - "node": ">=10.15.3 <11.00", + "node": ">=16", "npm": "~6.8.0" } }, diff --git a/package.json b/package.json index 8f145a9..f8b6871 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "url": "https://github.com/data-mermaid/mermaid-dash/issues" }, "engines": { - "node": ">=10.15.3 <11.00", + "node": ">=16", "npm": "~6.8.0" }, "scripts": { @@ -85,4 +85,4 @@ "git add" ] } -} \ No newline at end of file +} diff --git a/src/components/LeafletMap.js b/src/components/LeafletMap.js index 775d749..0aa0c32 100644 --- a/src/components/LeafletMap.js +++ b/src/components/LeafletMap.js @@ -198,7 +198,7 @@ class LeafletMap extends Component { if (mapBoundingBoxCorner !== prevMapBoundingBoxCorner) this.updateBoundingBoxFromPan() // Redraw leaflet map when dashboard is open or close - if (sidePanelOpen !== prevSidePanelOpen) this.map.invalidateSize() + if (sidePanelOpen !== prevSidePanelOpen) this.updateBoundingBoxMapResize() // Reset when selected site view is set to center if (!sidePanelOpen && sidePanelOpen !== prevSidePanelOpen) @@ -313,7 +313,7 @@ class LeafletMap extends Component { if (zoomFullMap) { if (mapBounds) { - const bbox = this.createBoundingBox(mapBounds) + const bbox = mapBounds this.map.fitBounds(mapBounds) fullMapZoomHandler(false) @@ -354,72 +354,6 @@ class LeafletMap extends Component { return coordinatesSizeResult && siteNamesSizeResult } - splitWestEast(w, e) { - const { mapBounds } = this.state - const maxBounds = mapBounds && mapBounds.getEast() - const minBounds = mapBounds && mapBounds.getWest() - const eastSide = maxBounds || e - - if (mapBounds && (e < minBounds || w > maxBounds)) { - // console.log('Out of bounds case') - return [[]] - } else if (eastSide <= 180) { - // console.log('When all markers locates on [0, 180]') - return [[w, e]] - } else if (eastSide > 180) { - // console.log('When all markers locates on [0, 360]') - if (w > 180) { - // console.log('Markers west and east are > 180, example: Belize') - return [[w - 360, eastSide - 360]] - } else if (minBounds && w < minBounds) { - if (e < 180) { - // console.log('Markers west and east stay between minBounds and east') - return [[minBounds, e]] - } else if (e > maxBounds) { - // console.log('When map is moving to right, and east is at maxBounds') - return [ - [minBounds, 180], - [-180, maxBounds - 360], - ] - } - - // console.log('When map is moving to west (LEFT) side') - return [ - [minBounds, 180], - [-180, e - 360], - ] - } else if (w > 0 && e < 180) { - // console.log('Markers west and east stay between 0 and 180. example: Indonesia') - return [[w, e]] - } else if (e < maxBounds) { - // console.log('Left side of Belize') - return [ - [w, 180], - [-180, e - 360], - ] - } - - // console.log('When map is moving to east (RIGHT) side'); - return [ - [w, 180], - [-180, eastSide - 360], - ] - } - - return [[]] - } - - createBoundingBox(boundingBox) { - const north = boundingBox.getNorth() - const east = boundingBox.getEast() - const south = boundingBox.getSouth() - const west = boundingBox.getWest() - - return this.splitWestEast(west, east).map(bound => { - return this.#buildBbox(north, bound[1], south, bound[0]) - }) - } - updateBoundingBoxFromZoom() { const { getMapBounds, contentLoadHandler } = this.props const { mapZoomLevel } = this.state @@ -429,14 +363,13 @@ class LeafletMap extends Component { this.map.once('zoomend', e => { const curBounds = e.target.getBounds() const curZoom = e.target.getZoom() - const curBBox = this.createBoundingBox(curBounds) if (mapZoomLevel === curZoom) { this.setState({ mapZoomLevel: curZoom + 1 }) contentLoadHandler(false) } else { this.setState({ mapZoomLevel: curZoom }) - getMapBounds(curBBox) + getMapBounds(curBounds) } }) } @@ -450,7 +383,6 @@ class LeafletMap extends Component { this.map.once('dragend', e => { const curBounds = e.target.getBounds() const southBound = curBounds.getSouth() - const curBBox = this.createBoundingBox(curBounds) setTimeout(() => { if (mapBoundingBoxCorner === southBound) { @@ -458,12 +390,30 @@ class LeafletMap extends Component { contentLoadHandler(false) } else { this.setState({ mapBoundingBoxCorner: southBound }) - getMapBounds(curBBox) + getMapBounds(curBounds) } }, 750) }) } + updateBoundingBoxMapResize() { + const { mapBoundingBoxCorner } = this.state + const { getMapBounds, contentLoadHandler } = this.props + + this.map.invalidateSize() + + const curBounds = this.map.getBounds() + const southBound = curBounds.getSouth() + + if (mapBoundingBoxCorner === southBound) { + this.setState({ mapBoundingBoxCorner: southBound + 0.1 }) + contentLoadHandler(false) + } else { + this.setState({ mapBoundingBoxCorner: southBound }) + getMapBounds(curBounds) + } + } + createPopup(markersData, coordinates) { const popUpContentStyles = markersData.length >= 10 || this.#countClusterPopupChar(markersData) >= 450 @@ -608,7 +558,6 @@ class LeafletMap extends Component { this.map.fitBounds(markerBounds) const mapBounds = this.map.getBounds() - const mapBoundingBox = this.createBoundingBox(mapBounds) const mapBoundingBoxCorner = mapBounds.getSouth() this.setState({ @@ -617,7 +566,7 @@ class LeafletMap extends Component { mapBounds, }) - getMapBounds(mapBoundingBox) + getMapBounds(mapBounds) } this.map.addLayer(markersCluster) diff --git a/src/components/MermaidDash.js b/src/components/MermaidDash.js index 33d084e..1c0aa2b 100644 --- a/src/components/MermaidDash.js +++ b/src/components/MermaidDash.js @@ -77,7 +77,6 @@ class MermaidDash extends Component { } this.fetchAllSites(paramsObj) - this.fetchAllSitesWithEmptyQueryParams() if (countryName) { filterParams.country = countryName.split(',') @@ -227,7 +226,9 @@ class MermaidDash extends Component { const { filterChoices } = this.state const projectsParam = updatedParams.project_id && updatedParams.project_id.split(/,(?=\S)|:/) const organizationsParam = updatedParams.tag_id && updatedParams.tag_id.split(/,(?=\S)|:/) - const projectApi = summary.get('/projects/?showall&status=90&limit=1000') + const projectApi = summary.get( + '/projects/?showall&status=90&limit=1000&fields=id,name,countries,tags', + ) const organizationApi = summary.get('/projecttags/?limit=1000') const choicesApi = summary.get('/choices/') const fishFamiliesApi = summary.get('fishfamilies/?limit=500') @@ -542,19 +543,55 @@ class MermaidDash extends Component { contentLoadHandler = option => this.setState({ isLoading: option }) filterSites = (sites, bbox) => { - const bboxList = this.getBboxXY(bbox) + const normalizeLongitude = lon => { + let lng = lon + + while (lng < -180) { + lng += 360 + } + while (lng > 180) { + lng -= 360 + } + + return lng + } - return sites.reduce((newSites, site) => { + const x1 = bbox._southWest.lng + const x2 = bbox._northEast.lng + const y1 = bbox._southWest.lat + const y2 = bbox._northEast.lat + const searchBoxes = [] + + if (x1 < -180 && x2 > 180) { + searchBoxes.push([-180, y1, 180, y2]) + } else if ((x1 > 180 && x2 > 180) || (x1 < -180 && x2 <= 180)) { + searchBoxes.push([normalizeLongitude(x1), y1, normalizeLongitude(x2), y2]) + } else if (x1 >= -180 && x2 > 180) { + searchBoxes.push([x1, y1, 180, y2]) + searchBoxes.push([-180, y1, normalizeLongitude(x2), y2]) + } else if (x1 < -180 && x2 <= 180) { + searchBoxes.push([-180, y1, x2, y2]) + searchBoxes.push([normalizeLongitude(x1), y1, 180, y2]) + } else { + searchBoxes.push([x1, y1, x2, y2]) + } + + const filteredSites = sites.reduce((newSites, site) => { const { longitude, latitude } = site[1][0] - for (const { x, y } of bboxList) { - if (longitude >= x[0] && longitude <= x[1] && latitude >= y[0] && latitude <= y[1]) { - newSites.push(site) - } + const is_in_bbox = + searchBoxes.filter(([_x1, _y1, _x2, _y2]) => { + return longitude >= _x1 && longitude <= _x2 && latitude >= _y1 && latitude <= _y2 + }).length > 0 + + if (is_in_bbox) { + newSites.push(site) } return newSites }, []) + + return filteredSites } filterHandler = ({ country, project, organization, sample_date_after, sample_date_before }) => {