aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzaultavangar <zaul_tavangar@brown.edu>2023-12-11 20:37:52 -0500
committerzaultavangar <zaul_tavangar@brown.edu>2023-12-11 20:37:52 -0500
commitbc23855777633dfd1caf7237b75c1e8fee88dff4 (patch)
treecca84763f3d8269222b67fb637127e9ba2cb2d50 /src
parente4eac6e4256dc320f6c767ecbad54b83459c4331 (diff)
new updates to map feature
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts25
-rw-r--r--src/client/views/nodes/MapBox/MapAnchorMenu.scss20
-rw-r--r--src/client/views/nodes/MapBox/MapAnchorMenu.tsx76
-rw-r--r--src/client/views/nodes/MapBox/MapBox.scss40
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx288
-rw-r--r--src/client/views/nodes/MapBox/MapboxApiUtility.ts2
-rw-r--r--src/client/views/nodes/MapBox/MarkerIcons.tsx87
-rw-r--r--src/client/views/nodes/MapBox/icon_images/mapbox-marker-icon-20px-blue.pngbin0 -> 1623 bytes
-rw-r--r--src/fields/Doc.ts2
9 files changed, 438 insertions, 102 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 02794c432..3db9f4f06 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -176,12 +176,14 @@ export class DocumentOptions {
_dimUnit?: DIMt = new DimInfo("units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units");
latitude?: NUMt = new NumInfo('latitude coordinate for map views', false);
longitude?: NUMt = new NumInfo('longitude coordinate for map views', false);
- routeCoordinates?: LISTt = new ListInfo("stores a route's/direction's coordinates"); // for a route document, this stores the route's coordiantes
+ routeCoordinates?: STRt = new StrInfo("stores a route's/direction's coordinates (stringified version)"); // for a route document, this stores the route's coordiantes
+ markerType?: STRt = new StrInfo('Defines the marker type for a pushpin document');
+ markerColor?: STRt= new StrInfo('Defines the marker color for a pushpin document');
map?: STRt = new StrInfo('text location of map');
map_type?: STRt = new StrInfo('type of map view', false);
map_zoom?: NUMt = new NumInfo('zoom of a map view', false);
wikiData?: STRt = new StrInfo('WikiData ID related to map location');
- description?: STRt = new StrInfo('A description of the document')
+ description?: STRt = new StrInfo('A description of the document');
_timecodeToShow?: NUMt = new NumInfo('the time that a document should be displayed (e.g., when an annotation shows up as a video plays)', false);
_timecodeToHide?: NUMt = new NumInfo('the time that a document should be hidden', false);
_width?: NUMt = new NumInfo('displayed width of a document');
@@ -783,6 +785,13 @@ export namespace Docs {
options: {},
},
],
+ [
+ DocumentType.MAPROUTE,
+ {
+ layout: { view: CollectionView, dataField: defaultDataKey },
+ options: {},
+ },
+ ],
]);
const suffix = 'Proto';
@@ -1139,16 +1148,12 @@ export namespace Docs {
documents: Array<Doc>,
options: DocumentOptions,
id?: string) {
+
return InstanceFromProto(Prototypes.get(DocumentType.PUSHPIN), new List(documents), { latitude, longitude, infoWindowOpen, ...options }, id);
}
- export function MapRouteDocument(
- infoWindowOpen: boolean,
- documents: Array<Doc>,
- options: DocumentOptions,
- id?: string
- ) {
- return InstanceFromProto(Prototypes.get(DocumentType.MAPROUTE), new List(documents), {infoWindowOpen, ...options}, id)
+ export function MapRouteDocument(infoWindowOpen: boolean, documents: Array<Doc>, options: DocumentOptions, id?: string) {
+ return InstanceFromProto(Prototypes.get(DocumentType.MAPROUTE), new List(documents), { 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)
@@ -2015,4 +2020,4 @@ ScriptingGlobals.add(function generateLinkTitle(link: Doc) {
const link_anchor_2title = link.link_anchor_2 && link.link_anchor_2 !== link ? Cast(link.link_anchor_2, Doc, null)?.title : '<?>';
const relation = link.link_relationship || 'to';
return `${link_anchor_1title} (${relation}) ${link_anchor_2title}`;
-});
+}); \ No newline at end of file
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.scss b/src/client/views/nodes/MapBox/MapAnchorMenu.scss
index e2fcd78fc..c36d98afe 100644
--- a/src/client/views/nodes/MapBox/MapAnchorMenu.scss
+++ b/src/client/views/nodes/MapBox/MapAnchorMenu.scss
@@ -103,6 +103,26 @@
}
+ .customized-marker-container{
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+ .current-marker-container{
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ }
+
+ .all-markers-container{
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ flex-wrap: wrap;
+ max-width: 400px;
+ }
+ }
+
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
index fca3998c8..2c2879900 100644
--- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
@@ -32,6 +32,9 @@ import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/materi
import { MapboxApiUtility, TransportationType } from './MapboxApiUtility';
import { MapBox } from './MapBox';
import { List } from '../../../../fields/List';
+import { MapboxColor, MarkerIcons } from './MarkerIcons';
+import { CirclePicker } from 'react-color';
+import { Position } from 'geojson';
type MapAnchorMenuType = 'standard' | 'route' | 'calendar' | 'customize';
@@ -58,9 +61,13 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
public DisplayRoute: (routeInfoMap: Record<TransportationType, any> | undefined, type: TransportationType) => void = unimplementedFunction;
public HideRoute: () => void = unimplementedFunction;
- public AddNewRouteToMap: (coordinates: List<any>, origin: string, destination: string) => void = unimplementedFunction;
+ public AddNewRouteToMap: (coordinates: Position[], origin: string, destination: string) => void = unimplementedFunction;
public CreatePin: (feature: any) => void = unimplementedFunction;
+ public UpdateMarkerColor: (color: string) => void = unimplementedFunction;
+ public UpdateMarkerIcon: (iconKey: string) => void = unimplementedFunction;
+
+
private allMapPinDocs: Doc[] = [];
@@ -151,11 +158,13 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
@action
CustomizeClick = () => {
+ this.currentRouteInfoMap = undefined;
this.menuType = 'customize';
}
@action
BackClick = () => {
+ this.currentRouteInfoMap = undefined;
this.menuType = 'standard';
}
@@ -238,11 +247,26 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
HandleAddRouteClick = () => {
if (this.currentRouteInfoMap && this.selectedTransportationType && this.selectedDestinationFeature){
const coordinates = this.currentRouteInfoMap[this.selectedTransportationType].coordinates;
- this.AddNewRouteToMap(this.currentRouteInfoMap![this.selectedTransportationType].coordinates, this.title ?? "", this.selectedDestinationFeature.place_name);
+ console.log(coordinates);
+ this.AddNewRouteToMap(coordinates, this.title ?? "", this.selectedDestinationFeature.place_name);
this.HideRoute();
}
}
+ getMarkerIcon = (): JSX.Element | undefined => {
+ if (this.pinDoc){
+ const markerType = StrCast(this.pinDoc.markerType);
+ const markerColor = StrCast(this.pinDoc.markerColor);
+
+ if (markerType.startsWith("MAPBOX")){
+ return MarkerIcons.getMapboxIcon(markerColor as MapboxColor);
+ } else { // font awesome icon
+ return MarkerIcons.getFontAwesomeIcon(markerType, markerColor);
+ }
+ }
+ return undefined;
+ }
+
render() {
const buttons = (
@@ -326,19 +350,6 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
color={SettingsManager.userColor}
/>
<IconButton
- tooltip="Upload image" //
- onPointerDown={this.TriggerFileInputClick}
- icon={<FontAwesomeIcon icon={faUpload as IconLookup} />}
- color={SettingsManager.userColor}
- />
- <input
- type="file"
- accept="image/*" // Optionally, specify accepted file types
- ref={this._fileInputRef}
- style={{ display: "none" }}
- onChange={() => {}}
- />
- <IconButton
tooltip="Revert to original" //
onPointerDown={this.BackClick}
icon={<FontAwesomeIcon icon={faArrowsRotate as IconLookup} />}
@@ -469,6 +480,41 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
}
+ {this.menuType === 'customize' &&
+ <div className='customized-marker-container'>
+ <div className='current-marker-container'>
+ <div>Current Marker: </div>
+ <div>
+ {this.getMarkerIcon()}
+ </div>
+ </div>
+ <div className='color-picker-container' style={{marginBottom: '10px'}}>
+ <CirclePicker
+ circleSize={15}
+ circleSpacing={7}
+ width='100%'
+ onChange={(color) => console.log(color.hex)}
+ />
+ </div>
+ <div className='all-markers-container'>
+ {Object.keys(MarkerIcons.FAMarkerIconsMap).map((iconKey) => {
+ const icon = MarkerIcons.getFontAwesomeIcon(iconKey);
+ if (icon){
+ return (
+ <div key={iconKey} className='marker-icon'>
+ <IconButton
+ onPointerDown={() => {}}
+ icon={MarkerIcons.getFontAwesomeIcon(iconKey, 'white')}
+ />
+ </div>
+ )
+ }
+ return null;
+ })}
+ </div>
+ <div style={{width: '100%', height:'3px', color: 'white'}}></div>
+ </div>
+ }
{buttons}
</div>
, true);
diff --git a/src/client/views/nodes/MapBox/MapBox.scss b/src/client/views/nodes/MapBox/MapBox.scss
index 946c6f495..bc2f90fbd 100644
--- a/src/client/views/nodes/MapBox/MapBox.scss
+++ b/src/client/views/nodes/MapBox/MapBox.scss
@@ -12,8 +12,10 @@
font-size: 17;
}
.mapBox-searchbar {
- // display: flex;
- // flex-direction: row;
+ display: flex;
+ flex-direction: row;
+ gap: 5px;
+ align-items: center;
width: calc(100% - 40px);
// .editableText-container {
@@ -25,6 +27,38 @@
// }
}
+ .mapbox-settings-panel{
+ z-index: 900;
+ padding: 10px 20px;
+ display: flex;
+ background-color: rgb(187, 187, 187);
+ font-size: 1.3em;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: center;
+ gap: 7px;
+ position: absolute;
+ border-top-left-radius: 5px;
+ border-bottom-left-radius: 5px;
+
+ .mapbox-style-select{
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: center;
+ gap: 4px;
+ }
+
+ .mapbox-terrain-selection{
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 4px;
+ }
+
+ }
+
.mapbox-geocoding-search-results {
z-index: 900;
display: flex;
@@ -35,6 +69,8 @@
background-color: rgb(187, 187, 187);
font-size: 1.4em;
padding: 10px;
+ border-top-right-radius: 5px;
+ border-bottom-right-radius: 5px;
.search-result-container {
width: 100%;
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 2b563faf2..ac926e1fb 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -9,7 +9,7 @@ import * as React from 'react';
import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc';
import { DocCss, Highlight } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
-import { DocCast, NumCast, StrCast } from '../../../../fields/Types';
+import { Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils';
import { Docs, DocUtils } from '../../../documents/Documents';
import { DocumentType } from '../../../documents/DocumentTypes';
@@ -52,11 +52,13 @@ import './MapBox.scss';
import { NumberLiteralType } from 'typescript';
// import { GeocoderControl } from './GeocoderControl';
import mapboxgl, { LngLat, MapLayerMouseEvent } from 'mapbox-gl';
-import { Feature, FeatureCollection } from 'geojson';
+import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString, MultiLineString, Position } from 'geojson';
import { MarkerEvent } from 'react-map-gl/dist/esm/types';
import { MapboxApiUtility, TransportationType} from './MapboxApiUtility';
-import { Autocomplete, TextField } from '@mui/material';
+import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/material';
import { List } from '../../../../fields/List';
+import { listSpec } from '../../../../fields/Schema';
+import { IconLookup, faGear } from '@fortawesome/free-solid-svg-icons';
// amongus
/**
@@ -140,15 +142,17 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@computed get allRoutes() {
return this.allAnnotations.filter(anno => anno.type === DocumentType.MAPROUTE);
}
- @computed get allRoutesGeoJson() {
- const features = this.allRoutes.map(route => {
+ @computed get allRoutesGeoJson(): FeatureCollection {
+ const features: Feature<Geometry, GeoJsonProperties>[] = this.allRoutes.map(route => {
+ console.log("Route coords: ", route.coordinates);
+ const geometry: LineString = {
+ type: 'LineString',
+ coordinates: JSON.parse(StrCast(route.coordinates))
+ }
return {
type: 'Feature',
properties: {},
- geometry: {
- type: 'LineString',
- coordinates: route.coordinates
- }
+ geometry: geometry
};
});
@@ -771,7 +775,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
NumCast(longitude),
false,
[],
- {title: location ?? `lat=${latitude},lng=${longitude}`, map: location, description: "", wikiData: wikiData},
+ {
+ title: location ?? `lat=${latitude},lng=${longitude}`,
+ map: location,
+ description: "",
+ wikiData: wikiData,
+ markerType: 'MAPBOX_MARKER',
+ markerColor: '#3FB1CE'
+ },
// { title: map ?? `lat=${latitude},lng=${longitude}`, map: map },
// ,'pushpinIDamongus'+ this.incrementer++
);
@@ -783,11 +794,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}, 'createpin');
@action
- createMapRoute = undoable((coordinates: List<any>, origin: string, destination: string) => {
+ createMapRoute = undoable((coordinates: Position[], origin: string, destination: string) => {
+ console.log(coordinates);
const mapRoute = Docs.Create.MapRouteDocument(
false,
[],
- {title: `${origin} -> ${destination}`, routeCoordinates: coordinates},
+ {title: `${origin} -> ${destination}`, routeCoordinates: JSON.stringify(coordinates)},
);
this.addDocument(mapRoute, this.annotationKey);
return mapRoute;
@@ -800,29 +812,11 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
- @observable
- mapboxMapViewState: ViewState = {
- zoom: 9,
- longitude: -71.41,
- latitude: 41.82,
- pitch: 0,
- bearing: 0,
- padding: {
- top: 0,
- bottom: 0,
- left: 0,
- right: 0
- }
- }
+
@observable
featuresFromGeocodeResults: any[] = [];
- @action
- onMapMove = (e: ViewStateChangeEvent) => {
- this.mapboxMapViewState = e.viewState;
- }
-
@action
addMarkerForFeature = (feature: any) => {
@@ -838,6 +832,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
location,
wikiData
)
+
+ if (this._mapRef.current){
+ this._mapRef.current.flyTo({
+ center: feature.center
+ });
+ }
this.featuresFromGeocodeResults = [];
} else {
@@ -855,6 +855,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const features = await MapboxApiUtility.forwardGeocodeForFeatures(searchText);
if (features){
runInAction(() => {
+ this.settingsOpen= false;
this.featuresFromGeocodeResults = features;
})
}
@@ -988,6 +989,75 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
+ @observable
+ mapboxMapViewState: ViewState = {
+ zoom: 9,
+ longitude: -71.45,
+ latitude: 41.82,
+ pitch: 0,
+ bearing: 0,
+ padding: {
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0
+ }
+ }
+
+ @observable
+ settingsOpen: boolean = false;
+
+ @observable
+ mapStyle: string = 'mapbox://styles/mapbox/streets-v12'
+
+ @observable
+ showTerrain: boolean = false;
+
+ @action
+ toggleSettings = () => {
+ this.featuresFromGeocodeResults = [];
+ this.settingsOpen = !this.settingsOpen;
+ }
+
+ @action
+ changeMapStyle = (e: React.ChangeEvent<HTMLSelectElement>) => {
+ this.mapStyle = `mapbox://styles/mapbox/${e.target.value}`
+ }
+
+ @action
+ onMapMove = (e: ViewStateChangeEvent) => {
+ this.mapboxMapViewState = e.viewState;
+ }
+
+ @action
+ toggleShowTerrain = () => {
+ this.showTerrain = !this.showTerrain;
+ }
+
+ @action
+ onBearingChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ const newVal = parseInt(e.target.value)
+ if (!isNaN(newVal) && newVal >= 0){
+ this.mapboxMapViewState = {
+ ...this.mapboxMapViewState,
+ bearing: parseInt(e.target.value)
+ }
+ }
+ }
+
+ @action
+ onPitchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ const newVal = parseInt(e.target.value);
+ if (!isNaN(newVal) && newVal >= 0){
+ this.mapboxMapViewState = {
+ ...this.mapboxMapViewState,
+ pitch: parseInt(e.target.value)
+ }
+ }
+ }
+
+
+
static _firstRender = true;
static _rerenderDelay = 500;
@@ -1029,51 +1099,59 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
placeholder='Enter a location'
onChange={(e) => this.handleSearchChange(e.target.value)}
/>
- {/* <Autocomplete
- fullWidth
- id="map-location-searcher"
- freeSolo
- onInputChange={(e, searchText) => this.handleSearchChange(searchText)}
- onChange={(e, selectedOption) => {
- this.handleSearchChange(""); // clear input
- this.addMarkerForFeature(selectedOption);
- }}
- options={this.featuresFromGeocodeResults
- .filter(feature => feature.place_name)
- .map(feature => feature)}
- getOptionLabel={(feature) => feature.place_name}
- renderInput={(params) => (
- <TextField
- {...params}
- placeholder='Enter a location'
- />
- )}
- /> */}
- {/* <EditableText
- // editing
- setVal={(newText: string | number) => typeof newText === 'string' && this.handleSearchChange(newText)}
- // onEnter={e => this.bingSearch()}
- onEnter={e => {}}
- height={32}
- // placeholder={this.bingSearchBarContents || 'Enter a location'}
- placeholder='Enter a location'
- textAlign="center"
- /> */}
- {/* <IconButton
- icon={
- <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="magnifying-glass" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" color="#DFDFDF">
- <path
- fill="currentColor"
- d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"></path>
- </svg>
- }
- onClick={this.bingSearch}
+ <IconButton
+ icon={<FontAwesomeIcon icon={faGear as IconLookup} size='1x'/>}
type={Type.TERT}
+ onClick={(e) => this.toggleSettings()}
+
/>
- <div style={{ width: 30, height: 30 }} ref={this._dragRef} onPointerDown={this.dragToggle}>
- <Button tooltip="drag to place a pushpin" icon={<FontAwesomeIcon size={'lg'} icon={'bullseye'} />} />
- </div> */}
</div>
+ {this.settingsOpen &&
+ <div className='mapbox-settings-panel' style={{right: `${0+ this.sidebarWidth()}px`}}>
+ <div className='mapbox-style-select'>
+ <div>
+ Map Style:
+ </div>
+ <div>
+ <select onChange={this.changeMapStyle}>
+ <option value='streets-v12'>Streets</option>
+ <option value='outdoors-v12'>Outdoors</option>
+ <option value='light-v11'>Light</option>
+ <option value='dark-v11'>Dark</option>
+ <option value='satellite-v9'>Satellite</option>
+ <option value='satellite-streets-v12'>Satellite Streets</option>
+ <option value='navigation-day-v1'>Navigation Day</option>
+ <option value='navigation-night-v1'>Navigation Night</option>
+ </select>
+ </div>
+ </div>
+ <div className='mapbox-bearing-selection'>
+ <div>Bearing: </div>
+ <input
+ value={this.mapboxMapViewState.bearing}
+ min={0}
+ type='number'
+ onChange={this.onBearingChange}/>
+ </div>
+ <div className='mapbox-pitch-selection'>
+ <div>Pitch: </div>
+ <input
+ value={this.mapboxMapViewState.pitch}
+ min={0}
+ type='number'
+ onChange={this.onPitchChange}/>
+ </div>
+ <div className='mapbox-terrain-selection'>
+ <div>Show terrain: </div>
+ <input
+ type='checkbox'
+ checked={this.showTerrain}
+ onChange={this.toggleShowTerrain}
+ />
+ </div>
+ </div>
+ }
+
<div className='mapbox-geocoding-search-results'>
{this.featuresFromGeocodeResults.length > 0 && (
<React.Fragment>
@@ -1107,15 +1185,24 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}}
mapboxAccessToken={MAPBOX_ACCESS_TOKEN}
id="mapbox-map"
- mapStyle="mapbox://styles/mapbox/streets-v9"
+ mapStyle={this.mapStyle}
style={{height: '100%', width: '100%'}}
{...this.mapboxMapViewState}
onMove={this.onMapMove}
onDblClick={this.handleMapClick}
+ terrain={this.showTerrain ? { source: 'mapbox-dem', exaggeration: 2.0 } : undefined}
>
+ <Source
+ id="mapbox-dem"
+ type="raster-dem"
+ url="mapbox://mapbox.mapbox-terrain-dem-v1"
+ tileSize={512}
+ maxzoom={14}
+ />
<Source id='temporary-route' type='geojson' data={this.temporaryRouteSource}/>
+ <Source id='map-routes' type='geojson' data={this.allRoutesGeoJson}/>
<Layer
id='temporary-route-layer'
type='line'
@@ -1123,6 +1210,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
layout={{"line-join": "round", "line-cap": "round"}}
paint={{"line-color": "#36454F", "line-width": 4, "line-dasharray": [1,1]}}
/>
+ <Layer
+ id='map-routes-layer'
+ type='line'
+ source='map-routes'
+ layout={{"line-join": "round", "line-cap": "round"}}
+ paint={{"line-color": "#FF0000", "line-width": 4}}
+ />
+
<>
{this.allPushpins
// .filter(anno => !anno.layout_unrendered)
@@ -1219,3 +1314,48 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
}
}
+
+{/* <Autocomplete
+ fullWidth
+ id="map-location-searcher"
+ freeSolo
+ onInputChange={(e, searchText) => this.handleSearchChange(searchText)}
+ onChange={(e, selectedOption) => {
+ this.handleSearchChange(""); // clear input
+ this.addMarkerForFeature(selectedOption);
+ }}
+ options={this.featuresFromGeocodeResults
+ .filter(feature => feature.place_name)
+ .map(feature => feature)}
+ getOptionLabel={(feature) => feature.place_name}
+ renderInput={(params) => (
+ <TextField
+ {...params}
+ placeholder='Enter a location'
+ />
+ )}
+ /> */}
+ {/* <EditableText
+ // editing
+ setVal={(newText: string | number) => typeof newText === 'string' && this.handleSearchChange(newText)}
+ // onEnter={e => this.bingSearch()}
+ onEnter={e => {}}
+ height={32}
+ // placeholder={this.bingSearchBarContents || 'Enter a location'}
+ placeholder='Enter a location'
+ textAlign="center"
+ /> */}
+ {/* <IconButton
+ icon={
+ <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="magnifying-glass" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" color="#DFDFDF">
+ <path
+ fill="currentColor"
+ d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"></path>
+ </svg>
+ }
+ onClick={this.bingSearch}
+ type={Type.TERT}
+ />
+ <div style={{ width: 30, height: 30 }} ref={this._dragRef} onPointerDown={this.dragToggle}>
+ <Button tooltip="drag to place a pushpin" icon={<FontAwesomeIcon size={'lg'} icon={'bullseye'} />} />
+ </div> */} \ No newline at end of file
diff --git a/src/client/views/nodes/MapBox/MapboxApiUtility.ts b/src/client/views/nodes/MapBox/MapboxApiUtility.ts
index 80962f435..011b6f72a 100644
--- a/src/client/views/nodes/MapBox/MapboxApiUtility.ts
+++ b/src/client/views/nodes/MapBox/MapboxApiUtility.ts
@@ -68,6 +68,8 @@ export class MapboxApiUtility {
const geometry = routeData.geometry;
const coordinates = geometry.coordinates;
+ console.log(coordinates);
+
routeInfoMap[transportationTypeKey] = {
duration: this.secondsToMinutesHours(routeData.duration),
distance: this.metersToMiles(routeData.distance),
diff --git a/src/client/views/nodes/MapBox/MarkerIcons.tsx b/src/client/views/nodes/MapBox/MarkerIcons.tsx
new file mode 100644
index 000000000..cf50109ac
--- /dev/null
+++ b/src/client/views/nodes/MapBox/MarkerIcons.tsx
@@ -0,0 +1,87 @@
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { faShopify } from '@fortawesome/free-brands-svg-icons';
+import { IconLookup, faBasketball, faBicycle, faBowlFood, faBus, faCameraRetro, faCar, faCartShopping, faFilm, faFootball, faFutbol, faHockeyPuck, faHospital, faHotel, faHouse, faLandmark, faMasksTheater, faMugSaucer, faPersonHiking, faPlane, faSchool, faShirt, faShop, faSquareParking, faStar, faTrainSubway, faTree, faUtensils, faVolleyball } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import React = require('react');
+
+export type MapboxColor = 'yellow' | 'red' | 'orange' | 'purple' | 'pink' | 'blue' | 'green';
+type ColorProperties = {
+ fill: string,
+ stroke: string
+}
+type ColorsMap = {
+ [key in MapboxColor]: ColorProperties;
+}
+
+export class MarkerIcons {
+
+ static getMapboxIcon = (color: string) => {
+ return (
+ <svg xmlns="http://www.w3.org/2000/svg" id="marker" data-name="marker" width="20" height="48" viewBox="0 0 20 35">
+ <g id="mapbox-marker-icon">
+ <g id="icon">
+ <ellipse id="shadow" cx="10" cy="27" rx="9" ry="5" fill="#c4c4c4" opacity="0.3" />
+ <g id="mask" opacity="0.3">
+ <g id="group">
+ <path id="shadow-2" data-name="shadow" fill="#bfbfbf" d="M10,32c5,0,9-2.2,9-5s-4-5-9-5-9,2.2-9,5S5,32,10,32Z" fillRule="evenodd"/>
+ </g>
+ </g>
+ <path id="color" fill={color} strokeWidth="0.5" d="M19.25,10.4a13.0663,13.0663,0,0,1-1.4607,5.2235,41.5281,41.5281,0,0,1-3.2459,5.5483c-1.1829,1.7369-2.3662,3.2784-3.2541,4.3859-.4438.5536-.8135.9984-1.0721,1.3046-.0844.1-.157.1852-.2164.2545-.06-.07-.1325-.1564-.2173-.2578-.2587-.3088-.6284-.7571-1.0723-1.3147-.8879-1.1154-2.0714-2.6664-3.2543-4.41a42.2677,42.2677,0,0,1-3.2463-5.5535A12.978,12.978,0,0,1,.75,10.4,9.4659,9.4659,0,0,1,10,.75,9.4659,9.4659,0,0,1,19.25,10.4Z"/>
+ <path id="circle" fill="#fff" stroke='white' strokeWidth="0.5" d="M13.55,10A3.55,3.55,0,1,1,10,6.45,3.5484,3.5484,0,0,1,13.55,10Z"/>
+ </g>
+ </g>
+ <rect width="20" height="48" fill="none"/>
+ </svg>
+ )
+ }
+
+ static getFontAwesomeIcon(key: string, color?: string): JSX.Element | undefined {
+ const icon: IconProp = MarkerIcons.FAMarkerIconsMap[key];
+
+ if (icon) {
+ const iconProps: any = { icon };
+
+ if (color) {
+ iconProps.color = color;
+ }
+
+ return (<FontAwesomeIcon {...iconProps} size='1x' />);
+ }
+
+ return undefined;
+ }
+
+ static FAMarkerIconsMap: {[key: string]: IconProp} = {
+ 'RESTAURANT_ICON': faUtensils,
+ 'HOTEL_ICON': faHotel,
+ 'HOUSE_ICON': faHouse,
+ 'AIRPLANE_ICON': faPlane,
+ 'CAR_ICON': faCar,
+ 'BUS_ICON': faBus,
+ 'TRAIN_ICON': faTrainSubway,
+ 'BICYCLE_ICON': faBicycle,
+ 'PARKING_ICON': faSquareParking,
+ 'PHOTO_ICON': faCameraRetro,
+ 'CAFE_ICON': faMugSaucer,
+ 'STAR_ICON': faStar,
+ 'SHOPPING_CART_ICON': faCartShopping,
+ 'SHOPIFY_ICON': faShopify,
+ 'SHOP_ICON': faShop,
+ 'SHIRT_ICON': faShirt,
+ 'FOOD_ICON': faBowlFood,
+ 'LANDMARK_ICON': faLandmark,
+ 'HOSPITAL_ICON': faHospital,
+ 'NATURE_ICON': faTree,
+ 'HIKING_ICON': faPersonHiking,
+ 'SOCCER_ICON': faFutbol,
+ 'VOLLEYBALL_ICON': faVolleyball,
+ 'BASKETBALL_ICON': faBasketball,
+ 'HOCKEY_ICON': faHockeyPuck,
+ 'FOOTBALL_ICON': faFootball,
+ 'SCHOOL_ICON': faSchool,
+ 'THEATER_ICON': faMasksTheater,
+ 'FILM_ICON': faFilm
+ }
+
+
+} \ No newline at end of file
diff --git a/src/client/views/nodes/MapBox/icon_images/mapbox-marker-icon-20px-blue.png b/src/client/views/nodes/MapBox/icon_images/mapbox-marker-icon-20px-blue.png
new file mode 100644
index 000000000..8b686e2aa
--- /dev/null
+++ b/src/client/views/nodes/MapBox/icon_images/mapbox-marker-icon-20px-blue.png
Binary files differ
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 084cb872a..1678d9012 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1598,4 +1598,4 @@ ScriptingGlobals.add(function setDocFilter(container: Doc, key: string, value: a
});
ScriptingGlobals.add(function setDocRangeFilter(container: Doc, key: string, range: number[]) {
Doc.setDocRangeFilter(container, key, range);
-});
+}); \ No newline at end of file