aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/MapBox/MapBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/MapBox/MapBox.tsx')
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx355
1 files changed, 279 insertions, 76 deletions
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 36be7d257..c44f5765a 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -1,6 +1,7 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Autocomplete, GoogleMap, GoogleMapProps, Marker } from '@react-google-maps/api';
+import { GoogleMapProps, Marker } from '@react-google-maps/api';
import BingMapsReact from 'bingmaps-react';
+import { EditableText } from 'browndash-components';
import { action, computed, IReactionDisposer, observable, ObservableMap, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -24,7 +25,7 @@ import { FieldView, FieldViewProps } from '../FieldView';
import { PinProps } from '../trails';
import './MapBox.scss';
import { MapBoxInfoWindow } from './MapBoxInfoWindow';
-
+// amongus
/**
* MapBox architecture:
* Main component: MapBox.tsx
@@ -218,6 +219,27 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
controlDiv.appendChild(controlUI);
return controlDiv;
};
+ /**
+ * Load and render all map markers
+ * @param marker
+ * @param place
+ */
+ @action
+ private markerLoadHandler = (marker: google.maps.Marker, place: Doc) => {
+ place[Id] ? (this.markerMap[place[Id]] = marker) : null;
+ };
+
+ /**
+ * on clicking the map marker, set the selected place to the marker document & set infowindowopen to be true
+ * @param e
+ * @param place
+ */
+ @action
+ private markerClickHandler = (e: google.maps.MapMouseEvent, place: Doc) => {
+ // set which place was clicked
+ this.selectedPlace = place;
+ // place.infoWindowOpen = true;
+ };
/**
* Place the marker on google maps & store the empty marker as a MapMarker Document in allMarkers list
@@ -298,25 +320,49 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
/**
- * Load and render all map markers
- * @param marker
- * @param place
+ * function that reads the place inputed from searchbox, then zoom in on the location that's been autocompleted;
+ * add a customized temporary marker on the map
*/
@action
- private markerLoadHandler = (marker: google.maps.Marker, place: Doc) => {
- place[Id] ? (this.markerMap[place[Id]] = marker) : null;
- };
+ private handlePlaceChanged = () => {
+ const place = this.searchBox.getPlace();
- /**
- * on clicking the map marker, set the selected place to the marker document & set infowindowopen to be true
- * @param e
- * @param place
- */
- @action
- private markerClickHandler = (e: google.maps.MapMouseEvent, place: Doc) => {
- // set which place was clicked
- this.selectedPlace = place;
- place.infoWindowOpen = true;
+ if (!place.geometry || !place.geometry.location) {
+ // user entered the name of a place that wasn't suggested & pressed the enter key, or place details request failed
+ window.alert("No details available for input: '" + place.name + "'");
+ return;
+ }
+
+ // zoom in on the location of the search result
+ if (place.geometry.viewport) {
+ this._map.fitBounds(place.geometry.viewport);
+ } else {
+ this._map.setCenter(place.geometry.location);
+ this._map.setZoom(17);
+ }
+
+ // customize icon => customized icon for the nature of the location selected
+ 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),
+ };
+
+ // put temporary cutomized marker on searched location
+ this.searchMarkers.forEach(marker => {
+ marker.setMap(null);
+ });
+ this.searchMarkers = [];
+ this.searchMarkers.push(
+ new window.google.maps.Marker({
+ map: this._map,
+ icon,
+ title: place.name,
+ position: place.geometry.location,
+ })
+ );
};
/**
@@ -397,52 +443,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
/**
- * function that reads the place inputed from searchbox, then zoom in on the location that's been autocompleted;
- * add a customized temporary marker on the map
- */
- @action
- private handlePlaceChanged = () => {
- const place = this.searchBox.getPlace();
-
- if (!place.geometry || !place.geometry.location) {
- // user entered the name of a place that wasn't suggested & pressed the enter key, or place details request failed
- window.alert("No details available for input: '" + place.name + "'");
- return;
- }
-
- // zoom in on the location of the search result
- if (place.geometry.viewport) {
- this._map.fitBounds(place.geometry.viewport);
- } else {
- this._map.setCenter(place.geometry.location);
- this._map.setZoom(17);
- }
-
- // customize icon => customized icon for the nature of the location selected
- 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),
- };
-
- // put temporary cutomized marker on searched location
- this.searchMarkers.forEach(marker => {
- marker.setMap(null);
- });
- this.searchMarkers = [];
- this.searchMarkers.push(
- new window.google.maps.Marker({
- map: this._map,
- icon,
- title: place.name,
- position: place.geometry.location,
- })
- );
- };
-
- /**
* Handles toggle of sidebar on click the little comment button
*/
@computed get sidebarHandle() {
@@ -591,13 +591,204 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
});
};
+ /**
+ *
+ *
+ * ERIC'S BING MAP CODE BELOW
+ *
+ *
+ *
+ **/
+
+ bingSearchBarContents: any = 'Boston, MA'; // For Bing Maps: The contents of the Bing search bar (string)
+
+ geoDataRequestOptions = {
+ entityType: 'PopulatedPlace',
+ };
+
+ @action
+ updateView = () => {
+ this._bingMap.current.setView({
+ center: new this.MicrosoftMaps.Location(this.dataDoc.latitude, this.dataDoc.longitude),
+ // zoom: location
+ });
+ };
+
+ @action
+ createPushpin = (latitude: number, longitude: number) => {
+ // Stores the pushpin as a MapMarkerDocument
+ const mapMarker = Docs.Create.MapMarkerDocument(NumCast(latitude), NumCast(longitude), false, [], {});
+ this.addDocument(mapMarker, this.annotationKey);
+ mapMarker.infoWindowOpen = true;
+ };
+
+ infobox: any;
+ pushpinClicked = (e: { target: { metadata: { title: any; description: any }; getLocation: () => any } }) => {
+ //Make sure the infobox has metadata to display.
+ if (e.target.metadata) {
+ //Set the infobox options with the metadata of the pushpin. // HOW DO I GET THE CORRECT INFOBOX FOR THIS PIN? CAN I use this e?
+ this.infobox.setOptions({
+ location: e.target.getLocation(),
+ title: e.target.metadata.title,
+ description: e.target.metadata.description,
+ visible: true,
+ });
+ }
+ };
+
+ //PushpinClicked using MapBoxInfoWindow
+ private pushpinClicked2 = (e: { target: { metadata: { title: any; description: any }; getLocation: () => any } }, pin: Doc) => {
+ // // set which place was clicked
+ // this.selectedPlace = place;
+ pin.infoWindowOpen = true;
+ // console.log("later:" + pin.infoWindowOpen)
+ };
+
+ /**
+ * Returns a list of MapMarkerDocument
+ */
+ @computed get allMapPushpins() {
+ return DocListCast(this.dataDoc[this.annotationKey]);
+ }
+ /**
+ * Map OnClick create pushpin
+ */
+ @action
+ mapOnClick = (e: { location: { latitude: any; longitude: any } }) => {
+ if (this.placePinOn) {
+ this.createPushpin(e.location.latitude, e.location.longitude);
+ this.addAllPins();
+ this.placePinOn = false;
+ console.log('PUSHPIN CREATED');
+ }
+ };
+
+ searched_pin: any;
+ /*
+ * For Bing Maps
+ * Called by search button's onClick
+ * Finds the geocode of the searched contents and sets location to that location
+ **/
+ @action
+ bingSearch = async () => {
+ this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'click', this.mapOnClick);
+ this.addAllPins();
+
+ const location = await this.bingGeocode(this._bingMap, this.bingSearchBarContents);
+
+ this.dataDoc.latitude = location.latitude;
+ this.dataDoc.longitude = location.longitude;
+ this.updateView();
+
+ // Creates a temporary pin but does not add it to the dataDoc
+ var temp = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(location.latitude, location.longitude), {
+ // title: this.bingSearchBarContents,
+ // subTitle: 'subtitle here',
+ // text: '1',
+ color: 'blue',
+ });
+ if (temp != this.searched_pin || this.searched_pin == null) {
+ this._bingMap.current.entities.push(this.searched_pin);
+ this.searched_pin = temp;
+ }
+
+ // console.log(this.allMapPushpins
+ // .filter(marker => marker.infoWindowOpen)
+ // .length)
+ // console.log(this.allMapPushpins
+ // .map(marker => console.log(marker.infoWindowOpen)))
+ };
+
+ /**
+ * Adds all pushpins in dataDoc onto the map
+ */
+ @action
+ addAllPins = () => {
+ this._bingMap.current.entities.clear();
+ //TODO: clear all infoboxes
+ if (this.searched_pin) this._bingMap.current.entities.push(this.searched_pin);
+ this.allMapPushpins.map(pin => this.createInfobox(pin));
+ this.allMapPushpins.map(pin => this._bingMap.current.entities.push(pin));
+ };
+
+ @action
+ createInfobox = (pin: any) => {
+ var pushPin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {
+ // title: this.bingSearchBarContents,
+ // subTitle: 'subtitle here',
+ // text: '1'
+ });
+ this._bingMap.current.entities.push(pushPin);
+
+ var id = Utils.GenerateGuid();
+ document.getElementById(id);
+ var infoboxTemplate = '<div class="customInfobox"><div class="title">{title}</div>{description}</div>';
+ // var infowindowtemp = '<MapBoxInfoWindow key={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})[Id]}{...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit} place={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})} markerMap={this.markerMap} PanelWidth={this.infoWidth} PanelHeight={this.infoHeight} moveDocument={this.moveDocument} isAnyChildContentActive={this.isAnyChildContentActive} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}/>'
+
+ // console.log(<div id={id} style={{width:100, height:100, background:"blue"}}/>)
+ // var htmlString = ReactDOMServer.renderToString(<div id={id} style={{width:100, height:100, background:"blue"}}/>);
+
+ //Create an infobox at the pin
+ this.infobox = new this.MicrosoftMaps.Infobox(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {
+ htmlContent: infoboxTemplate, // style="width:100; height:100; background:blue"
+ visible: false,
+ });
+ try {
+ // console.log(document.getElementById(id))
+ // console.log(this.infobox)
+ // const root = ReactDOM.createRoot(document.getElementById(id)!);
+ // root.render(<div style={{width:100, height:100, background:"blue"}}/>);
+ } catch (e) {
+ console.log(e);
+ }
+
+ //Assign the infobox to a map instance.
+ this.infobox.setMap(this._bingMap.current);
+ //Store some metadata with the pushpin.
+ pushPin.metadata = {
+ title: pushPin.title,
+ description: 'Pin description',
+ };
+ // pushPin.infoWindowOpen = true;
+
+ //Add a click event handler to the pushpin.
+ // For bing maps infobox
+ // this.MicrosoftMaps.Events.addHandler(pushPin, 'click', this.pushpinClicked);
+
+ // For our infowindow
+ this.MicrosoftMaps.Events.addHandler(pushPin, 'click', (e: any) => this.pushpinClicked(e));
+ // this.MicrosoftMaps.Events.addHandler(pushPin, 'mouseover', (e:any) => this.onHover(e));
+ };
+
+ /**
+ * View options for bing maps
+ */
bingViewOptions = {
- center: { latitude: defaultCenter.lat, longitude: defaultCenter.lng },
+ center: { latitude: this.dataDoc.latitude ?? defaultCenter.lat, longitude: this.dataDoc.longitude ?? defaultCenter.lng },
+ zoom: this.dataDoc.latitude ?? 10,
mapTypeId: 'grayscale',
};
+
+ /**
+ * Map options
+ */
bingMapOptions = {
navigationBarMode: 'square',
+ backgroundColor: '#f1f3f4',
+ enableInertia: true,
+ };
+
+ /**
+ * Toggles mode for placing a pin down on map
+ */
+ @observable
+ placePinOn: boolean | undefined;
+ @action
+ togglePlacePin = () => {
+ if (this.placePinOn) this.placePinOn = false;
+ else this.placePinOn = true;
};
+
bingMapReady = (map: any) => (this._bingMap = map.map);
render() {
const renderAnnotations = (docFilters?: () => string[]) => null;
@@ -622,17 +813,18 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
{SnappingManager.GetIsDragging() ? null : renderAnnotations()}
{this.annotationLayer}
- {!MapBox.UseBing ? null : <BingMapsReact onMapReady={this.bingMapReady} bingMapsKey={bingApiKey} height="100%" mapOptions={this.bingMapOptions} width="100%" viewOptions={this.bingViewOptions} />}
- <div style={{ display: MapBox.UseBing ? 'none' : undefined }}>
- <GoogleMap mapContainerStyle={mapContainerStyle} onZoomChanged={this.zoomChanged} onCenterChanged={this.centered} onLoad={this.loadHandler} options={mapOptions}>
- <Autocomplete onLoad={this.setSearchBox} onPlaceChanged={this.handlePlaceChanged}>
- <input className="mapBox-input" ref={this.inputRef} type="text" onKeyDown={e => e.stopPropagation()} placeholder="Enter location" />
- </Autocomplete>
+ {!MapBox.UseBing ? null : <EditableText editing onEdit={(newText: string) => (this.bingSearchBarContents = newText)} placeholder="..." size="medium" text="Boston, MA" onKeyPress={(e: { key: any }) => console.log(e.key)} />}
+
+ {!MapBox.UseBing ? null : <input type="button" value="Search" onClick={this.bingSearch} />}
+
+ {!MapBox.UseBing ? null : this.placePinOn ? <input type="button" value="Place Pin Mode On" onClick={this.togglePlacePin} /> : <input type="button" value="Place Pin Mode Off" onClick={this.togglePlacePin} />}
- {this.renderMarkers()}
- {this.allMapMarkers
+ {!MapBox.UseBing ? null : (
+ <BingMapsReact onMapReady={this.bingMapReady} bingMapsKey={bingApiKey} height="100%" mapOptions={this.bingMapOptions} width="100%" viewOptions={this.bingViewOptions}>
+ {this.allMapPushpins
.filter(marker => marker.infoWindowOpen)
.map(marker => (
+ // console.log('this is a marker window')
<MapBoxInfoWindow
key={marker[Id]}
{...this.props}
@@ -646,9 +838,20 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
/>
))}
- {/* {this.handleMapCenter(this._map)} */}
- </GoogleMap>
- </div>
+ </BingMapsReact>
+ )}
+ {/* <MapBoxInfoWindow
+ key={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})[Id]}
+ {...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit}
+ place={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})}
+ markerMap={this.markerMap}
+ PanelWidth={this.infoWidth}
+ PanelHeight={this.infoHeight}
+ moveDocument={this.moveDocument}
+ isAnyChildContentActive={this.isAnyChildContentActive}
+ whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
+ /> */}
+
{!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? null : (
<MarqueeAnnotator
rootDoc={this.rootDoc}