aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/collections/MapView/CollectionMapView.scss2
-rw-r--r--src/client/views/collections/MapView/CollectionMapView.tsx261
2 files changed, 86 insertions, 177 deletions
diff --git a/src/client/views/collections/MapView/CollectionMapView.scss b/src/client/views/collections/MapView/CollectionMapView.scss
index c76f1d4b9..6ad0f3a92 100644
--- a/src/client/views/collections/MapView/CollectionMapView.scss
+++ b/src/client/views/collections/MapView/CollectionMapView.scss
@@ -15,7 +15,7 @@
.searchbox {
box-sizing: border-box;
border: 1px solid transparent;
- width: 240px;
+ width: 300px;
height: 32px;
padding: 0 12px;
border-radius: 3px;
diff --git a/src/client/views/collections/MapView/CollectionMapView.tsx b/src/client/views/collections/MapView/CollectionMapView.tsx
index 290972364..d7025f6da 100644
--- a/src/client/views/collections/MapView/CollectionMapView.tsx
+++ b/src/client/views/collections/MapView/CollectionMapView.tsx
@@ -31,9 +31,14 @@ import { MapMarker } from '../../nodes/MapMarker/MapMarker';
type MapSchema = makeInterface<[typeof documentSchema]>;
const MapSchema = makeInterface(documentSchema);
+export type Coordinates = {
+ lat: number,
+ lng: number,
+}
+
export type LocationData = {
- id?: number;
- pos?: { lat: number, lng: number };
+ id: string;
+ pos: Coordinates;
};
const mapContainerStyle = {
@@ -45,6 +50,28 @@ const defaultCenter = {
lng: -115.234,
};
+const mapOptions = {
+ fullscreenControl: false,
+}
+
+const drawingManager = new google.maps.drawing.DrawingManager({
+ drawingControl: true,
+ drawingControlOptions: {
+ position: google.maps.ControlPosition.TOP_RIGHT,
+ drawingModes: [
+ google.maps.drawing.OverlayType.MARKER,
+ google.maps.drawing.OverlayType.CIRCLE,
+ google.maps.drawing.OverlayType.POLYLINE,
+ ],
+ },
+});
+
+const options = {
+ fields: ["formatted_address", "geometry", "name"], // note: level of details is charged by item per retrieval, not recommended to return all fields
+ strictBounds: false,
+ types: ["establishment"], // type pf places, subject of change according to user need
+} as google.maps.places.AutocompleteOptions;
+
@observer
export default class CollectionMapView extends CollectionSubView<MapSchema, Partial<GoogleMapProps>>(MapSchema) {
private _dropDisposer?: DragManager.DragDropDisposer;
@@ -52,8 +79,8 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
@observable private _map = null as unknown as google.maps.Map;
- @observable private selectedPlace: LocationData = null as any;
- @observable private markerMap = {};
+ @observable private selectedPlace: LocationData | undefined;
+ @observable private markerMap: { [id: string]: google.maps.Marker } = {};
@observable private center = defaultCenter;
@observable private zoom = 2.5;
@observable private clickedLatLng = null;
@@ -62,19 +89,12 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
@observable private inputRef = React.createRef<HTMLInputElement>();
@observable private buttonRef = React.createRef<HTMLDivElement>();
@observable private searchMarkers: google.maps.Marker[] = [];
+ @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options);
- private options = {
- fields: ["formatted_address", "geometry", "name"], // note: level of details is charged by item per retrieval, not recommended to return all fields
- strictBounds: false,
- types: ["establishment"], // type pf places, subject of change according to user need
- } as google.maps.places.AutocompleteOptions;
-
- @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, this.options);
-
- @observable private myPlaces = [
- { id: 1, pos: { lat: 39.09366509575983, lng: -94.58751660204751 } },
- { id: 2, pos: { lat: 41.82399, lng: -71.41283 } },
- { id: 3, pos: { lat: 47.606214, lng: -122.33207 } },
+ @observable private myPlaces: LocationData[] = [
+ { id: "id1", pos: { lat: 39.09366509575983, lng: -94.58751660204751 } },
+ { id: "id2", pos: { lat: 41.82399, lng: -71.41283 } },
+ { id: "id3", pos: { lat: 47.606214, lng: -122.33207 } },
];
@action
@@ -82,87 +102,46 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
this.searchBox = searchBox;
}
- @action
- private setButton = (button: any) => {
- this.buttonRef = button;
- this._map.controls[google.maps.ControlPosition.TOP_RIGHT].push(this.buttonRef.current!)
- }
-
// iterate myPlaces to size, center, and zoom map to contain all markers
private fitBounds = (map: google.maps.Map) => {
console.log('map bound is:' + this.bounds);
- this.myPlaces.map(place => {
- this.bounds.extend(place.pos);
- return place.id;
- });
- map.fitBounds(this.bounds)
+ this.myPlaces ? this.myPlaces.map(place => {
+ this.bounds.extend(place.pos!);
+ }) : null;
+ map.fitBounds(this.bounds);
}
// store a reference to google map instance; fit map bounds to contain all markers
@action
private loadHandler = (map: google.maps.Map) => {
this._map = map;
+ drawingManager.setMap(map);
this.fitBounds(map);
-
- // //add a custom control for button add marker
- // //TODO: why this doesn't work
- // const google = window.google;
- // console.log("google window: " + google)
- // const controlButtonDiv = document.createElement('div');
- // ReactDOM.render(<button onClick={() => console.log('click me to add marker!')}>Add Marker</button>, controlButtonDiv);
- // map.controls[google.maps.ControlPosition.TOP_RIGHT].push(controlButtonDiv);
}
@action
- private markerClickHandler = (e: MouseEvent, place: LocationData) => {
+ private markerClickHandler = (e: MouseEvent, place: any) => {
// set which place was clicked
- this.selectedPlace = place
+ this.selectedPlace = place;
- console.log(this.selectedPlace.id);
- console.log(this.selectedPlace.pos);
+ console.log(this.selectedPlace);
// used so clicking a second marker works
if (this.infoWindowOpen) {
this.infoWindowOpen = false;
console.log("closeinfowindow")
}
- else {
- this.infoWindowOpen = true;
- console.log("open infowindow")
- }
+ this.infoWindowOpen = true;
+ console.log("open infowindow")
}
- // @action
- // private handleInfoWindowClose = () => {
- // if (this.infoWindowOpen) {
- // this.infoWindowOpen = false;
- // }
- // this.infoWindowOpen = false;
- // this.selectedPlace = { id: undefined, pos: undefined };
- // }
-
- // @action
- // private markerLoadHandler = (marker: any, place: LocationData) => {
- // if (marker != null) {
- // this.markerMap[place.id] = marker;
- // }
- // }
-
@action
- @undoBatch
- private handleDragMarker = (marker: any, place: LocationData) => {
- // if (marker != null) {
- // place = {
- // id: place.id,
- // position: {
- // lat: marker.latLng.lat().toFixed(3),
- // lng: marker.latLng.lng().toFixed(3)
- // }
- // }
-
- // console.log(place);
- // console.log(this.myPlaces);
- // }
+ private handleInfoWindowClose = () => {
+ if (this.infoWindowOpen) {
+ this.infoWindowOpen = false;
+ }
+ this.infoWindowOpen = false;
+ this.selectedPlace = undefined;
}
@action
@@ -186,17 +165,16 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
this._map.setZoom(17);
}
- /**
- * customize icon => customized icon for the nature of the location selected (hard to tell from other pre-existing markers, probably won't implement
- */
- // const icon = {
- // url: place.icon as string,
- // size: new google.maps.Size(71, 71),
- // origin: new google.maps.Point(0, 0),
- // anchor: new google.maps.Point(17, 34),
- // scaledSize: new google.maps.Size(25, 25),
- // };
+ // customize icon => customized icon for the nature of the location selected
+ const icon = {
+ url: place.icon as string,
+ size: new google.maps.Size(71, 71),
+ origin: new google.maps.Point(0, 0),
+ anchor: new google.maps.Point(17, 34),
+ scaledSize: new google.maps.Size(25, 25),
+ };
+ // put temporary cutomized marker on searched location
this.searchMarkers.forEach((marker) => {
marker.setMap(null);
});
@@ -204,64 +182,13 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
this.searchMarkers.push(
new window.google.maps.Marker({
map: this._map,
+ icon,
title: place.name,
position: place.geometry.location,
})
)
}
- // @computed get markerContent() {
- // const allMarkers = this.childLayoutPairs
- // const markerId = NumCast(this.layoutDoc._itemIndex);
- // const selectedMarker = this.childLayoutPairs?.[markerId];
- // const position = {
- // lat: NumCast(this.layoutDoc.lat),
- // lng: NumCast(this.layoutDoc.lng)
- // }
- // return <>
- // {
- // allMarkers?.map(place => (
- // <Marker
- // key={markerId}
- // position={position}
- // onClick={e => this.markerClickHandler(e, place.layout)} //??
- // draggable={true}
- // onDragEnd={marker => this.handleDragMarker(marker, place.layout)}
- // />
- // ))
- // }
- // {this.infoWindowOpen && selectedMarker && (
- // <InfoBox
- // //anchor={selectedMarker}
- // // onCloseClick={this.handleInfoWindowClose}
- // position={position}
- // // options={{ enableEventPropagation: true }}
- // >
- // <div style={{ backgroundColor: 'white', opacity: 0.75, padding: 12 }}>
- // <div style={{ fontSize: 16 }}>
- // {/* the linkmenu as the ones in other nodes */}
- // <div>
- // <a>a link to another node</a>
- // <hr />
- // </div>
- // <div>
- // <a>a link to another node</a>
- // <hr />
- // </div>
- // <div>
- // <a>a link to another node</a>
- // <hr />
- // </div>
- // <div>
- // <button>New +</button>
- // </div>
- // </div>
- // </div>
- // </InfoBox>
- // )}
-
- // </>
- // }
@action
private addMarker = (location: google.maps.LatLng | undefined, map: google.maps.Map) => {
@@ -271,18 +198,10 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
});
}
- // @action
- // private renderMarkerToMap = (marker: Doc) => {
- // const id = StrCast(marker.id);
- // const lat = NumCast(marker.lat);
- // const lng = NumCast(marker.lng);
-
- // return <Marker
- // key={id}
- // position={{ lat: lat, lng: lng }}
- // onClick={e => this.markerClickHandler(e, marker)}
- // />
- // }
+ @action
+ private markerLoadHandler = (marker: google.maps.Marker, place: LocationData) => {
+ place.id ? this.markerMap[place.id] = marker : null;
+ }
render() {
const { Document, fieldKey, isContentActive: active } = this.props;
@@ -303,6 +222,7 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
zoom={this.zoom}
center={this.center}
onLoad={map => this.loadHandler(map)}
+ options={mapOptions}
>
<Autocomplete
onLoad={this.setSearchBox}
@@ -310,49 +230,38 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
<input ref={this.inputRef} className="searchbox" type="text" placeholder="Search anywhere:" />
</Autocomplete>
- <div onLoad={this.setButton}>
- <div ref={this.buttonRef} className="add-button-UI" >
- <div className="add-button-Text">Add Marker</div>
- </div>
- </div>
-
- {this.myPlaces.map(place => (
+ {this.myPlaces ? this.myPlaces.map(place =>
<Marker
- key={place.id}
position={place.pos}
- // onLoad={marker => this.markerLoadHandler(marker, place)}
+ onLoad={marker => this.markerLoadHandler(marker, place)}
onClick={e => this.markerClickHandler(e, place)}
- draggable={true}
- onDragEnd={marker => this.handleDragMarker(marker, place)}
+ draggable={false}
/>
- ))}
+ ) : null}
{this.infoWindowOpen && this.selectedPlace && (
- <InfoBox
- // anchor={this.markerMap[this.selectedPlace.id]}
- // onCloseClick={this.handleInfoWindowClose}
- position={this.selectedPlace.pos}
- // options={{ enableEventPropagation: true }}
+ <InfoWindow
+ anchor={this.markerMap[this.selectedPlace.id!]}
+ onCloseClick={this.handleInfoWindowClose}
>
<div style={{ backgroundColor: 'white', opacity: 0.75, padding: 12 }}>
<div style={{ fontSize: 16 }}>
<div>
- <a>a link to another node</a>
- <hr />
- </div>
- <div>
- <a>a link to another node</a>
+ <img src="http://placekitten.com/200/300" />
<hr />
- </div>
- <div>
- <a>a link to another node</a>
+ <form>
+ <label>Title: </label><br />
+ <input type="text" id="fname" name="fname"></input><br />
+ <label>Desription: </label><br />
+ <textarea style={{ height: 150 }} id="lname" name="lname" placeholder="Notes, a short description of this location, a brief comment, etc."></textarea>
+ </form>
<hr />
- </div>
- <div>
- <button>New +</button>
+ <div>
+ <button>New link+</button>
+ </div>
</div>
</div>
</div>
- </InfoBox>
+ </InfoWindow>
)}
</GoogleMap>
</div>