diff options
Diffstat (limited to 'src/client/views/nodes/MapBox/MapBox.tsx')
-rw-r--r-- | src/client/views/nodes/MapBox/MapBox.tsx | 235 |
1 files changed, 89 insertions, 146 deletions
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 792cb6b46..a279ccc48 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1,8 +1,8 @@ -import { IconLookup, faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons'; +import { IconButton, Size, Type } from '@dash/components'; +import { faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, FormControlLabel, TextField } from '@mui/material'; import * as turf from '@turf/turf'; -import { IconButton, Size, Type } from '@dash/components'; import * as d3 from 'd3'; import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString } from 'geojson'; import { LngLatBoundsLike, LngLatLike, MapLayerMouseEvent } from 'mapbox-gl'; @@ -10,11 +10,14 @@ import { IReactionDisposer, ObservableMap, action, autorun, computed, makeObserv import { observer } from 'mobx-react'; import * as React from 'react'; import { CirclePicker, ColorResult } from 'react-color'; -import { Layer, MapProvider, MapRef, Map as MapboxMap, Marker, Source, ViewState, ViewStateChangeEvent } from 'react-map-gl'; +import { Layer, MapProvider, MapRef, Map as MapboxMap, Marker, Source, ViewState, ViewStateChangeEvent } from 'react-map-gl/mapbox'; import { ClientUtils, setupMoveUpEvents } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; -import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc'; +import { Doc, DocListCast, Field, LinkedTo, StrListCast } from '../../../../fields/Doc'; +import { List } from '../../../../fields/List'; +import { RichTextField } from '../../../../fields/RichTextField'; import { DocCast, NumCast, StrCast, toList } from '../../../../fields/Types'; +import { TraceMobx } from '../../../../fields/util'; import { DocUtils } from '../../../documents/DocUtils'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; @@ -34,7 +37,6 @@ import { MapAnchorMenu } from './MapAnchorMenu'; import './MapBox.scss'; import { MapboxApiUtility, TransportationType } from './MapboxApiUtility'; import { MarkerIcons } from './MarkerIcons'; -import { RichTextField } from '../../../../fields/RichTextField'; // import { GeocoderControl } from './GeocoderControl'; // amongus @@ -76,7 +78,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { makeObservable(this); } - @observable _featuresFromGeocodeResults: { place_name: string; center: LngLatLike | undefined }[] = []; + @observable _featuresFromGeocodeResults: { place_name: string; center: LngLatLike | undefined; properties?: { wikiData: string } }[] = []; @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>(); @observable _selectedPinOrRoute: Doc | undefined = undefined; // The pin that is selected @observable _mapReady = false; @@ -109,12 +111,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // this list contains pushpins and configs @computed get allAnnotations() { return DocListCast(this.dataDoc[this.annotationKey]); } // prettier-ignore - @computed get allSidebarDocs() { return DocListCast(this.dataDoc[this.SidebarKey]); } // prettier-ignore + @computed get allSidebarDocs() { return DocListCast(this.dataDoc[this.sidebarKey]); } // prettier-ignore @computed get allPushpins() { return this.allAnnotations.filter(anno => anno.type === DocumentType.PUSHPIN); } // prettier-ignore @computed get allRoutes() { return this.allAnnotations.filter(anno => anno.type === DocumentType.MAPROUTE); } // prettier-ignore @computed get SidebarShown() { return !!this.layoutDoc._layout_showSidebar; } // prettier-ignore @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); } // prettier-ignore - @computed get SidebarKey() { return this.fieldKey + '_sidebar'; } // prettier-ignore + @computed get sidebarKey() { return this.fieldKey + '_sidebar'; } // prettier-ignore @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this._props.fieldKey + '_backgroundColor'], '#e4e4e4')); } @@ -123,7 +125,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const originalCoordinates: Position[] = JSON.parse(StrCast(this._routeToAnimate.routeCoordinates)); // const index = Math.floor(this.animationPhase * originalCoordinates.length); const index = this._animationPhase * (originalCoordinates.length - 1); // Calculate the fractional index - console.log('Animation phase', this._animationPhase); const startIndex = Math.floor(index); const endIndex = Math.ceil(index); let feature: Feature<Geometry, GeoJsonProperties>; @@ -183,7 +184,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }); return feature; } - console.log('ERROR'); return { type: 'Feature', properties: {}, @@ -199,7 +199,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @computed get allRoutesGeoJson(): FeatureCollection { const features: Feature<Geometry, GeoJsonProperties>[] = this.allRoutes.map((routeDoc: Doc) => { - console.log('Route coords: ', routeDoc.routeCoordinates); const geometry: LineString = { type: 'LineString', coordinates: JSON.parse(StrCast(routeDoc.routeCoordinates)), @@ -215,7 +214,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { return { type: 'FeatureCollection', - features: features, + features, }; } @@ -241,7 +240,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { toList(docs).forEach(doc => { let existingPin = this.allPushpins.find(pin => pin.latitude === doc.latitude && pin.longitude === doc.longitude) ?? this._selectedPinOrRoute; if (doc.latitude !== undefined && doc.longitude !== undefined && !existingPin) { - existingPin = this.createPushpin(NumCast(doc.latitude), NumCast(doc.longitude), StrCast(doc.map)); + existingPin = this.createPushpin({ lng: NumCast(doc.longitude), lat: NumCast(doc.latitude) }, StrCast(doc.map)); } if (existingPin) { setTimeout(() => { @@ -261,7 +260,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { removeMapDocument = (doc: Doc | Doc[], annotationKey?: string) => { this.allAnnotations - .filter(anno => toList(doc).includes(DocCast(anno.mapPin))) + .filter(anno => toList(doc).includes(DocCast(anno.mapPin)!)) .forEach(anno => { anno.mapPin = undefined; }); @@ -340,27 +339,19 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { startAnchorDrag = (e: PointerEvent, ele: HTMLElement) => { e.preventDefault(); e.stopPropagation(); - - const sourceAnchorCreator = action(() => { - const note = this.getAnchor(true); - if (note && this._selectedPinOrRoute) { - note.latitude = this._selectedPinOrRoute.latitude; - note.longitude = this._selectedPinOrRoute.longitude; - note.map = this._selectedPinOrRoute.map; - } - return note as Doc; - }); - const targetCreator = (annotationOn: Doc | undefined) => { const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, annotationOn, 'yellow'); + target.layout_fitWidth = true; DocumentView.SetSelectOnLoad(target); return target; }; + + const sourceAnchorCreator = () => this.getAnchor(true); const docView = this.DocumentView?.(); docView && DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(docView, sourceAnchorCreator, targetCreator), e.pageX, e.pageY, { dragComplete: dragEv => { - if (!dragEv.aborted && dragEv.annoDragData && dragEv.annoDragData.linkSourceDoc && dragEv.annoDragData.dropDocument && dragEv.linkDocument) { + if (!dragEv.aborted && dragEv.annoDragData?.linkSourceDoc && dragEv.annoDragData.dropDocument && dragEv.linkDocument) { dragEv.annoDragData.linkSourceDoc.followLinkToggle = dragEv.annoDragData.dropDocument.annotationOn === this.Document; dragEv.annoDragData.linkSourceDoc.followLinkZoom = false; } @@ -369,17 +360,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }; createNoteAnnotation = () => { - const createFunc = undoable( - action(() => { - const note = this._sidebarRef.current?.anchorMenuClick(this.getAnchor(true), ['latitude', 'longitude', LinkedTo]); - if (note && this._selectedPinOrRoute) { - note.latitude = this._selectedPinOrRoute.latitude; - note.longitude = this._selectedPinOrRoute.longitude; - note.map = this._selectedPinOrRoute.map; - } - }), - 'create note annotation' - ); + const createFunc = undoable(() => this._sidebarRef.current?.anchorMenuClick(this.getAnchor(true), ['latitude', 'longitude', LinkedTo]), 'create note annotation'); if (!this.layoutDoc.layout_showSidebar) { this.toggleSidebar(); setTimeout(createFunc); @@ -429,14 +410,11 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } }; - getView = (doc: Doc, options: FocusViewOptions) => { - if (this._sidebarRef?.current?.makeDocUnfiltered(doc) && !this.SidebarShown) { - this.toggleSidebar(); - options.didMove = true; + getView = async (doc: Doc, options: FocusViewOptions) => { + if (DocListCast(this.dataDoc[this.sidebarKey]).find(anno => Doc.AreProtosEqual(doc.layout_unrendered ? DocCast(doc.annotationOn) : doc, anno))) { + SidebarAnnos.getView(this._sidebarRef.current, this.SidebarShown, this.toggleSidebar, doc, options); } - return new Promise<Opt<DocumentView>>(res => { - DocumentView.addViewRenderedCb(doc, dv => res(dv)); - }); + return undefined; }; /* @@ -477,14 +455,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @action deleteSelectedPinOrRoute = undoable(() => { - console.log('deleting'); - if (this._selectedPinOrRoute) { + const selPin = DocCast(this._selectedPinOrRoute); + if (selPin) { // Removes filter - Doc.setDocFilter(this.Document, 'latitude', NumCast(this._selectedPinOrRoute.latitude), 'remove'); - Doc.setDocFilter(this.Document, 'longitude', NumCast(this._selectedPinOrRoute.longitude), 'remove'); - Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(DocCast(this._selectedPinOrRoute))}`, 'remove'); + Doc.setDocFilter(this.Document, 'latitude', NumCast(selPin.latitude), 'remove'); + Doc.setDocFilter(this.Document, 'longitude', NumCast(selPin.longitude), 'remove'); + Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(selPin)}`, 'remove'); - this.removePushpinOrRoute(this._selectedPinOrRoute); + this.removePushpinOrRoute(selPin); } MapAnchorMenu.Instance.fadeOut(true); document.removeEventListener('pointerdown', this.tryHideMapAnchorMenu, true); @@ -542,17 +520,16 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * Creates Pushpin doc and adds it to the list of annotations */ @action - createPushpin = undoable((center: LngLatLike, location?: string, wikiData?: string) => { - const lat = 'lat' in center ? center.lat : center[0]; - const lon = 'lng' in center ? center.lng : 'lon' in center ? center.lon : center[1]; + createPushpin = (center: LngLatLike, location?: string, wikiData?: string) => { + const [lng, lat] = center instanceof Array ? center : ['lng' in center ? center.lng : center.lon, center.lat]; // Stores the pushpin as a MapMarkerDocument const pushpin = Docs.Create.PushpinDocument( lat, - lon, + lng, false, [], { - title: location ?? `lat=${lat},lng=${lon}`, + title: location ?? `lat=${lat},lng=${lng}`, map: location, description: '', wikiData: wikiData, @@ -563,11 +540,10 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // ,'pushpinIDamongus'+ this.incrementer++ ); this.addDocument(pushpin, this.annotationKey); - console.log(pushpin); return pushpin; // mapMarker.infoWindowOpen = true; - }, 'createpin'); + }; @action createMapRoute = undoable((coordinates: Position[], originName: string, destination: { place_name: string; center: number[] }, createPinForDestination: boolean) => { @@ -575,7 +551,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const mapRoute = Docs.Create.MapRouteDocument(false, [], { title: `${originName} --> ${destination.place_name}`, routeCoordinates: JSON.stringify(coordinates) }); this.addDocument(mapRoute, this.annotationKey); if (createPinForDestination) { - this.createPushpin(destination.center[1], destination.center[0], destination.place_name); + this.createPushpin({ lng: destination.center[0], lat: destination.center[1] }, destination.place_name); } this._temporaryRouteSource = { type: 'FeatureCollection', @@ -598,18 +574,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }; @action - addMarkerForFeature = (feature: { place_name: string; center: LngLatLike | undefined; properties?: { wikiData: unknown } }) => { - const location = feature.place_name; + addMarkerForFeature = (feature: { place_name: string; center: LngLatLike | undefined; properties?: { wikiData: string } }) => { if (feature.center) { - const wikiData = feature.properties?.wikiData; - - this.createPushpin(feature.center, location, wikiData); - - if (this._mapRef.current) { - this._mapRef.current.flyTo({ - center: feature.center, - }); - } + this.createPushpin(feature.center, feature.place_name, feature.properties?.wikiData); + this._mapRef.current?.flyTo({ + center: feature.center, + }); this._featuresFromGeocodeResults = []; } else { // TODO: handle error @@ -632,7 +602,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // try { // const url = MAPBOX_FORWARD_GEOCODE_BASE_URL + encodeURI(searchText) +'.json' +`?access_token=${MAPBOX_ACCESS_TOKEN}`; // const response = await fetch(url); - // const data = await response.json(); + // const data = await response.jchildDocson(); // runInAction(() => { // this.featuresFromGeocodeResults = data.features; // }) @@ -653,7 +623,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { layers: ['map-routes-layer'], }); - console.error(features); + this.Document._childFilters = new List<string>(StrListCast(this.Document._childFilters).filter(filter => !filter.includes(LinkedTo))); if (features && features.length > 0 && features[0].properties && features[0].geometry) { const { routeTitle } = features[0].properties; const routeDoc: Doc | undefined = this.allRoutes.find(rtDoc => rtDoc.title === routeTitle); @@ -668,9 +638,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { MapAnchorMenu.Instance.Center = this.centerOnSelectedPin; MapAnchorMenu.Instance.OnClick = this.createNoteAnnotation; MapAnchorMenu.Instance.StartDrag = this.startAnchorDrag; - MapAnchorMenu.Instance.Reset(); - MapAnchorMenu.Instance.setRouteDoc(routeDoc); // TODO: Subject to change @@ -833,10 +801,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @computed get preAnimationViewState() { - if (!this._isAnimating) { - return this.mapboxMapViewState; - } - return undefined; + return !this._isAnimating ? this.mapboxMapViewState : undefined; } @action @@ -846,24 +811,15 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @action updateAnimationSpeed = () => { - let newAnimationSpeed: AnimationSpeed; + this._animationSpeed = (() => { switch (this._animationSpeed) { - case AnimationSpeed.SLOW: - newAnimationSpeed = AnimationSpeed.MEDIUM; - break; - case AnimationSpeed.MEDIUM: - newAnimationSpeed = AnimationSpeed.FAST; - break; - case AnimationSpeed.FAST: - newAnimationSpeed = AnimationSpeed.SLOW; - break; - default: - newAnimationSpeed = AnimationSpeed.MEDIUM; - break; - } - this._animationSpeed = newAnimationSpeed; + case AnimationSpeed.SLOW: return AnimationSpeed.MEDIUM; + case AnimationSpeed.MEDIUM: return AnimationSpeed.FAST; + case AnimationSpeed.FAST: return AnimationSpeed.SLOW; + default: return AnimationSpeed.MEDIUM; + }})(); // prettier-ignore if (this._animationUtility) { - this._animationUtility.updateAnimationSpeed(newAnimationSpeed); + this._animationUtility.updateAnimationSpeed(this._animationSpeed); } }; @computed get animationSpeedTooltipText(): string { @@ -890,19 +846,16 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this._animationUtility?.updateIsStreetViewAnimation(newVal); }; - getFeatureFromRouteDoc = (routeDoc: Doc): Feature<Geometry, GeoJsonProperties> => { - const geometry: LineString = { + getFeatureFromRouteDoc = (routeDoc: Doc): Feature<Geometry, GeoJsonProperties> => ({ + type: 'Feature', + properties: { + routeTitle: routeDoc.title, + }, + geometry: { type: 'LineString', coordinates: JSON.parse(StrCast(routeDoc.routeCoordinates)), - }; - return { - type: 'Feature', - properties: { - routeTitle: routeDoc.title, - }, - geometry: geometry, - }; - }; + }, + }); @action playAnimation = (status: AnimationStatus) => { @@ -936,7 +889,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const updateAnimationPhase = (newAnimationPhase: number) => this.setAnimationPhase(newAnimationPhase); if (status !== AnimationStatus.RESUME) { - const result = await animationUtil.flyInAndRotate({ + await animationUtil.flyInAndRotate({ map: this._mapRef.current!, // targetLngLat, // duration 3000 @@ -948,9 +901,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // endPitch: this.isStreetViewAnimation ? 80 : 50, updateFrameId, }); - - console.log('Bearing: ', result.bearing); - console.log('Altitude: ', result.altitude); } runInAction(() => { @@ -1028,7 +978,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this.playAnimation(AnimationStatus.START); // Play from the beginning } }} - icon={this._isAnimating && this._finishedFlyTo ? <FontAwesomeIcon icon={faPause as IconLookup} /> : <FontAwesomeIcon icon={faPlay as IconLookup} />} + icon={<FontAwesomeIcon icon={this._isAnimating && this._finishedFlyTo ? faPause : faPlay} />} color="black" size={Size.MEDIUM} /> @@ -1039,12 +989,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this.stopAnimation(false); this.playAnimation(AnimationStatus.START); }} - icon={<FontAwesomeIcon icon={faRotate as IconLookup} />} + icon={<FontAwesomeIcon icon={faRotate} />} color="black" size={Size.MEDIUM} /> )} - <IconButton style={{ marginRight: '10px' }} tooltip="Stop and close animation" onPointerDown={() => this.stopAnimation(true)} icon={<FontAwesomeIcon icon={faCircleXmark as IconLookup} />} color="black" size={Size.MEDIUM} /> + <IconButton style={{ marginRight: '10px' }} tooltip="Stop and close animation" onPointerDown={() => this.stopAnimation(true)} icon={<FontAwesomeIcon icon={faCircleXmark} />} color="black" size={Size.MEDIUM} /> <div className="animation-suboptions"> <div>|</div> <FormControlLabel className="first-person-label" label="1st person animation:" labelPlacement="start" control={<Checkbox color="success" checked={this._isStreetViewAnimation} onChange={this.toggleIsStreetViewAnimation} />} /> @@ -1085,7 +1035,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { onBearingChange = (e: React.ChangeEvent<HTMLInputElement>) => { const bearing = parseInt(e.target.value); if (!isNaN(bearing) && this._mapRef.current) { - console.log('bearing change'); const fixedBearing = Math.max(0, Math.min(360, bearing)); this._mapRef.current.setBearing(fixedBearing); this.dataDoc.map_bearing = fixedBearing; @@ -1096,7 +1045,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { onPitchChange = (e: React.ChangeEvent<HTMLInputElement>) => { const pitch = parseInt(e.target.value); if (!isNaN(pitch) && this._mapRef.current) { - console.log('pitch change'); const fixedPitch = Math.max(0, Math.min(85, pitch)); this._mapRef.current.setPitch(fixedPitch); this.dataDoc.map_pitch = fixedPitch; @@ -1141,16 +1089,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this._showTerrain = !this._showTerrain; }; - getMarkerIcon = (pinDoc: Doc): JSX.Element | null => { - const markerType = StrCast(pinDoc.markerType); - const markerColor = StrCast(pinDoc.markerColor); - - return MarkerIcons.getFontAwesomeIcon(markerType, '2x', markerColor) ?? null; - }; + getMarkerIcon = (pinDoc: Doc) => MarkerIcons.getFontAwesomeIcon(StrCast(pinDoc.markerType), '2x', StrCast(pinDoc.markerColor)) ?? null; render() { - const scale = this._props.NativeDimScaling?.() || 1; - const parscale = scale === 1 ? 1 : (this.ScreenToLocalBoxXf().Scale ?? 1); + TraceMobx(); + const scale = (this._props.NativeDimScaling?.() || 1) + 0.001; // bcz: weird, but without this hack, MapBox doesn't locate map correctly + const parscale = this.ScreenToLocalBoxXf().Scale; return ( <div className="mapBox" ref={this._ref}> @@ -1158,13 +1102,13 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { className="mapBox-wrapper" onWheel={e => e.stopPropagation()} onPointerDown={e => e.button === 0 && !e.ctrlKey && e.stopPropagation()} - style={{ transformOrigin: 'top left', transform: `scale(${scale})`, width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}> + style={{ transform: `scale(${scale})`, width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}> {!this._routeToAnimate && ( - <div className="mapBox-searchbar" style={{ width: `${100 / scale}%`, zIndex: 1, position: 'relative', background: 'lightGray' }}> + <div className="mapBox-searchbar" style={{ width: `${100 / scale}%` }}> <TextField fullWidth placeholder="Enter a location" onKeyDown={this.searchbarKeyDown} onChange={e => this.handleSearchChange(e.target.value)} /> - <IconButton icon={<FontAwesomeIcon icon={faGear as IconLookup} size="1x" />} type={Type.TERT} onClick={() => this.toggleSettings()} /> + <IconButton icon={<FontAwesomeIcon icon={faGear} size="1x" />} type={Type.TERT} onClick={this.toggleSettings} /> <div style={{ opacity: 0 }}> - <IconButton icon={<FontAwesomeIcon icon={faGear as IconLookup} size="1x" />} type={Type.TERT} onClick={() => this.toggleSettings()} /> + <IconButton icon={<FontAwesomeIcon icon={faGear} size="1x" />} type={Type.TERT} onClick={this.toggleSettings} /> </div> </div> )} @@ -1188,15 +1132,15 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { </div> <div className="mapbox-bearing-selection"> <div>Bearing: </div> - <input value={NumCast(this.mapboxMapViewState.bearing).toFixed(0)} type="number" onChange={this.onBearingChange} /> + <input value={this.mapboxMapViewState.bearing.toFixed(0)} type="number" onChange={this.onBearingChange} /> </div> <div className="mapbox-pitch-selection"> <div>Pitch: </div> - <input value={NumCast(this.mapboxMapViewState.pitch).toFixed(0)} type="number" onChange={this.onPitchChange} /> + <input value={this.mapboxMapViewState.pitch.toFixed(0)} type="number" onChange={this.onPitchChange} /> </div> <div className="mapbox-pitch-selection"> <div>Zoom: </div> - <input value={NumCast(this.mapboxMapViewState.zoom).toFixed(0)} type="number" onChange={this.onZoomChange} /> + <input value={this.mapboxMapViewState.zoom.toFixed(0)} type="number" onChange={this.onZoomChange} /> </div> <div className="mapbox-terrain-selection"> <div>Show terrain: </div> @@ -1230,17 +1174,18 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { )} <MapProvider> <MapboxMap + key={'' + this.Document.x + this.Document.y} // force map to rerender after dragging, otherwise it will display the wrong location until it gets re-rendered ref={this._mapRef} mapboxAccessToken={MAPBOX_ACCESS_TOKEN} - viewState={this._isAnimating || this._routeToAnimate ? undefined : { ...this.mapboxMapViewState, width: NumCast(this.layoutDoc._width), height: NumCast(this.layoutDoc._height) }} + viewState={this._isAnimating || this._routeToAnimate ? undefined : { ...this.mapboxMapViewState, width: this._props.PanelWidth(), height: this._props.PanelHeight() }} mapStyle={this.dataDoc.map_style ? StrCast(this.dataDoc.map_style) : 'mapbox://styles/mapbox/streets-v11'} style={{ position: 'absolute', top: 0, left: 0, zIndex: '0', - width: NumCast(this.layoutDoc._width) * parscale, - height: NumCast(this.layoutDoc._height) * parscale, + width: this._props.PanelWidth() * parscale, + height: this._props.PanelHeight() * parscale, }} initialViewState={this._isAnimating ? undefined : this.mapboxMapViewState} onZoom={this.onMapZoom} @@ -1315,19 +1260,18 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { /> </> )} - - {!this._isAnimating && - this._animationPhase === 0 && - this.allPushpins // .filter(anno => !anno.layout_unrendered) - .map((pushpin, idx) => ( - <Marker key={idx} longitude={NumCast(pushpin.longitude)} latitude={NumCast(pushpin.latitude)} anchor="bottom" onClick={e => this.handleMarkerClick(e.originalEvent.clientX, e.originalEvent.clientY, pushpin)}> - {this.getMarkerIcon(pushpin)} - </Marker> - ))} - - {/* {this.mapMarkers.length > 0 && this.mapMarkers.map((marker, idx) => ( - <Marker key={idx} longitude={marker.longitude} latitude={marker.latitude}/> - ))} */} + {this._isAnimating || this._animationPhase + ? null + : this.allPushpins.map(p => ( + <Marker + key={'' + p.longitude + p.latitude} + longitude={NumCast(p.longitude)} + latitude={NumCast(p.latitude)} + anchor="bottom" + onClick={e => this.handleMarkerClick(e.originalEvent.clientX, e.originalEvent.clientY, p)}> + {this.getMarkerIcon(p)} + </Marker> + ))} </MapboxMap> </MapProvider> </div> @@ -1335,8 +1279,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { <SidebarAnnos ref={this._sidebarRef} {...this._props} - fieldKey={this.fieldKey} - Document={this.Document} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} usePanelWidth |