aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/DocumentTypes.ts2
-rw-r--r--src/client/documents/Documents.ts22
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx2
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx264
-rw-r--r--src/client/views/nodes/MapBox/MapBox2.tsx4
-rw-r--r--src/client/views/nodes/MapBox/MapMarkerBox.tsx0
-rw-r--r--src/client/views/nodes/MapBox/MapPushpinBox.tsx38
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx19
-rw-r--r--src/fields/Doc.ts7
9 files changed, 235 insertions, 123 deletions
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 2da3a24fd..2cfd9e680 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -27,6 +27,7 @@ export enum DocumentType {
MAP = 'map',
DATAVIZ = 'dataviz',
LOADING = 'loading',
+
// special purpose wrappers that either take no data or are compositions of lower level types
LINK = 'link',
@@ -40,6 +41,7 @@ export enum DocumentType {
SEARCHITEM = 'searchitem',
COMPARISON = 'comparison',
GROUP = 'group',
+ PUSHPIN = "pushpin",
LINKDB = 'linkdb', // database of links ??? why do we have this
SCRIPTDB = 'scriptdb', // database of scripts
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 849a5d6ae..5cced6d24 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -48,6 +48,7 @@ import { LinkBox } from '../views/nodes/LinkBox';
import { LinkDescriptionPopup } from '../views/nodes/LinkDescriptionPopup';
import { LoadingBox } from '../views/nodes/LoadingBox';
import { MapBox } from '../views/nodes/MapBox/MapBox';
+import { MapPushpinBox } from '../views/nodes/MapBox/MapPushpinBox';
import { PDFBox } from '../views/nodes/PDFBox';
import { RecordingBox } from '../views/nodes/RecordingBox/RecordingBox';
import { ScreenshotBox } from '../views/nodes/ScreenshotBox';
@@ -218,8 +219,8 @@ export class DocumentOptions {
dragFactory_count?: NUMt = new NumInfo('number of items created from a drag button (used for setting title with incrementing index)', true);
openFactoryLocation?: string; // an OpenWhere value to place the factory created document
openFactoryAsDelegate?: boolean; //
- lat?: number;
- lng?: number;
+ lat?: NUMt = new NumInfo('latitude of a mapping view');
+ lng?: NUMt = new NumInfo('longitude of a mapping view');
infoWindowOpen?: boolean;
author?: string;
_layout_fieldKey?: string;
@@ -286,6 +287,8 @@ export class DocumentOptions {
viewTransitionTime?: number; // transition duration for view parameters
presPanX?: number; // panX saved as a view spec
presPanY?: number; // panY saved as a view spec
+ presLat?: NUMt = new NumInfo('latitude of a map'); // latitude of a map
+ presLong?: NUMt = new NumInfo('longitude of map'); // longitude of map
presViewScale?: number; // viewScale saved as a view Spec
presTransition?: number; //the time taken for the transition TO a document
presDuration?: number; //the duration of the slide in presentation view
@@ -683,6 +686,13 @@ export namespace Docs {
options: { _layout_fitWidth: true, _fitHeight: true, nativeDimModifiable: true },
},
],
+ [
+ DocumentType.PUSHPIN,
+ {
+ layout: { view: MapPushpinBox, dataField: defaultDataKey },
+ options: {},
+ },
+ ],
]);
const suffix = 'Proto';
@@ -1028,8 +1038,8 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.MAP), new List(documents), options);
}
- export function MapMarkerDocument(lat: number, lng: number, infoWindowOpen: boolean, documents: Array<Doc>, options: DocumentOptions, id?: string) {
- return InstanceFromProto(Prototypes.get(DocumentType.MARKER), new List(documents), { lat, lng, infoWindowOpen, ...options }, id);
+ export function PushpinDocument(lat: number, lng: number, infoWindowOpen: boolean, documents: Array<Doc>, options: DocumentOptions, id?: string) {
+ return InstanceFromProto(Prototypes.get(DocumentType.PUSHPIN), new List(documents), { lat, lng, infoWindowOpen, ...options }, id);
}
// shouldn't ever need to create a KVP document-- instead set the LayoutTemplateString to be a KeyValueBox for the DocumentView (see addDocTab in TabDocView)
@@ -1058,6 +1068,10 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.MARKER), options?.data, options, id);
}
+ export function MapanchorDocument(options: DocumentOptions = {}, id?: string) {
+ return InstanceFromProto(Prototypes.get(DocumentType.MARKER), options?.data, options, id);
+ }
+
export function InkAnchorDocument(options: DocumentOptions, id?: string) {
return InstanceFromProto(Prototypes.get(DocumentType.MARKER), options?.data, options, id);
}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 348ef910a..9546a6d38 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -44,6 +44,7 @@ import { VideoBox } from './VideoBox';
import { WebBox } from './WebBox';
import React = require('react');
import XRegExp = require('xregexp');
+import { MapPushpinBox } from './MapBox/MapPushpinBox';
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
@@ -266,6 +267,7 @@ export class DocumentContentsView extends React.Component<
ComparisonBox,
LoadingBox,
SchemaRowBox,
+ MapPushpinBox,
}}
bindings={bindings}
jsx={layoutFrame}
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 7d3dcb811..f1f6b0756 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -4,17 +4,19 @@ import BingMapsReact from 'bingmaps-react';
import { EditableText } from 'browndash-components';
import e from 'connect-flash';
import { truncateSync } from 'fs';
-import { action, computed, IReactionDisposer, observable, ObservableMap, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Opt, WidthSym } from '../../../../fields/Doc';
import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
+import { ScriptField } from '../../../../fields/ScriptField';
import { NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils';
+import { emptyFunction, returnAll, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils';
import { Docs } from '../../../documents/Documents';
import { DragManager } from '../../../util/DragManager';
import { SnappingManager } from '../../../util/SnappingManager';
+import { Transform } from '../../../util/Transform';
import { UndoManager } from '../../../util/UndoManager';
import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent';
@@ -23,8 +25,9 @@ import { MarqueeAnnotator } from '../../MarqueeAnnotator';
import { AnchorMenu } from '../../pdf/AnchorMenu';
import { Annotation } from '../../pdf/Annotation';
import { SidebarAnnos } from '../../SidebarAnnos';
+import { DocumentView } from '../DocumentView';
import { FieldView, FieldViewProps } from '../FieldView';
-import { PinProps } from '../trails';
+import { PinProps, PresBox } from '../trails';
import './MapBox.scss';
import { MapBoxInfoWindow } from './MapBoxInfoWindow';
// amongus
@@ -126,11 +129,23 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
static _hadSelection: boolean = false;
private _sidebarRef = React.createRef<SidebarAnnos>();
private _ref: React.RefObject<HTMLDivElement> = React.createRef();
-
+ private _disposer: {[key:string]:IReactionDisposer} = {}
componentDidMount() {
this.props.setContentView?.(this);
+ this._disposer.location = reaction(() => ({lat:this.rootDoc.latitude, lng:this.rootDoc.longitude}),
+ (locationObject) => {
+
+ //TODO: SAVE ZOOM? VIEW STYLE?
+ this._bingMap.current.setView({
+ center: new this.MicrosoftMaps.Location(locationObject.lat, locationObject.lng),
+ });
+
+ }, {fireImmediately: true});
}
+ componentWillUnmount(): void {
+ Object.keys(this._disposer).forEach(key => this._disposer[key]?.())
+ }
// iterate allMarkers to size, center, and zoom map to contain all markers
private fitBounds = (map: google.maps.Map) => {
const curBounds = map.getBounds() ?? new window.google.maps.LatLngBounds();
@@ -240,7 +255,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
map: map,
});
map.panTo(position);
- const mapMarker = Docs.Create.MapMarkerDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {});
+ const mapMarker = Docs.Create.PushpinDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {});
this.addDocument(mapMarker, this.annotationKey);
};
@@ -368,7 +383,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (existingMarker) {
Doc.AddDocToList(existingMarker, 'data', doc);
} else {
- const marker = Docs.Create.MapMarkerDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {});
+ const marker = Docs.Create.PushpinDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {});
this.addDocument(marker, this.annotationKey);
}
}
@@ -512,7 +527,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
}
- getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.rootDoc;
+ // Old get anchor function
+ // getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.rootDoc;
/**
* render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker
@@ -592,57 +608,78 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
entityType: 'PopulatedPlace',
};
- @action
- updateView = () => {
- this._bingMap.current.setView({
- center: new this.MicrosoftMaps.Location(this.dataDoc.latitude, this.dataDoc.longitude),
- // zoom: location
- });
- };
+
+ /*
+ * Creates Pushpin doc and adds it to the list of annotations
+ */
@action
createPushpin = (latitude: number, longitude: number) => {
// Stores the pushpin as a MapMarkerDocument
- const mapMarker = Docs.Create.MapMarkerDocument(NumCast(latitude), NumCast(longitude), false, [], {});
+ const mapMarker = Docs.Create.PushpinDocument(NumCast(latitude), NumCast(longitude), false, [], {});
this.addDocument(mapMarker, this.annotationKey);
- mapMarker.infoWindowOpen = true;
- };
+ // mapMarker.infoWindowOpen = true;
+ };
- selectedPin: Doc | undefined;
- infobox: any;
+ /*
+ * Pushpin onclick
+ */
pushpinClicked = (pin:Doc) => {
- pin["infoWindowOpen"] =
- // true
- !pin.infoWindowOpen;
- // if (this.selectedPin){
- // this.selectedPin.infoWindowOpen = false;
- // this.selectedPin = pin
- // }
- // else{
- // this.selectedPin = pin
- // }
- this.addAllPins();
+ pin.infoWindowOpen = !pin.infoWindowOpen;
+
+ // @action
+ // onPointerDown = (e: React.PointerEvent) => {
+ // if (e.button === 2 || e.ctrlKey) {
+ // AnchorMenu.Instance.Status = 'annotation';
+ // AnchorMenu.Instance.Delete = this.deleteAnnotation.bind(this);
+ // AnchorMenu.Instance.Pinned = false;
+ // AnchorMenu.Instance.PinToPres = this.pinToPres;
+ // AnchorMenu.Instance.MakeTargetToggle = this.makeTargretToggle;
+ // AnchorMenu.Instance.IsTargetToggler = this.isTargetToggler;
+ // AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(this.annoTextRegion);
+ // AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
+ // e.stopPropagation();
+ // } else if (e.button === 0) {
+ // e.stopPropagation();
+ // LinkFollower.FollowLink(undefined, this.annoTextRegion, false);
+ // }
+ // };
+
+ // TODO: UPDATE FOR DASHDOC SELECTION
};
/**
- * Returns a list of MapMarkerDocument
+ * Returns a list of Pushpin docs
*/
@computed get allMapPushpins() {
return DocListCast(this.dataDoc[this.annotationKey]);
}
+
/**
- * Map OnClick create pushpin
+ * Map OnClick ~> creates a pushpin
*/
@action
mapOnClick = (e: { location: { latitude: any; longitude: any } }) => {
if (this.placePinOn) {
this.createPushpin(e.location.latitude, e.location.longitude);
- this.addAllPins();
+ // this.addAllPins();
this.placePinOn = false;
}
};
+
+
+
+ /*
+ * Updates values of layout doc to match the current map
+ */
+ @action
+ updateLayout = () => {
+ this.dataDoc.latitude = this._bingMap.current.getCenter().latitude;
+ this.dataDoc.longitude = this._bingMap.current.getCenter().longitude;
+ };
+
searched_pin: any;
/*
* For Bing Maps
@@ -651,20 +688,20 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
**/
@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();
+ // Centers on the searched location
+ this._bingMap.current.setView({
+ center: new this.MicrosoftMaps.Location(this.dataDoc.latitude, this.dataDoc.longitude),
+ });
+ this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'click', this.mapOnClick);
+ this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'viewchangeend', this.updateLayout);
+
+
// 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) {
@@ -672,82 +709,65 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
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
+ * Adds all pushpins in dataDoc onto the map (render) - OLD & UNUSED
*/
@action
addAllPins = () => {
this._bingMap.current.entities.clear();
if (this.searched_pin) this._bingMap.current.entities.push(this.searched_pin);
-
- this.allMapPushpins.map(pin => this.createPushPin(pin));
-
-
+ // this.allMapPushpins.map(pin => this.addPushpin(pin));
};
- @action
- createPushPin = (pin: any) => {
- var pushPin:any;
- if (pin.infoWindowOpen){
- pushPin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {
- // title: this.bingSearchBarContents,
- // subTitle: 'subtitle here',
- // text: '1',
- // height: '50px'
+ /*
+ * Returns doc w/ relevant info
+ */
+ getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
+ const anchor =
+ Docs.Create.MapanchorDocument({
+ title: 'MapAnchor:' + this.rootDoc.title,
+ presLat: NumCast(this.dataDoc.latitude),
+ presLong: NumCast(this.dataDoc.longitude),
+ // presTransition: 1000,
+ unrendered: true,
+ annotationOn: this.rootDoc,
});
+ if (anchor) {
+ if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
+ /* addAsAnnotation &&*/ this.addDocument(anchor);
+ PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), map: true } }, this.rootDoc);
+ return anchor;
}
- else{
- pushPin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {icon: 'http://icons.iconarchive.com/icons/icons-land/vista-map-markers/24/Map-Marker-Marker-Outside-Chartreuse-icon.png'});
- }
-
- 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);
- }
+ return this.rootDoc;
+ };
- //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;
+ /*
+ * Input: pin doc
+ * Adds MicrosoftMaps Pushpin to the map (render)
+ */
+ @action
+ addPushpin = (pin: Doc) => {
+ const pushPin = pin.infoWindowOpen ? new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {}): new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {icon: 'http://icons.iconarchive.com/icons/icons-land/vista-map-markers/24/Map-Marker-Marker-Outside-Chartreuse-icon.png'});
- //Add a click event handler to the pushpin.
- // For bing maps infobox
- // this.MicrosoftMaps.Events.addHandler(pushPin, 'click', this.pushpinClicked);
+
+ this._bingMap.current.entities.push(pushPin);
// For our infowindow
this.MicrosoftMaps.Events.addHandler(pushPin, 'click', (e: any) => this.pushpinClicked(pin));
- // this.MicrosoftMaps.Events.addHandler(pushPin, 'mouseover', (e:any) => this.onHover(e));
- };
+ }
+
+ /*
+ * Input: pin doc
+ * Adds MicrosoftMaps Pushpin to the map (render)
+ */
+ @action
+ removePushpin = (pin:any)=>{
+ this._bingMap.current.entities.clear();
+ this.allMapPushpins
+ this.allMapPushpins.map(pin => this.addPushpin(pin));
+ }
/**
* View options for bing maps
@@ -809,25 +829,37 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
{this.placePinOn ? <input type="button" value="Place Pin Mode On" onClick={this.togglePlacePin} /> : <input type="button" value="Place Pin Mode Off" onClick={this.togglePlacePin} />}
<BingMapsReact onMapReady={this.bingMapReady} bingMapsKey={bingApiKey} height="100%" mapOptions={this.bingMapOptions} width="100%" viewOptions={this.bingViewOptions}>
+ </BingMapsReact>
+ <div>
{this.allMapPushpins
- .filter(marker => marker.infoWindowOpen)
- .map(marker => (
- // console.log('this is a marker window')
- <MapBoxInfoWindow
- key={marker[Id]}
+ .map(pushpin => (
+ <DocumentView
{...this.props}
- setContentView={emptyFunction}
- place={marker}
- markerMap={this.markerMap}
- PanelWidth={this.infoWidth}
- PanelHeight={this.infoHeight}
- moveDocument={this.moveDocument}
- isAnyChildContentActive={this.isAnyChildContentActive}
- whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- />
+
+ // HOW DO I PASS IN pushpin???
+ // HOW DO I MAKE SURE IT KNOWS TO MAKE MapPushpinBox???
+ Document={pushpin}
+ DataDoc={undefined}
+ PanelWidth={returnOne}
+ PanelHeight={returnOne}
+ NativeWidth={returnOne}
+ NativeHeight={returnOne}
+ onClick={()=>new ScriptField(undefined)}
+ onKey={undefined}
+ onDoubleClick={undefined}
+ onBrowseClick={undefined}
+ docFilters={returnEmptyDoclist}
+ docRangeFilters={returnEmptyDoclist}
+ searchFilterDocs={returnEmptyDoclist}
+ isDocumentActive={returnFalse}
+ isContentActive={returnFalse}
+ addDocTab={returnFalse}
+ ScreenToLocalTransform={()=>new Transform(0,0,0)}
+ fitContentsToBox={undefined}
+ focus={returnOne}
+ />
))}
- </BingMapsReact>
-
+ </div>
{/* <MapBoxInfoWindow
key={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})[Id]}
{...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit}
diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx
index 9354f9639..f75b3a6a6 100644
--- a/src/client/views/nodes/MapBox/MapBox2.tsx
+++ b/src/client/views/nodes/MapBox/MapBox2.tsx
@@ -228,7 +228,7 @@ export class MapBox2 extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
map: map,
});
map.panTo(position);
- const mapMarker = Docs.Create.MapMarkerDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {});
+ const mapMarker = Docs.Create.PushpinDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {});
this.addDocument(mapMarker, this.annotationKey);
};
@@ -332,7 +332,7 @@ export class MapBox2 extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (existingMarker) {
Doc.AddDocToList(existingMarker, 'data', doc);
} else {
- const marker = Docs.Create.MapMarkerDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {});
+ const marker = Docs.Create.PushpinDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {});
this.addDocument(marker, this.annotationKey);
}
}
diff --git a/src/client/views/nodes/MapBox/MapMarkerBox.tsx b/src/client/views/nodes/MapBox/MapMarkerBox.tsx
deleted file mode 100644
index e69de29bb..000000000
--- a/src/client/views/nodes/MapBox/MapMarkerBox.tsx
+++ /dev/null
diff --git a/src/client/views/nodes/MapBox/MapPushpinBox.tsx b/src/client/views/nodes/MapBox/MapPushpinBox.tsx
new file mode 100644
index 000000000..13fb11054
--- /dev/null
+++ b/src/client/views/nodes/MapBox/MapPushpinBox.tsx
@@ -0,0 +1,38 @@
+import { observer } from 'mobx-react';
+// import { SettingsManager } from '../../../util/SettingsManager';
+import { ViewBoxBaseComponent } from '../../DocComponent';
+import { FieldView, FieldViewProps } from '../FieldView';
+import React = require('react');
+import { computed } from 'mobx';
+import { MapBox } from './MapBox';
+
+
+/**
+ * Map Pushpin doc class
+ */
+@observer
+export class MapPushpinBox extends ViewBoxBaseComponent<FieldViewProps>() {
+
+
+ public static LayoutString(fieldKey: string) {
+ return FieldView.LayoutString(MapPushpinBox, fieldKey);
+ }
+ componentDidMount() {
+ this.mapBoxView.addPushpin(this.rootDoc);
+ }
+ componentWillUnmount() {
+ this.mapBoxView.removePushpin(this.rootDoc);
+ }
+
+
+ @computed get mapBoxView() {
+ return this.props.DocumentView?.()?.props.docViewPath().lastElement()?.ComponentView as MapBox;
+ }
+ @computed get mapBox() {
+ return this.props.DocumentView?.().props.docViewPath().lastElement()?.rootDoc;
+ }
+
+ render() {
+ return (<div></div>);
+ }
+}
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 858d83b7a..d1cfb86ae 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -41,6 +41,7 @@ export interface pinDataTypes {
scrollable?: boolean;
dataviz?: number[];
pannable?: boolean;
+ map?:boolean;
viewType?: boolean;
inkable?: boolean;
filters?: boolean;
@@ -378,6 +379,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const inkable = [DocumentType.INK].includes(targetType);
const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetType) || target?._viewType === CollectionViewType.Stacking;
const pannable = [DocumentType.IMG, DocumentType.PDF].includes(targetType) || (targetType === DocumentType.COL && target?._viewType === CollectionViewType.Freeform);
+ const map = [DocumentType.MAP].includes(targetType);
const temporal = [DocumentType.AUDIO, DocumentType.VID].includes(targetType);
const clippable = [DocumentType.COMPARISON].includes(targetType);
const datarange = [DocumentType.FUNCPLOT].includes(targetType);
@@ -387,7 +389,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const filters = true;
const pivot = true;
const dataannos = false;
- return { scrollable, pannable, inkable, viewType, pivot, filters, temporal, clippable, dataview, datarange, poslayoutview, dataannos };
+ return { scrollable, pannable, inkable, viewType, pivot, map, filters, temporal, clippable, dataview, datarange, poslayoutview, dataannos };
}
@action
@@ -455,6 +457,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
changed = true;
}
}
+ if (pinDataTypes?.map || (!pinDataTypes && activeItem.presLat !== undefined)) {
+ if (bestTarget.latitude !== activeItem.presLat) {
+ Doc.SetInPlace(bestTarget, "latitude", NumCast(activeItem.presLat), true);
+ changed = true;
+ }
+ if (bestTarget.longitude !== activeItem.presLong) {
+ Doc.SetInPlace(bestTarget, "longitude", NumCast(activeItem.presLong), true);
+ bestTarget.restoreTargetOn = true;
+ changed = true;
+ }
+ }
if (pinDataTypes?.temporal || (!pinDataTypes && activeItem.presStartTime !== undefined)) {
if (bestTarget._layout_currentTimecode !== activeItem.presStartTime) {
bestTarget._layout_currentTimecode = activeItem.presStartTime;
@@ -633,6 +646,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
pinDoc.presXRange = undefined; //targetDoc?.xrange;
pinDoc.presYRange = undefined; //targetDoc?.yrange;
}
+ if (pinProps.pinData.map) {
+ pinDoc.presLat = targetDoc?.lat;
+ //...
+ }
if (pinProps.pinData.poslayoutview)
pinDoc.presPinLayoutData = new List<string>(
DocListCast(targetDoc[fkey] as ObjectField).map(d =>
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index deda4c876..0cf4256d6 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -522,6 +522,13 @@ export namespace Doc {
export function IsDelegateField(doc: Doc, fieldKey: string) {
return doc && Get(doc, fieldKey, true) !== undefined;
}
+ //
+ // this will write the value to the key on either the data doc or the embedding doc. The choice
+ // of where to write it is based on:
+ // 1) if the embedding Doc already has this field defined on it, then it will be written to the embedding
+ // 2) if the data doc has the field, then it's written there.
+ // 3) if neither already has the field, then 'defaultProto' determines whether to write it to the data doc (or the embedding)
+ //
export async function SetInPlace(doc: Doc, key: string, value: Field | undefined, defaultProto: boolean) {
if (key.startsWith('_')) key = key.substring(1);
const hasProto = Doc.GetProto(doc) !== doc ? Doc.GetProto(doc) : undefined;