Created
May 19, 2020 20:32
-
-
Save basith374/a2c87be5a45636646d3dc7d90a526752 to your computer and use it in GitHub Desktop.
google maps wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { useEffect, useRef, useState } from "react"; | |
| import "./map.css"; | |
| import moment from "moment"; | |
| import _ from "lodash"; | |
| import { resolvePlugin } from "@babel/core"; | |
| /** | |
| * geofences format | |
| { | |
| geofenceid: 1, | |
| type: 'polygon', | |
| paths: [ | |
| {lat: 12.947014, lng: 77.207108}, | |
| {lat: 13.054061, lng: 77.119217}, | |
| {lat: 13.163737, lng: 77.226334}, | |
| {lat: 13.094192, lng: 77.327957}, | |
| {lat: 12.914891, lng: 77.410355}, | |
| ], | |
| }, | |
| { | |
| geofenceid: 2, | |
| type: 'circle', | |
| center: {lat: 12.960398, lng: 78.050309}, | |
| radius: 10, | |
| }, | |
| { | |
| geofenceid: 3, | |
| type: 'rectangle', | |
| bounds: { | |
| north: 12.596114, | |
| west: 77.624588, | |
| south: 12.515687, | |
| east: 77.816849, | |
| } | |
| }, | |
| */ | |
| /* | |
| props | |
| hideControls bool - hides the maximize & fit screen buttons | |
| mapClicked func - get lat lng coords when you click on map | |
| */ | |
| let assets = { | |
| blueMarker: require("./assets/blue-dot.png"), | |
| greenMarker: require("./assets/green-dot.png"), | |
| nonCommMarker: require("./assets/nocomm-dot.png"), | |
| }; | |
| window.googleMapKey = "AIzaSyBWP1I3WaF2vAUI82JpdwfW3vGhfROCFTA"; | |
| window.vehicleMap = {}; | |
| let defaultCenter = { lat: 1.330025, lng: 103.853081 }; // singapore | |
| // let defaultCenter = {lat: 12.972442, lng: 77.580643}; // bengaluru | |
| let vehicleDataMap = { | |
| direction: "dr", | |
| }; | |
| let defaultMapZoom = 9; | |
| let polygonColor = "#00ff00"; | |
| let circleColor = "#ff0000"; | |
| let rectangleColor = "#0000ff"; | |
| let getScale = (zoom) => { | |
| if (zoom >= 16) return 1; | |
| else if (zoom === 15) return 0.9; | |
| else if (zoom === 14) return 0.8; | |
| else if (zoom === 13) return 0.7; | |
| return 0.6; | |
| }; | |
| let getVehicleData = (v, k) => { | |
| let ac = _.get(vehicleDataMap, k, ""); // actual key | |
| return _.get(v, ac, ""); | |
| }; | |
| let getIcon = (vehicle, refs) => { | |
| let scale = refs.markerScale.current; | |
| let size = 32 * scale; | |
| let offset = Math.floor(getVehicleData(vehicle, "direction") / 10) * size; | |
| let url = assets.blueMarker; | |
| if (vehicle.ig) url = assets.greenMarker; | |
| if (vehicle.im) url = assets.nonCommMarker; | |
| return { | |
| url, | |
| origin: new window.google.maps.Point(0, offset), | |
| size: new window.google.maps.Size(size, size), | |
| anchor: new window.google.maps.Point(size / 2, size / 2), | |
| scaledSize: new window.google.maps.Size(size, size * 36), | |
| }; | |
| }; | |
| function updateControls(props, map) { | |
| function toggleButtonIcon() { | |
| let position = window.google.maps.ControlPosition.TOP_RIGHT; | |
| let controls = _.get(map.current.controls, position + ".g.0.children", []); | |
| let expandButton = _.find(controls, ["className", "exp"]); | |
| let bState = props.expanded ? "minimize" : "maximize"; | |
| if (expandButton) { | |
| expandButton.innerHTML = '<i class="fa fa-window-' + bState + '"></i>'; | |
| if (props.expand) expandButton.onclick = props.expand; | |
| } | |
| } | |
| function toggleControls() { | |
| let position = window.google.maps.ControlPosition.TOP_LEFT; | |
| let controls = _.get(map.current.controls, position + ".g", []); | |
| let dropdown = _.find(controls, (f) => f.classList.contains("map-lft")); | |
| if (dropdown) dropdown.style.display = props.expanded ? "flex" : "none"; | |
| } | |
| toggleButtonIcon(); | |
| toggleControls(); | |
| } | |
| function initMap(props, refs, setMapInitialized) { | |
| let mapLoaded = () => { | |
| let zoomChanged = () => { | |
| let setMarkerScale = (scale) => { | |
| if (scale) refs.markerScale.current = scale; | |
| if (props.vehicles) | |
| Object.keys(props.vehicles.data).forEach((k) => { | |
| let marker = _.get(refs, "vehicleMarkers.current." + k + ".marker"); | |
| let v = _.get(props, "vehicles.data." + k); | |
| if (marker) marker.setIcon(getIcon(v, refs)); | |
| }); | |
| }; | |
| // resize markers | |
| let level = refs.map.current.getZoom(); | |
| let scale = getScale(level); | |
| if (scale !== refs.markerScale.current) setMarkerScale(scale); | |
| if (props.zoomChanged) props.zoomChanged(level); | |
| }; | |
| const center = props.center || defaultCenter; | |
| let map = (refs.map.current = new window.google.maps.Map( | |
| document.getElementById("map"), | |
| { | |
| center, | |
| zoom: defaultMapZoom, | |
| fullscreenControl: false, | |
| mapTypeControl: false, | |
| streetViewControl: false, | |
| } | |
| )); | |
| if (!props.hideControls) attachControls(props, refs); | |
| map.addListener("zoom_changed", zoomChanged); | |
| map.addListener("click", (e) => { | |
| if (props.mapClicked) | |
| props.mapClicked(e.latLng.lat().toFixed(6), e.latLng.lng().toFixed(6)); | |
| console.log(e.latLng.lat().toFixed(6), e.latLng.lng().toFixed(6)); | |
| showHideDropdown(refs, false); | |
| }); | |
| if (props.geofence === true) { | |
| map.addListener("rightclick", (e) => { | |
| console.log("right click clicked on map"); | |
| props.openGeoCreate(e.latLng); | |
| }); | |
| } | |
| let mapLoadedListener = map.addListener( | |
| "tilesloaded", | |
| function mapFullyLoaded() { | |
| drawEvents(refs, props); | |
| drawHotspots(refs, props); | |
| drawTrace(props, refs); | |
| drawVehicles(props, refs); | |
| drawGeofences(props, refs); | |
| updateControls(props, refs.map); | |
| setMapInitialized(true); | |
| } | |
| ); | |
| refs.onMapInitialized.current = () => | |
| window.google.maps.event.removeListener(mapLoadedListener); | |
| }; | |
| if (window.google) { | |
| mapLoaded(); | |
| } else { | |
| let loadJS = (src) => { | |
| let ref = window.document.getElementsByTagName("script")[0]; | |
| let script = window.document.createElement("script"); | |
| script.src = src; | |
| script.async = true; | |
| ref.parentNode.insertBefore(script, ref); | |
| }; | |
| window.initMap = mapLoaded; | |
| let libraries = [ | |
| "places", | |
| // 'visualization', | |
| ]; | |
| let params = ["callback=initMap", "key=" + window.googleMapKey]; | |
| if (libraries.length) params.push("libraries=" + libraries.join(",")); | |
| loadJS("https://maps.googleapis.com/maps/api/js?" + params.join("&")); | |
| } | |
| } | |
| const makePolyline = (path, map) => { | |
| return new window.google.maps.Polyline({ | |
| path, | |
| icons: [ | |
| { | |
| icon: { | |
| path: window.google.maps.SymbolPath.FORWARD_CLOSED_ARROW, | |
| strokeWeight: 1, | |
| strokeColor: "#222122", | |
| fillColor: "#222122", | |
| fillOpacity: 1, | |
| scale: 1.5, | |
| }, | |
| offset: "100%", | |
| repeat: "100px", | |
| }, | |
| ], | |
| geodesic: true, | |
| strokeColor: "#2569ff", | |
| strokeOpacity: 1.0, | |
| strokeWeight: 3, | |
| map, | |
| }); | |
| }; | |
| const makeMarker = (position, map, icon, label) => { | |
| return new window.google.maps.Marker({ | |
| position, | |
| map, | |
| icon, | |
| label, | |
| }); | |
| }; | |
| const drawEvents = (refs, props) => { | |
| if (refs.eventMarkers.current) | |
| refs.eventMarkers.current.forEach((f) => f.setMap(null)); | |
| if (props.events) | |
| refs.eventMarkers.current = props.events.data.map((f) => { | |
| let icon = null; | |
| if (f.icon) { | |
| icon = { | |
| url: f.icon, | |
| }; | |
| } | |
| let marker = makeMarker(f, refs.map.current, icon); | |
| if (f.content) { | |
| let infowindow = new window.google.maps.InfoWindow({ | |
| content: f.content, | |
| }); | |
| marker.addListener("mouseover", () => | |
| infowindow.open(refs.map.current, marker) | |
| ); | |
| marker.addListener("mouseout", () => infowindow.close()); | |
| } | |
| return marker; | |
| }); | |
| }; | |
| const drawHotspots = (refs, props) => { | |
| if (refs.hotspotMarkers.current) | |
| refs.hotspotMarkers.current.forEach((f) => f.setMap(null)); | |
| if (props.hotspot) | |
| refs.hotspotMarkers.current = props.hotspot.data.map((f) => { | |
| let icon = null; | |
| if (f.icon) { | |
| let size = 32; | |
| icon = { | |
| url: f.icon, | |
| // size: new window.google.maps.Size(size, size), | |
| anchor: new window.google.maps.Point(size / 2, size / 2), | |
| scaledSize: new window.google.maps.Size(size, size), | |
| }; | |
| } | |
| let label = null; | |
| if (f.text) { | |
| label = { | |
| text: f.text, | |
| color: "#fff", | |
| fontSize: "10px", | |
| }; | |
| } | |
| return makeMarker(f, refs.map.current, icon, label); | |
| }); | |
| }; | |
| function drawTrace(props, refs) { | |
| if (props.trace) { | |
| if (!refs.trace.current) | |
| refs.trace.current = makePolyline(props.trace.data, refs.map.current); | |
| else refs.trace.current.setPath(props.trace.data); | |
| } else { | |
| if (refs.trace.current) { | |
| refs.trace.current.setMap(null); | |
| refs.trace.current = null; | |
| } | |
| } | |
| } | |
| function drawVehicles(props, refs) { | |
| if (props.vehicles) { | |
| Object.keys(props.vehicles.data).forEach((k) => { | |
| let marker; | |
| let v = _.get(props, "vehicles.data." + k); | |
| let vid = v.vp; | |
| if (refs.vehicleMarkers.current[vid]) | |
| marker = refs.vehicleMarkers.current[vid].marker; | |
| if (!marker) { | |
| marker = makeMarker( | |
| new window.google.maps.LatLng(v.lt, v.ln), | |
| refs.map.current, | |
| getIcon(v, refs) | |
| ); | |
| refs.vehicleMarkers.current[vid] = { | |
| marker, | |
| updatedAt: moment().valueOf(), | |
| }; | |
| } else { | |
| marker.setPosition(new window.google.maps.LatLng(v.lt, v.ln)); | |
| marker.setMap(refs.map.current); | |
| marker.setIcon(getIcon(v, refs)); | |
| } | |
| }); | |
| } else { | |
| Object.keys(refs.vehicleMarkers.current).forEach((f) => { | |
| let marker = _.get(refs.vehicleMarkers.current, f + ".marker"); | |
| if (marker) marker.setMap(null); | |
| }); | |
| } | |
| } | |
| function drawGeofences(props, refs) { | |
| console.log("geofence data is:", props.geofences); | |
| let geofences = _.keyBy(props.geofences, 'geofenceid'); | |
| let prevGeofences = refs.geofences.current; | |
| (props.geofences || []).forEach((g) => { | |
| if(!g.geofenceid) { | |
| return console.error('No geofenceid in provided geofence props'); | |
| } | |
| let geofence = prevGeofences[g.geofenceid]; | |
| if (!geofence) { | |
| if (g.structure === "polygon") { | |
| let color = g.color || polygonColor; | |
| geofence = new window.google.maps.Polygon({ | |
| paths: g.paths, | |
| strokeColor: color, | |
| strokeOpacity: 0.8, | |
| strokeWeight: 1, | |
| fillColor: color, | |
| fillOpacity: 0.35, | |
| map: refs.map.current, | |
| }); | |
| let pointsChanged = () => { | |
| let paths = geofence.getPath().g.map((p) => { | |
| return { | |
| lat: parseFloat(p.lat().toFixed(6)), | |
| lng: parseFloat(p.lng().toFixed(6)), | |
| }; | |
| }); | |
| props.changeGeofence(g.geofenceid, { paths }); | |
| }; | |
| geofence.getPath().addListener("set_at", pointsChanged); | |
| geofence.getPath().addListener("insert_at", pointsChanged); | |
| geofence.getPath().addListener("remove_at", pointsChanged); | |
| } else if (g.structure === "circle") { | |
| let color = g.color || circleColor; | |
| geofence = new window.google.maps.Circle({ | |
| strokeColor: color, | |
| strokeOpacity: 0.8, | |
| strokeWeight: 1, | |
| fillColor: color, | |
| fillOpacity: 0.35, | |
| center: g.center, | |
| radius: g.radius * 100, | |
| map: refs.map.current, | |
| }); | |
| geofence.addListener("radius_changed", () => { | |
| props.changeGeofence(g.geofenceid, { | |
| radius: parseFloat((geofence.getRadius() / 100).toFixed(2)), | |
| }); | |
| }); | |
| geofence.addListener( | |
| "center_changed", | |
| _.debounce(() => { | |
| let center = geofence.getCenter(); | |
| props.changeGeofence(g.geofenceid, { | |
| center: { | |
| lat: parseFloat(center.lat().toFixed(6)), | |
| lng: parseFloat(center.lng().toFixed(6)), | |
| }, | |
| }); | |
| }, 200) | |
| ); | |
| } else if (g.structure === "rectangle") { | |
| let color = g.color || rectangleColor; | |
| geofence = new window.google.maps.Rectangle({ | |
| bounds: g.bounds, | |
| strokeColor: color, | |
| strokeOpacity: 0.8, | |
| strokeWeight: 1, | |
| fillColor: color, | |
| fillOpacity: 0.35, | |
| map: refs.map.current, | |
| }); | |
| let boundsChanged = () => { | |
| props.changeGeofence(g.geofenceid, { | |
| bounds: { | |
| north: parseFloat(geofence.bounds.pa.h.toFixed(6)), | |
| west: parseFloat(geofence.bounds.ka.g.toFixed(6)), | |
| south: parseFloat(geofence.bounds.pa.g.toFixed(6)), | |
| east: parseFloat(geofence.bounds.ka.h.toFixed(6)), | |
| }, | |
| }); | |
| }; | |
| // debounce is for drag event | |
| geofence.addListener( | |
| "bounds_changed", | |
| _.debounce(boundsChanged, 200) | |
| ); | |
| } | |
| prevGeofences[g.geofenceid] = geofence; | |
| } else { | |
| // geofence.setDraggable(g.draggable); | |
| // geofence.setEditable(g.editable); | |
| geofence.setDraggable(true); | |
| geofence.setEditable(true); | |
| geofence.setMap(refs.map.current); | |
| } | |
| }); | |
| Object.keys(prevGeofences).forEach((k) => { | |
| if(!(k in geofences)) { | |
| prevGeofences[k].setMap(null); | |
| delete prevGeofences[k]; | |
| } | |
| }); | |
| } | |
| const fitBounds = (refs) => { | |
| return () => { | |
| var bounds = new window.google.maps.LatLngBounds(); | |
| let list = []; | |
| let markers = [ | |
| ...refs.eventMarkers.current, | |
| ...refs.hotspotMarkers.current, | |
| ]; | |
| markers.forEach((f) => { | |
| let lat = f.position.lat(), | |
| lng = f.position.lng(); | |
| if (!(lat === 0 && lng === 0)) { | |
| bounds.extend(f.position); | |
| list.push([lat, lng]); | |
| } | |
| }); | |
| if (refs.trace.current) | |
| refs.trace.current | |
| .getPath() | |
| .getArray() | |
| .forEach((f) => { | |
| let lat = f.lat(), | |
| lng = f.lng(); | |
| bounds.extend(f); | |
| list.push([lat, lng]); | |
| }); | |
| Object.keys(refs.vehicleMarkers.current).forEach((f) => { | |
| let marker = refs.vehicleMarkers.current[f].marker; | |
| let lat = marker.position.lat(), | |
| lng = marker.position.lng(); | |
| if (marker.getMap() && !(lat === 0 && lng === 0)) { | |
| bounds.extend(marker.position); | |
| list.push([lat, lng]); | |
| } | |
| }); | |
| if (list.length === 1) { | |
| let lat = list[0][0], | |
| lng = list[0][1]; | |
| bounds.extend({ lat: lat * 0.999, lng: lng * 0.999 }); | |
| bounds.extend({ lat: lat * 1.001, lng: lng * 1.001 }); | |
| } | |
| if (list.length) refs.map.current.fitBounds(bounds); | |
| }; | |
| }; | |
| function attachControls(props, refs) { | |
| let attachRightControls = () => { | |
| let expandButton = () => { | |
| let el = document.createElement("button"); | |
| el.className = "exp"; | |
| el.innerHTML = '<i class="fa fa-window-maximize"></i>'; | |
| if (props.expand) el.onclick = props.expand; | |
| return el; | |
| }; | |
| let fitViewButton = () => { | |
| let el = document.createElement("button"); | |
| el.innerHTML = '<i class="fa fa-crosshairs"></i>'; | |
| el.onclick = fitBounds(refs); | |
| return el; | |
| }; | |
| let position = window.google.maps.ControlPosition.TOP_RIGHT; | |
| let controls = document.createElement("div"); | |
| controls.className = "map-grc"; | |
| controls.appendChild(expandButton()); | |
| controls.appendChild(fitViewButton()); | |
| refs.map.current.controls[position].push(controls); | |
| }; | |
| let attachLeftControls = () => { | |
| let position = window.google.maps.ControlPosition.TOP_LEFT; | |
| let controls = document.createElement("div"); | |
| controls.className = "map-lft"; | |
| controls.style.display = "none"; | |
| controls.appendChild(makeDropdown(props, refs)); | |
| controls.appendChild(makeSearch(refs)); | |
| refs.map.current.controls[position].push(controls); | |
| }; | |
| attachLeftControls(); | |
| attachRightControls(); | |
| } | |
| const dropdownLabel = (label, props) => { | |
| if (label) { | |
| let [lbl, cls] = label.split(","); | |
| return ( | |
| '<div class="' + | |
| cls + | |
| '">' + | |
| lbl + | |
| ' <i class="fa fa-caret-down"></i></div>' | |
| ); | |
| } | |
| if (!props.hotspot) return "No hotspots"; | |
| return '<div>Apply filter <i class="fa fa-caret-down"></i><div>'; | |
| }; | |
| const updateDropdownLabel = (map, label, props) => { | |
| let position = window.google.maps.ControlPosition.TOP_LEFT; | |
| let controls = _.get(map.controls, position + ".g.0.children", []); | |
| let dropdown = _.find(controls, (f) => f.classList.contains("map-grd")); | |
| // let button = dropdown.querySelector("button"); | |
| // button.innerHTML = dropdownLabel(label, props); | |
| }; | |
| const makeDropdown = (props, refs) => { | |
| let dropdownButton = () => { | |
| let el = document.createElement("button"); | |
| el.innerHTML = dropdownLabel("", props); | |
| el.onclick = () => { | |
| if (el.innerHTML !== "No hotspots") showHideDropdown(refs); | |
| }; | |
| return el; | |
| }; | |
| let dropdownList = () => { | |
| let makeOpt = (cls, lbl) => { | |
| let el = document.createElement("div"); | |
| el.className = cls; | |
| el.innerText = lbl; | |
| el.onclick = () => { | |
| updateDropdownLabel(refs.map.current, lbl + "," + cls, props); | |
| showHideDropdown(refs); | |
| if (props.selectOpt) props.selectOpt(lbl); | |
| }; | |
| return el; | |
| }; | |
| let el = document.createElement("div"); | |
| el.className = "list"; | |
| el.appendChild(makeOpt("red", "Acceleration")); | |
| el.appendChild(makeOpt("blu", "Braking")); | |
| el.appendChild(makeOpt("pur", "All")); | |
| return el; | |
| }; | |
| let dropdown = document.createElement("div"); | |
| dropdown.className = "map-grd"; | |
| dropdown.appendChild(dropdownButton()); | |
| dropdown.appendChild(dropdownList()); | |
| return dropdown; | |
| }; | |
| const makeSearch = (refs) => { | |
| let search = document.createElement("div"); | |
| search.className = "map-sch"; | |
| let input = document.createElement("input"); | |
| input.placeholder = "Search"; | |
| let searchBox = new window.google.maps.places.SearchBox(input); | |
| window.google.maps.event.addListener(searchBox, "places_changed", () => { | |
| let places = searchBox.getPlaces(); | |
| if (places.length === 0) return; | |
| let bounds = new window.google.maps.LatLngBounds(); | |
| places.forEach((place) => { | |
| if (place.geometry.viewport) { | |
| bounds.union(place.geometry.viewport); | |
| } else { | |
| bounds.extend(place.geometry.location); | |
| } | |
| }); | |
| refs.map.current.fitBounds(bounds); | |
| }); | |
| search.appendChild(input); | |
| return search; | |
| }; | |
| const showHideDropdown = (refs, show) => { | |
| let position = window.google.maps.ControlPosition.TOP_LEFT; | |
| let controls = _.get( | |
| refs.map.current.controls, | |
| position + ".g.0.children", | |
| [] | |
| ); | |
| let dropdown = _.find(controls, (f) => f.classList.contains("map-grd")); | |
| if (dropdown) | |
| if (show !== undefined) dropdown.classList[show ? "add" : "remove"]("open"); | |
| else dropdown.classList.toggle("open"); | |
| }; | |
| const propsUpdated = (props, refs) => { | |
| // update trace | |
| if (_.get(props, "trace.updatedAt") !== refs.traceUpdatedAt.current) { | |
| drawTrace(props, refs); | |
| } | |
| // update markers (events) | |
| if (_.get(props, "events.updatedAt") !== refs.eventsUpdatedAt.current) { | |
| drawEvents(refs, props); | |
| } | |
| // update markers (vehicles) | |
| if (_.get(props, "vehicles.updatedAt") !== refs.vehiclesUpdatedAt.current) { | |
| drawVehicles(props, refs); | |
| } | |
| if (!props.hotspot && refs.prevHotspotRef.current) | |
| showHideDropdown(refs, false); | |
| }; | |
| export default function GoogleMap(props) { | |
| let { busy, msg, statusbar } = props; | |
| if (!msg) msg = ""; | |
| let vehicleMarkers = useRef({}); | |
| let eventMarkers = useRef([]); | |
| let hotspotMarkers = useRef([]); | |
| let markerScale = useRef(getScale(defaultMapZoom)); | |
| let map = useRef(); | |
| let trace = useRef(); | |
| let geofences = useRef({}); // shapes | |
| let prevHotspotRef = useRef(); | |
| let eventsUpdatedAt = useRef(); | |
| let vehiclesUpdatedAt = useRef(); | |
| let traceUpdatedAt = useRef(); | |
| // used to mark map ready status | |
| // any markers are drawn only after initial tile loaded event | |
| let [mapInitialized, setMapInitialized] = useState(false); | |
| let onMapInitialized = useRef(); | |
| useEffect(() => { | |
| let refs = { | |
| markerScale, | |
| vehicleMarkers, | |
| map, | |
| eventMarkers, | |
| hotspotMarkers, | |
| trace, | |
| onMapInitialized, | |
| geofences, | |
| }; | |
| initMap(props, refs, setMapInitialized); | |
| }, []); | |
| useEffect(() => { | |
| let refs = { | |
| markerScale, | |
| vehicleMarkers, | |
| map, | |
| eventMarkers, | |
| hotspotMarkers, | |
| prevHotspotRef, | |
| eventsUpdatedAt, | |
| vehiclesUpdatedAt, | |
| traceUpdatedAt, | |
| trace, | |
| }; | |
| if (window.google && mapInitialized) { | |
| propsUpdated(props, refs); | |
| } | |
| eventsUpdatedAt.current = _.get(props, "events.updatedAt"); | |
| traceUpdatedAt.current = _.get(props, "trace.updatedAt"); | |
| vehiclesUpdatedAt.current = _.get(props, "vehicles.updatedAt"); | |
| }, [props]); | |
| function hotspotUpdated() { | |
| drawHotspots( | |
| { | |
| hotspotMarkers, | |
| map, | |
| }, | |
| props | |
| ); | |
| updateDropdownLabel(map.current, "", props); | |
| } | |
| useEffect(() => { | |
| if (window.google && mapInitialized) { | |
| if ( | |
| _.get(props, "hotspot.updatedAt") !== | |
| _.get(prevHotspotRef, "current.updatedAt") | |
| ) { | |
| hotspotUpdated(); | |
| } | |
| } | |
| prevHotspotRef.current = props.hotspot; | |
| }, [props.hotspot]); | |
| useEffect(() => { | |
| console.log("google map recv new geofence data"); | |
| if (window.google && mapInitialized) { | |
| let refs = { | |
| geofences, | |
| map, | |
| }; | |
| drawGeofences(props, refs); | |
| } | |
| }, [props.geofences]); | |
| // one time, used as callback to map initialized | |
| useEffect(() => { | |
| if (mapInitialized) { | |
| onMapInitialized.current(); | |
| hotspotUpdated(); | |
| } | |
| }, [mapInitialized]); | |
| useEffect(() => { | |
| if (!window.google) return; | |
| updateControls(props, map); | |
| }, [props.expanded]); | |
| return ( | |
| <div className="map-gc"> | |
| <div className="map-gm" id="map"></div> | |
| {busy && <div className="map-gb"></div>} | |
| {msg && <div className="map-gh">{msg}</div>} | |
| {statusbar && <div className="map-sb"></div>} | |
| </div> | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment