Commit 44859380 authored by Elisabeth Reuhl's avatar Elisabeth Reuhl
Browse files

Merge branch 'map'

# Conflicts:
#	src/components/AppContent/AppContent.jsx
#	src/components/OurMap/OurMap.jsx
parents ba84a935 8bbd78a9
......@@ -178,24 +178,6 @@ export const AppContent = () => {
dispatch({type: "UPDATE_INPUT", payload: {field: "selectedMarker", value: index}});
}
//TODO: not possible to change map view twice in a row if markers have not changed
const extendMapBounds = () => {
let markers;
if(mapDataContext.entity) markers = mapDataContext.entity;
else if(mapDataObjects.entitiesMultiFilter) markers = mapDataObjects.entitiesMultiFilter;
else if(mapDataSitesByRegion.sitesByRegion) markers = mapDataSitesByRegion.sitesByRegion;
else if(mapDataArchaeoSites.archaeologicalSites) markers = mapDataArchaeoSites.archaeologicalSites;
if(!markers) return;
const newMapBounds = latLngBounds();
markers.map( (item) => {
if (item && item.coordinates) return newMapBounds.extend(item.coordinates.split(", ").reverse());
else if (item && item.spatial) return item.spatial.map( (nestedItem) =>
nestedItem &&
newMapBounds.extend(nestedItem.coordinates.split(", ").reverse()));
});
dispatch({type: "UPDATE_INPUT", payload: {field: "mapBounds", value: newMapBounds}});
}
useEffect( () => {
if(dataContext && input.mode === "objects" && input.showRelatedObjects) {
......@@ -270,6 +252,31 @@ export const AppContent = () => {
// query result not empty
&& mapDataSitesByRegion && mapDataSitesByRegion.sitesByRegion;
const getMapData = () => {
let mapData;
if(renderingConditionObjects) mapData = mapDataObjects?.entitiesMultiFilter;
else if(renderingConditionRelatedObjects) mapData = {original: mapDataContext?.entity?.spatial, related: mapDataContext?.entity?.related};
else if(renderingConditionSites) mapData = mapDataArchaeoSites?.archaeologicalSites;
else if(renderingConditionSitesByRegion) mapData = mapDataSitesByRegion?.sitesByRegion;
return mapData;
}
const getMapDataType = () => {
let type = null;
let handler = false;
if(renderingConditionObjects) handler = true;
else if(renderingConditionRelatedObjects) {
type = "related";
handler = true;
}
return {type: type, handler: handler};
}
const setWidth = () => window.innerWidth
const setOneTwelfthWidth = () => setWidth() / 12
......@@ -349,17 +356,10 @@ export const AppContent = () => {
area={area}
content={
<OurMap
extendMapBounds={extendMapBounds}
handleRelatedObjects={handleRelatedObjects}
mapDataObjects={mapDataObjects}
mapDataContext={mapDataContext}
mapDataArchaeoSites={mapDataArchaeoSites}
mapDataSitesByRegion={mapDataSitesByRegion}
data={getMapData()}
dataType={getMapDataType()}
reducer={[input, dispatch]}
renderingConditionObjects={renderingConditionObjects}
renderingConditionRelatedObjects={renderingConditionRelatedObjects}
renderingConditionSites={renderingConditionSites}
renderingConditionSitesByRegion={renderingConditionSitesByRegion}
/>
}
/>
......
......@@ -7,6 +7,7 @@ query searchObjects($searchTerm: String, $catalogIds: [Int], $bbox: [String], $p
identifier
name
coordinates
polygon
}
dating
datingSpan
......@@ -42,6 +43,7 @@ query searchObjectContext($arachneId: ID!) {
identifier
name
coordinates
polygon
}
dating
datingSpan
......@@ -75,6 +77,7 @@ query searchArchaeoSites($searchTerm: String, $bbox: [String]) {
identifier
name
coordinates
polygon
types
locatedIn {
identifier
......@@ -88,6 +91,7 @@ query byRegion($searchTerm: String, $idOfRegion: ID!) {
identifier
name
coordinates
polygon
types
locatedIn {
identifier
......@@ -101,6 +105,7 @@ query searchArchaeoSiteContext($searchTerm: String, $bbox: [String]) {
identifier
name
coordinates
polygon
types
locatedIn {
identifier
......
......@@ -6,7 +6,8 @@ export const CreateMarkers = (props) => {
const { data, selectedMarker, handleRelatedObjects, showRelatedObjects } = props;
return data && data.map((item, index) => {
if(!data) return null;
else return data && data.map((item, index) => {
if (item && item.coordinates) {
return (
item &&
......
import React, { useEffect, useRef } from "react";
import { Circle, Map, Rectangle, TileLayer } from 'react-leaflet';
import { Circle, GeoJSON, Map, Rectangle, TileLayer } from 'react-leaflet';
import MarkerClusterGroup from "react-leaflet-markercluster";
import { CreateMarkers } from '..'
import { CreateMarkers, ReturnPopup } from '..'
import { useTranslation } from "react-i18next";
import { FormLabel, Grid, Switch, Tooltip } from "@material-ui/core";
import MapIcon from "@material-ui/icons/Map";
import { useStyles } from '../../styles';
import { makeStyles } from "@material-ui/core/styles";
import { latLngBounds } from "leaflet";
const osmTiles = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
......@@ -15,18 +16,14 @@ const osmAttr = '&copy; <a href="https://www.openstreetmap.org/copyright">OpenSt
export const OurMap = (props) => {
const [input, dispatch] = props.reducer;
const {
extendMapBounds,
handleRelatedObjects,
mapDataObjects,
mapDataContext,
mapDataArchaeoSites,
mapDataSitesByRegion,
renderingConditionObjects,
renderingConditionRelatedObjects,
renderingConditionSites,
renderingConditionSitesByRegion
data,
dataType
} = props;
let markers = data;
if(dataType.type === "related") markers = data.original;
const { t, i18n } = useTranslation();
// additional styling for this component only
......@@ -41,9 +38,30 @@ export const OurMap = (props) => {
const mapRef = useRef(null);
const resetMapBounds = () => {
if(markers.length === 0) return;
const newMapBounds = latLngBounds();
markers.map( (item) => {
if (item?.coordinates) return newMapBounds.extend(item.coordinates.split(", ").reverse());
else if (item && item.spatial) return item.spatial.map( (nestedItem) =>
nestedItem && nestedItem.coordinates &&
newMapBounds.extend(nestedItem.coordinates.split(", ").reverse()));
});
dispatch({type: "UPDATE_INPUT", payload: {field: "mapBounds", value: newMapBounds}});
}
useEffect(() => {
mapRef.current.leafletElement.fitBounds(input.mapBounds);
},[input.mapBounds])
useEffect(() => {
mapRef.current.leafletElement.invalidateSize()
},[input.areaCIsBig])
//this is needed to let the map adjust to its changed container size by loading more tiles and panning
mapRef.current.leafletElement.invalidateSize();
},[input.bigTileArea])
return (
<>
......@@ -52,7 +70,7 @@ export const OurMap = (props) => {
<h3 className={classes.h3}>{t('Map')}</h3>
</Grid>
<Grid item xs={5}>
<FormLabel>{t('Turn on/off marker clustering')}
<FormLabel>{t('Cluster nearby markers')}
<Tooltip title="Switch between showing individual markers or clustered circles." arrow placement="right-start">
<Switch
name="drawBBox"
......@@ -65,10 +83,10 @@ export const OurMap = (props) => {
</Grid>
<Grid item xs={5}>
<FormLabel
onClick={() => extendMapBounds()}
onClick={() => resetMapBounds()}
style={{cursor: "pointer"}}
>
{`${t('Resize map to show all markers')}\t`}
{`${t('Resize map on markers')}\t`}
<Tooltip title="Automatically adjust the size of the map so all markers are visible." arrow placement="right">
<MapIcon/>
</Tooltip>
......@@ -82,7 +100,7 @@ export const OurMap = (props) => {
//center={input.mapCenter}
bounds={input.mapBounds}
zoom={input.zoomLevel}
minZoom={2}
minZoom={1}
zoomSnap={0.5}
onClick={(event) => {
if (input.drawBBox && (!(/-?\d{1,2}\.\d+,-?\d{1,3}\.\d+/.test(input.boundingBoxCorner1)) || !(/-?\d{1,2}\.\d+,-?\d{1,3}\.\d+/.test(input.boundingBoxCorner2)))) {
......@@ -116,6 +134,30 @@ export const OurMap = (props) => {
fillOpacity={0.05}
/>}
{/* Polygons */}
{data?.map((entity, index) => {
//for some queries the polygon data is located inside of 'spatial'
const polygonData = entity?.spatial ? entity?.spatial[0]?.polygon : entity?.polygon;
return (
//because Leaflet's Polygon wants each of the coordinate pairs flipped compared to how they
// are in iDAI.gazetteer, it seems easier to just give Leaflet GeoJSON objects
polygonData && <GeoJSON
key={index}
data={{
"type": "MultiPolygon",
"coordinates": polygonData
}}
>
{/*TODO: this is just to test it works, in actuality ReturnPopup should get more props */}
<ReturnPopup
item={entity}
openPopup={input.selectedMarker === index}
/>
</GeoJSON>
)
}
)}
{/* Markers */}
{/*TODO: find a way to use marker clustering while still being able to open popups inside cluster; double check that the numbers for disableClusteringAtZoom are okay*/}
{input.clusterMarkers
......@@ -123,76 +165,37 @@ export const OurMap = (props) => {
<MarkerClusterGroup
disableClusteringAtZoom={input.clusterMarkers ? 20 : 1}
>
{renderingConditionRelatedObjects
&& mapDataContext.entity.spatial
&& <CreateMarkers
data={mapDataContext.entity.spatial}
selectedMarker={input.selectedMarker}
handleRelatedObjects={handleRelatedObjects}
showRelatedObjects={input.showRelatedObjects}
/>}
{renderingConditionRelatedObjects
&& mapDataContext.entity.related
&& <CreateMarkers
data={mapDataContext.entity.related}
selectedMarker={input.selectedMarker}
handleRelatedObjects={handleRelatedObjects}
showRelatedObjects={input.showRelatedObjects}
//opacity={0.5}
/>}
{renderingConditionObjects
&& <CreateMarkers
data={mapDataObjects.entitiesMultiFilter}
selectedMarker={input.selectedMarker}
handleRelatedObjects={handleRelatedObjects}
showRelatedObjects={input.showRelatedObjects}
/>}
{renderingConditionSitesByRegion
&& <CreateMarkers
data={mapDataSitesByRegion.sitesByRegion}
{<CreateMarkers
data={markers}
selectedMarker={input.selectedMarker}
handleRelatedObjects={dataType.handler === true && handleRelatedObjects}
showRelatedObjects={dataType.handler === true && input.showRelatedObjects}
/>}
{renderingConditionSites
{dataType.type === "related"
&& <CreateMarkers
data={mapDataArchaeoSites.archaeologicalSites}
data={data.related}
selectedMarker={input.selectedMarker}
handleRelatedObjects={dataType.handler === true && handleRelatedObjects}
showRelatedObjects={dataType.handler === true && input.showRelatedObjects}
opacity={0.5}
/>}
</MarkerClusterGroup>
)
: (<div>
{renderingConditionRelatedObjects
&& mapDataContext.entity.spatial
&& <CreateMarkers
data={mapDataContext.entity.spatial}
selectedMarker={input.selectedMarker}
handleRelatedObjects={handleRelatedObjects}
showRelatedObjects={input.showRelatedObjects}
/>}
{renderingConditionRelatedObjects
&& mapDataContext.entity.related
&& <CreateMarkers
data={mapDataContext.entity.related}
selectedMarker={input.selectedMarker}
handleRelatedObjects={handleRelatedObjects}
showRelatedObjects={input.showRelatedObjects}
//opacity={0.5}
/>}
{renderingConditionObjects
&& <CreateMarkers
data={mapDataObjects.entitiesMultiFilter}
selectedMarker={input.selectedMarker}
handleRelatedObjects={handleRelatedObjects}
showRelatedObjects={input.showRelatedObjects}
/>}
{renderingConditionSitesByRegion
&& <CreateMarkers
data={mapDataSitesByRegion.sitesByRegion}
: (
<div>
{<CreateMarkers
data={markers}
selectedMarker={input.selectedMarker}
handleRelatedObjects={dataType.handler === true && handleRelatedObjects}
showRelatedObjects={dataType.handler === true && input.showRelatedObjects}
/>}
{renderingConditionSites
{dataType.type === "related"
&& <CreateMarkers
data={mapDataArchaeoSites.archaeologicalSites}
data={data.related}
selectedMarker={input.selectedMarker}
handleRelatedObjects={dataType.handler === true && handleRelatedObjects}
showRelatedObjects={dataType.handler === true && input.showRelatedObjects}
opacity={0.5}
/>}
</div>
)
......
/*TODO: fit to whatever our colorscheme will be, could be different colors or gradient for small/medium/large clusters*/
.marker-cluster-small {
background-color: #49afa5 !important;
}
.marker-cluster-small div {
background-color: #1c9489 !important;
color: #fff !important;
}
.marker-cluster-medium {
background-color: #49afa5 !important;
}
.marker-cluster-medium div {
background-color: #1c9489 !important;
color: #fff !important;
}
.marker-cluster-large {
background-color: #49afa5 !important;
}
.marker-cluster-large div {
background-color: #1c9489 !important;
color: #fff !important;
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment