diff options
Diffstat (limited to 'src/client/views/nodes/MapBox/MapBox.tsx')
-rw-r--r-- | src/client/views/nodes/MapBox/MapBox.tsx | 59 |
1 files changed, 28 insertions, 31 deletions
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index c4bb7c47d..541b41bf7 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -4,14 +4,13 @@ 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, Position } from 'geojson'; -import mapboxgl, { LngLatBoundsLike, MapLayerMouseEvent } from 'mapbox-gl'; +import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString } from 'geojson'; +import { LngLatBoundsLike, LngLatLike, MapLayerMouseEvent } from 'mapbox-gl'; import { IReactionDisposer, ObservableMap, action, autorun, computed, makeObservable, observable, runInAction } from 'mobx'; 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 { MarkerEvent } from 'react-map-gl/dist/esm/types'; import { ClientUtils, setupMoveUpEvents } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc'; @@ -30,11 +29,12 @@ import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { FocusViewOptions } from '../FocusViewOptions'; import { fastSpeedIcon, mediumSpeedIcon, slowSpeedIcon } from './AnimationSpeedIcons'; -import { AnimationSpeed, AnimationStatus, AnimationUtility } from './AnimationUtility'; +import { AnimationSpeed, AnimationStatus, AnimationUtility, Position } from './AnimationUtility'; 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 +76,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { makeObservable(this); } - @observable _featuresFromGeocodeResults: any[] = []; + @observable _featuresFromGeocodeResults: { place_name: string; center: LngLatLike | undefined }[] = []; @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>(); @observable _selectedPinOrRoute: Doc | undefined = undefined; // The pin that is selected @observable _mapReady = false; @@ -100,7 +100,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { geometry: { type: 'LineString', coordinates: [] }, }; - @observable path: turf.helpers.Feature<turf.helpers.LineString, turf.helpers.Properties> = { + @observable path: Feature<LineString> = { + // turf.helpers.Feature<turf.helpers.LineString, turf.helpers.Properties> = { type: 'Feature', geometry: { type: 'LineString', coordinates: [] }, properties: {}, @@ -168,7 +169,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { autorun(() => { const animationUtil = this._animationUtility; const concattedCoordinates = geometry.coordinates.concat(originalCoordinates.slice(endIndex)); - const newFeature: Feature<LineString, turf.Properties> = { + const newFeature: Feature<LineString> = { type: 'Feature', properties: {}, geometry: { @@ -445,7 +446,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { /// this should use SELECTED pushpin for lat/long if there is a selection, otherwise CENTER const anchor = Docs.Create.ConfigDocument({ title: 'MapAnchor:' + this.Document.title, - text: (StrCast(this._selectedPinOrRoute?.map) || StrCast(this.Document.map) || 'map location') as any, + text: (StrCast(this._selectedPinOrRoute?.map) || StrCast(this.Document.map) || 'map location') as unknown as RichTextField, // strings are allowed for text config_latitude: NumCast((existingPin ?? this._selectedPinOrRoute)?.latitude ?? this.dataDoc.latitude), config_longitude: NumCast((existingPin ?? this._selectedPinOrRoute)?.longitude ?? this.dataDoc.longitude), config_map_zoom: NumCast(this.dataDoc.map_zoom), @@ -464,7 +465,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { return this.Document; }; - map_docToPinMap = new Map<Doc, any>(); + map_docToPinMap = new Map<Doc, unknown>(); map_pinHighlighted = new Map<Doc, boolean>(); /* @@ -541,15 +542,17 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * Creates Pushpin doc and adds it to the list of annotations */ @action - createPushpin = undoable((latitude: number, longitude: number, location?: string, wikiData?: string) => { + 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]; // Stores the pushpin as a MapMarkerDocument const pushpin = Docs.Create.PushpinDocument( - NumCast(latitude), - NumCast(longitude), + lat, + lon, false, [], { - title: location ?? `lat=${NumCast(latitude)},lng=${NumCast(longitude)}`, + title: location ?? `lat=${lat},lng=${lon}`, map: location, description: '', wikiData: wikiData, @@ -567,7 +570,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }, 'createpin'); @action - createMapRoute = undoable((coordinates: Position[], originName: string, destination: any, createPinForDestination: boolean) => { + createMapRoute = undoable((coordinates: Position[], originName: string, destination: { place_name: string; center: number[] }, createPinForDestination: boolean) => { if (originName !== destination.place_name) { const mapRoute = Docs.Create.MapRouteDocument(false, [], { title: `${originName} --> ${destination.place_name}`, routeCoordinates: JSON.stringify(coordinates) }); this.addDocument(mapRoute, this.annotationKey); @@ -586,23 +589,21 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }, 'createmaproute'); @action - searchbarKeyDown = (e: any) => { + searchbarKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && this._featuresFromGeocodeResults) { - const center = this._featuresFromGeocodeResults[0]?.center; + const center = this._featuresFromGeocodeResults[0]; this._featuresFromGeocodeResults = []; - setTimeout(() => center && this._mapRef.current?.flyTo({ center })); + setTimeout(() => center && this._mapRef.current?.flyTo(center)); } }; @action - addMarkerForFeature = (feature: any) => { + addMarkerForFeature = (feature: { place_name: string; center: LngLatLike | undefined; properties?: { wikiData: unknown } }) => { const location = feature.place_name; if (feature.center) { - const longitude = feature.center[0]; - const latitude = feature.center[1]; const wikiData = feature.properties?.wikiData; - this.createPushpin(latitude, longitude, location, wikiData); + this.createPushpin(feature.center, location, wikiData); if (this._mapRef.current) { this._mapRef.current.flyTo({ @@ -727,7 +728,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }; @action - handleMarkerClick = (e: MarkerEvent<mapboxgl.Marker, MouseEvent>, pinDoc: Doc) => { + handleMarkerClick = (clientX: number, clientY: number, pinDoc: Doc) => { this._featuresFromGeocodeResults = []; this.deselectPinOrRoute(); // TODO: check this method this._selectedPinOrRoute = pinDoc; @@ -758,7 +759,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // MapAnchorMenu.Instance.jumpTo(NumCast(pinDoc.longitude), NumCast(pinDoc.latitude)-3, true); - MapAnchorMenu.Instance.jumpTo(e.originalEvent.clientX, e.originalEvent.clientY, true); + MapAnchorMenu.Instance.jumpTo(clientX, clientY, true); document.addEventListener('pointerdown', this.tryHideMapAnchorMenu, true); @@ -768,7 +769,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }; @action - displayRoute = (routeInfoMap: Record<TransportationType, any> | undefined, type: TransportationType) => { + displayRoute = (routeInfoMap: Record<TransportationType, { coordinates: Position[] }> | undefined, type: TransportationType) => { if (routeInfoMap) { const newTempRouteSource: FeatureCollection = { type: 'FeatureCollection', @@ -1052,7 +1053,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { <div id="divider">|</div> <div style={{ display: 'flex', alignItems: 'center' }}> <div>Select Line Color: </div> - <CirclePicker circleSize={12} circleSpacing={5} width="100%" colors={['#ffff00', '#03a9f4', '#ff0000', '#ff5722', '#000000', '#673ab7']} onChange={(color: any) => this.setAnimationLineColor(color)} /> + <CirclePicker circleSize={12} circleSpacing={5} width="100%" colors={['#ffff00', '#03a9f4', '#ff0000', '#ff5722', '#000000', '#673ab7']} onChange={color => this.setAnimationLineColor(color)} /> </div> </div> </> @@ -1147,7 +1148,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { return MarkerIcons.getFontAwesomeIcon(markerType, '2x', markerColor) ?? null; }; - _textRef = React.createRef<any>(); render() { const scale = this._props.NativeDimScaling?.() || 1; const parscale = scale === 1 ? 1 : (this.ScreenToLocalBoxXf().Scale ?? 1); @@ -1161,7 +1161,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { style={{ transformOrigin: 'top left', 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' }}> - <TextField ref={this._textRef} fullWidth placeholder="Enter a location" onKeyDown={this.searchbarKeyDown} onChange={(e: any) => this.handleSearchChange(e.target.value)} /> + <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()} /> <div style={{ opacity: 0 }}> <IconButton icon={<FontAwesomeIcon icon={faGear as IconLookup} size="1x" />} type={Type.TERT} onClick={() => this.toggleSettings()} /> @@ -1217,7 +1217,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { .filter(feature => feature.place_name) .map((feature, idx) => ( <div - // eslint-disable-next-line react/no-array-index-key key={idx} className="search-result-container" onClick={() => { @@ -1321,8 +1320,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this._animationPhase === 0 && this.allPushpins // .filter(anno => !anno.layout_unrendered) .map((pushpin, idx) => ( - // eslint-disable-next-line react/no-array-index-key - <Marker key={idx} longitude={NumCast(pushpin.longitude)} latitude={NumCast(pushpin.latitude)} anchor="bottom" onClick={(e: MarkerEvent<mapboxgl.Marker, MouseEvent>) => this.handleMarkerClick(e, pushpin)}> + <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> ))} @@ -1336,7 +1334,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { <div className="mapBox-sidebar" style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}> <SidebarAnnos ref={this._sidebarRef} - // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} fieldKey={this.fieldKey} Document={this.Document} |