Skip to content

Commit

Permalink
#3045: Add all locations overlay to the map
Browse files Browse the repository at this point in the history
  • Loading branch information
ysf-simsoft committed Jun 13, 2020
1 parent e4da5a0 commit 7b8d1a8
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 1 deletion.
97 changes: 96 additions & 1 deletion client/src/components/Leaflet.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import API from "api"
import { gql } from "apollo-boost"
import { Control, CRS, Icon, Map, Marker, TileLayer } from "leaflet"
import "leaflet-defaulticon-compatibility"
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css"
Expand All @@ -14,13 +16,29 @@ import "leaflet.markercluster/dist/MarkerCluster.css"
import "leaflet.markercluster/dist/MarkerCluster.Default.css"
import "leaflet/dist/leaflet.css"
import { Location } from "models"
import GeoLocation from "pages/locations/GeoLocation"
import PropTypes from "prop-types"
import React, { useCallback, useEffect, useRef, useState } from "react"
import ReactDOM from "react-dom"
import MARKER_FLAG_BLUE from "resources/leaflet/marker-flag-blue.png"
import MARKER_ICON_2X from "resources/leaflet/marker-icon-2x.png"
import MARKER_ICON from "resources/leaflet/marker-icon.png"
import MARKER_SHADOW from "resources/leaflet/marker-shadow.png"
import Settings from "settings"

const allLocationsQuery = gql`
query {
locationList(query: { pageSize: 0 }) {
list {
uuid
name
lat
lng
}
}
}
`

const css = {
zIndex: 1
}
Expand Down Expand Up @@ -68,6 +86,13 @@ const icon = new Icon({
shadowSize: [41, 41]
})

const icon2 = new Icon({
iconUrl: MARKER_FLAG_BLUE,
iconSize: [64, 64],
iconAnchor: [32, 64],
popupAnchor: [4, -58]
})

const addLayers = (map, layerControl) => {
let defaultLayer = null
Settings.imagery.baseLayers.forEach(layerConfig => {
Expand Down Expand Up @@ -112,6 +137,8 @@ const Leaflet = ({

const [map, setMap] = useState(null)
const [markerLayer, setMarkerLayer] = useState(null)
const [layerControl, setLayerControl] = useState(null)
const [allLocationsLayer, setAllLocationsLayer] = useState(null)
const [doInitializeMarkerLayer, setDoInitializeMarkerLayer] = useState(false)
const prevMarkersRef = useRef()

Expand All @@ -125,7 +152,8 @@ const Leaflet = ({
icon: icon,
draggable: m.draggable || false,
autoPan: m.autoPan || false,
id: m.id
id: m.id,
zIndexOffset: 1000
})
if (m.name) {
marker.bindPopup(m.name)
Expand Down Expand Up @@ -170,6 +198,7 @@ const Leaflet = ({
const layerControl = new Control.Layers({}, {}, { collapsed: false })
layerControl.addTo(newMap)
addLayers(newMap, layerControl)
setLayerControl(layerControl)

setMap(newMap)

Expand Down Expand Up @@ -242,6 +271,72 @@ const Leaflet = ({
widthPropUnchanged
])

const { data } = API.useApiQuery(allLocationsQuery)

if (
data?.locationList?.list?.length &&
map &&
layerControl &&
!allLocationsLayer
) {
const allMarkers = data.locationList.list
.filter(loc => Location.hasCoordinates(loc))
.map(location => {
const popupContent = document.createElement("div")
popupContent.setAttribute("style", "width: 300px;text-align: center")

return new Marker([location.lat, location.lng], {
icon: icon2,
draggable: false,
autoPan: false,
id: location.uuid
})
.bindPopup(popupContent)
.on("popupopen", e => {
// TODO LinkTo component will be utilized here to provide routing
ReactDOM.render(
<>
<b>{location.name}</b> @{" "}
<GeoLocation lat={location.lat} lng={location.lng} />
</>,
e.popup.getContent()
)
})
})

const locationsLayer = new MarkerClusterGroup()
.addLayers(allMarkers)
.on("add", () => {
if (markers?.length && markers.some(m => m.onMove)) {
return // While editing a location don't change zoom levels
}

map.fitBounds(locationsLayer.getBounds())
})
.on("remove", () => {
if (markers?.length && markers.some(m => m.onMove)) {
return // While editing a location don't change zoom levels
}

const curMarkersWithLatLng = (markers || [])
.filter(m => Location.hasCoordinates(m))
.map(m => new Marker([m.lat, m.lng]))

if (curMarkersWithLatLng.length) {
map.fitBounds(
new MarkerClusterGroup()
.addLayers(curMarkersWithLatLng)
.getBounds(),
{ maxZoom: 15 }
)
}
})

layerControl.addOverlay(locationsLayer, "All Locations")

setAllLocationsLayer(locationsLayer)
}

return <div id={mapId} style={style} />
}
Leaflet.propTypes = {
Expand Down
Binary file added client/src/resources/leaflet/marker-flag-blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/resources/leaflet/marker-flag-red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 7b8d1a8

Please sign in to comment.