import { GoogleMap, Marker, InfoWindow, InfoBox, LoadScript, GoogleMapProps, StandaloneSearchBox, DrawingManager } from '@react-google-maps/api'; import { observable, action, computed, Lambda, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast, Field, FieldResult, Opt } from "../../../../fields/Doc"; import { documentSchema } from "../../../../fields/documentSchemas"; import { Id } from "../../../../fields/FieldSymbols"; import { makeInterface } from "../../../../fields/Schema"; import { Cast, NumCast, ScriptCast, StrCast } from "../../../../fields/Types"; import { LinkManager } from "../../../util/LinkManager"; import { undoBatch, UndoManager } from "../../../util/UndoManager"; import "./CollectionMapView.scss"; import { CollectionSubView } from "../CollectionSubView"; import React = require("react"); import requestPromise = require("request-promise"); import ReactDOM from 'react-dom'; type MapSchema = makeInterface<[typeof documentSchema]>; const MapSchema = makeInterface(documentSchema); export type LocationData = { id?: number; pos?: { lat: number, lng: number }; }; const mapContainerStyle = { height: '100%', }; const defaultCenter = { lat: 38.685, lng: -115.234, }; @observer export default class CollectionMapView extends CollectionSubView(MapSchema) { @observable private mapRef = null as any; @observable private selectedPlace: LocationData = { id: undefined, pos: undefined }; @observable private markerMap = {}; @observable private center = defaultCenter; @observable private zoom = 2.5; @observable private clickedLatLng = null; @observable private infoWindowOpen = false; @observable private myPlaces = [ { id: 1, pos: { lat: 39.09366509575983, lng: -94.58751660204751 } }, { id: 2, pos: { lat: 41.82399, lng: -71.41283 } }, { id: 3, pos: { lat: 47.606214, lng: -122.33207 } }, { id: 4, pos: { lat: 36.7783, lng: 119.4179 } } ]; // iterate myPlaces to size, center, and zoom map to contain all markers private fitBounds = (map: any) => { const bounds = new window.google.maps.LatLngBounds(); console.log('map bound is:' + bounds); this.myPlaces.map(place => { bounds.extend(place.pos); return place.id; }); map.fitBounds(bounds) } // store a reference to google map instance; fit map bounds to contain all markers @action private loadHandler = (map: any) => { this.mapRef = map; this.fitBounds(map); // //add a custom control for button add marker // //TODO: why this doesn't work // const google = window.google; // console.log("google window: " + google) // const controlButtonDiv = document.createElement('div'); // ReactDOM.render(, controlButtonDiv); // map.controls[google.maps.ControlPosition.TOP_RIGHT].push(controlButtonDiv); } @action private markerClickHandler = (e: MouseEvent, place: LocationData) => { // set which place was clicked this.selectedPlace = place console.log(this.selectedPlace.id); console.log(this.selectedPlace.pos); // used so clicking a second marker works if (this.infoWindowOpen) { this.infoWindowOpen = false; } this.infoWindowOpen = true; } @action private handleInfoWindowClose = () => { if (this.infoWindowOpen) { this.infoWindowOpen = false; } this.infoWindowOpen = false; this.selectedPlace = { id: undefined, pos: undefined }; } // @action // private markerLoadHandler = (marker: any, place: LocationData) => { // if (marker != null) { // this.markerMap[place.id] = marker; // } // } @action @undoBatch private handleDragMarker = (marker: any, place: LocationData) => { if (marker != null) { place = { id: place.id, pos: { lat: marker.latLng.lat().toFixed(3), lng: marker.latLng.lng().toFixed(3) } } console.log(place); console.log(this.myPlaces); } } /** * func that handles user's search location and zoom/pan on the input location */ private searchLocation = () => { } /** * func that adds marker to google maps */ @undoBatch private addMarker = () => { } /** * func that updates suggested results (and auto-complete) during user input */ private handleChange = () => { } // private mapRef = document.getElementById("map") // private markers: google.maps.Marker[] = []; @observable private input: HTMLInputElement | undefined; @action private setInputRef = (element: HTMLInputElement) => { this.input = element; console.log("htmlinputelement is:" + this.input) } // private searchBox = new window.google.maps.places.SearchBox(this.input); private handlePlacesChanged = () => { const searchBox = new window.google.maps.places.SearchBox(this.input!) const places = searchBox.getPlaces(); console.log(places); if (places.length == 0) { return; } // // clear out old markers // this.markers.forEach((marker) => { // marker.setMap(null); // }); // this.markers = [] // // for each place, get icon, name, location const bounds = new window.google.maps.LatLngBounds(); places.forEach((place) => { if (!place.geometry || !place.geometry.location) { console.log("Returned place contains no geometry"); return; } // const icon = { // url: place.icon as string, // size: new google.maps.Size(71, 71), // origin: new google.maps.Point(0, 0), // anchor: new google.maps.Point(17, 34), // scaledSize: new google.maps.Size(25, 25), // } // //create a marker for each place // this.markers.push( // new google.maps.Marker({ // mapRef, // title: place.name, // position: place.geometry.location, // }) // ); if (place.geometry.viewport) { // only geocodes have viewport bounds.union(place.geometry.viewport); } else { bounds.extend(place.geometry.location); } }); } // private setBounds = () => { // const places = this.searchBox.getPlaces(); // if (places.length == 0) { return; } // const bounds = new google.maps.LatLngBounds(); // places.forEach((place) => { // if (!place.geometry || !place.geometry.location) { // console.log("Returned place contains no geometry"); // return; // } // if (place.geometry.viewport) { // // only geocodes have viewport // bounds.union(place.geometry.viewport); // } // else { // bounds.extend(place.geometry.location); // } // }); // return bounds // } private onPolygonComplete = (polygon: any) => { console.log(polygon) } private onMarkerComplete = (marker: any) => { this.myPlaces.push(marker) } render() { const { Document, fieldKey, isContentActive: active } = this.props; return
e.stopPropagation()} onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} >
this.loadHandler(map)} > {this.myPlaces.map(place => ( this.markerLoadHandler(marker, place)} onClick={e => this.markerClickHandler(e, place)} draggable={true} onDragEnd={marker => this.handleDragMarker(marker, place)} /> ))} {this.infoWindowOpen && this.selectedPlace && ( )} {/* */}
; } }