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.tsx96
1 files changed, 58 insertions, 38 deletions
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 9cee7f2a2..6894cea19 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Autocomplete, GoogleMap, GoogleMapProps, InfoWindow, Marker } from '@react-google-maps/api';
+import { Autocomplete, GoogleMap, GoogleMapProps, InfoWindow, LoadScript, Marker } from '@react-google-maps/api';
import { action, computed, IReactionDisposer, observable, ObservableMap } from 'mobx';
import { observer } from "mobx-react";
import * as React from "react";
@@ -29,22 +29,25 @@ import { SidebarAnnos } from '../../SidebarAnnos';
import { StyleProp } from '../../StyleProvider';
import { FieldView, FieldViewProps } from '../FieldView';
import "./MapBox.scss";
-import { MapMarker } from './MapMarker';
-const _global = (window /* browser */ || global /* node */) as any;
+
+/**
+ * MapBox architecture:
+ * Main component: MapBox.tsx
+ * Supporting Components: SidebarAnnos, CollectionStackingView
+ *
+ * MapBox is a node that extends the ViewBoxAnnotatableComponent. Similar to PDFBox and WebBox, it supports interaction between sidebar content and document content.
+ * The main body of MapBox uses Google Maps API to allow location retrieval, adding map markers, pan and zoom, and open street view.
+ * Dash Document architecture is integrated with Maps API: When drag and dropping documents with ExifData (gps Latitude and Longitude information) available,
+ * sidebarAddDocument function checks if the document contains lat & lng information, if it does, then the document is added to both the sidebar and the infowindow (a pop up corresponding to a map marker--pin on map).
+ * The lat and lng field of the document is filled when importing (spec see ConvertDMSToDD method and processFileUpload method in Documents.ts).
+ * A map marker is considered a document that contains a collection with stacking view of documents, it has a lat, lng location, which is passed to Maps API's custom marker (red pin) to be rendered on the google maps
+ */
+
+// const _global = (window /* browser */ || global /* node */) as any;
type MapDocument = makeInterface<[typeof documentSchema]>;
const MapDocument = makeInterface(documentSchema);
-export type Coordinates = {
- lat: number,
- lng: number,
-}
-
-export type LocationData = {
- id: string;
- pos: Coordinates;
-};
-
const mapContainerStyle = {
height: '100%',
};
@@ -58,6 +61,9 @@ const mapOptions = {
fullscreenControl: false,
}
+/**
+ * Consider integrating later: allows for drawing, circling, making shapes on map
+ */
const drawingManager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
@@ -65,13 +71,14 @@ const drawingManager = new google.maps.drawing.DrawingManager({
drawingModes: [
google.maps.drawing.OverlayType.MARKER,
// currently we are not supporting the following drawing mode on map, a thought for future development
- // google.maps.drawing.OverlayType.CIRCLE,
- // google.maps.drawing.OverlayType.POLYLINE,
+ google.maps.drawing.OverlayType.CIRCLE,
+ google.maps.drawing.OverlayType.POLYLINE,
],
},
});
+// options for searchbox in Google Maps Places Autocomplete API
const options = {
fields: ["formatted_address", "geometry", "name"], // note: level of details is charged by item per retrieval, not recommended to return all fields
strictBounds: false,
@@ -96,7 +103,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
// @observable private markerIdToMapMarker: { [id: string]: Doc | MapMarker | undefined } = {};
@observable private center = navigator.geolocation ? navigator.geolocation.getCurrentPosition : defaultCenter;
@observable private zoom = 2.5;
- @observable private infoWindowOpen = false;
@observable private _marqueeing: number[] | undefined;
@observable private _isAnnotating = false;
@observable private bounds = new window.google.maps.LatLngBounds();
@@ -105,10 +111,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options);
@observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
@computed get allSidebarDocs() { return DocListCast(this.dataDoc[this.SidebarKey]); };
- @computed get allMapMarkers() { return DocListCast(this.dataDoc[this.annotationKey]); }; // method to add MapMarker to allMapMarkers
- //TODO: change all markers to a filter function to change
+ @computed get allMapMarkers() { return DocListCast(this.dataDoc[this.annotationKey]); };
@observable private toggleAddMarker = false;
-
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
@@ -241,18 +245,26 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
console.log(this.allMapMarkers)
}
})
- // this._map.addListener(drawingManager, 'markercomplete', this.addMarker)
}
+ /**
+ * 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;
- // place[Id] ? this.markerIdToMapMarker[place[Id]] = place : null;
console.log("the following is a markerMap from id to Marker:")
console.log(this.markerMap);
}
+ /**
+ * 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: MouseEvent, place: Doc) => {
// set which place was clicked
@@ -266,7 +278,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
/**
- * Called when dragging documents into map sidebar or directly into infowindow
+ * Called when dragging documents into map sidebar or directly into infowindow; to create a map marker, ref to MapMarkerDocument in Documents.ts
* @param doc
* @param sidebarKey
* @returns
@@ -294,6 +306,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return this.addDocument(doc, sidebarKey); // add to sidebar list
}
+ /**
+ * Removing documents from the sidebar
+ * @param doc
+ * @param sidebarKey
+ * @returns
+ */
sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
if (this.layoutDoc._showSidebar) this.toggleSidebar();
const docs = doc instanceof Doc ? [doc] : doc;
@@ -386,6 +404,9 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
place.infoWindowOpen = false;
}
+ /**
+ * Handles toggle of sidebar on click the little comment button
+ */
@computed get sidebarHandle() {
TraceMobx();
const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
@@ -403,6 +424,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
</div>;
}
+ // TODO: Adding highlight box layer to Maps
@action
toggleSidebar = () => {
const prevWidth = this.sidebarWidth();
@@ -459,20 +481,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
getAnchor = () => {
const anchor =
AnchorMenu.Instance?.GetAnchor(this._savedAnnotations) ??
- this.rootDoc // if anchormenu pops up else return rootDoc (map)
- // Docs.Create.MapMarkerDocument(this.allMapMarkers, {
- // title: StrCast(this.rootDoc.title + " " + this.layoutDoc._scrollTop),
- // annotationOn: this.rootDoc,
- // y: NumCast(this.layoutDoc._scrollTop),
- // });
- // this.addDocument(anchor);
+ this.rootDoc
return anchor;
}
infoWidth = () => this.props.PanelWidth() / 5;
infoHeight = () => this.props.PanelWidth() / 5;
- //documentView
+ // Collection stacking view for documents in the infowindow of a map marker
private renderChildDocs = (selectedDoc: Doc) => {
return <div style={{ width: this.infoWidth(), height: this.infoHeight() }}>
<CollectionStackingView {
@@ -521,6 +537,11 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
))
}
+ /**
+ * Renders infowindow corresponding to a map marker document
+ * @param place
+ * @returns
+ */
private renderInfoWindow = (place: Doc) => {
return place.infoWindowOpen && (
@@ -540,6 +561,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
)
}
+ // TODO: auto center on select a document in the sidebar
private handleMapCenter = (map: google.maps.Map) => {
console.log("print the selected views in selectionManager:")
if (SelectionManager.Views().lastElement()) {
@@ -579,13 +601,11 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
addDocument={this.sidebarAddDocument}
childPointerEvents={true}
pointerEvents={CurrentUserUtils.SelectedTool !== InkTool.None || this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} />;
- return <div className="mapBox" ref={this._ref}
- // style={{ pointerEvents: this.isContentActive() ? undefined : "none" }}
- >
- {/* // {/* <LoadScript
- // googleMapsApiKey={process.env.GOOGLE_MAPS!}
- // libraries={['places', 'drawing']}
- // > */}
+ return <div className="mapBox" ref={this._ref}>
+ {/* <LoadScript
+ googleMapsApiKey={process.env.GOOGLE_MAPS!}
+ libraries={['places', 'drawing']}
+ > */}
<div className="mapBox-wrapper"
onWheel={e => e.stopPropagation()}
onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()}
@@ -627,7 +647,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
annotationLayer={this._annotationLayer.current}
mainCont={this._mainCont.current} />}
</div>
- {/* {/* </LoadScript > */}
+ {/* </LoadScript > */}
<div className="mapBox-sidebar"
style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
<SidebarAnnos ref={this._sidebarRef}