Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add map popups to data extract geometries #1266

Merged
merged 4 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type asyncPopupPropType = {
closePopup?: any;
loading?: boolean;
showOnHover?: string;
primaryKey: string;
};

function hasKey(obj, key) {
Expand All @@ -33,6 +34,7 @@ const AsyncPopup = ({
closePopup = false,
loading = false,
showOnHover = 'click',
primaryKey = 'uid',
}: asyncPopupPropType) => {
const popupRef = useRef<any>(null);
const popupCloserRef = useRef<any>(null);
Expand Down Expand Up @@ -111,8 +113,11 @@ const AsyncPopup = ({
return;
}
const featureProperties = features[0].getProperties();
const { uid } = featureProperties;
if (layerIds.includes(uid) || (hasKey(featureProperties, 'uid') && featureProperties?.uid)) {
const { [primaryKey]: primaryKeyValue } = featureProperties;
if (
layerIds.includes(primaryKeyValue) ||
(hasKey(featureProperties, primaryKey) && featureProperties?.[primaryKey])
) {
setProperties(featureProperties);
setCoordinates(coordinate);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,6 @@ const VectorLayer = ({
if (feature) {
// Extract properties
const properties = feature.getProperties();
// Remove geometry key if properties are present
// If no properties are set, the feature uid is included
if (!('uid' in properties)) {
const { geometry, ...restProperties } = properties;
mapOnClick(restProperties, feature);
return;
}
mapOnClick(properties, feature);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Button from '@/components/common/Button';
import AssetModules from '@/shared/AssetModules.js';
import CoreModules from '@/shared/CoreModules.js';
import { TaskCardSkeletonLoader } from '@/components/ProjectSubmissions/ProjectSubmissionsSkeletonLoader';
import { taskInfoType } from '@/models/submission/submissionModel';
import { taskInfoType } from '@/models/task/taskModel';
import { useSearchParams } from 'react-router-dom';

const TaskSubmissions = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { basicGeojsonTemplate } from '@/utilities/mapUtils';
import TaskSubmissionsMapLegend from '@/components/ProjectSubmissions/TaskSubmissionsMapLegend';
import Accordion from '@/components/common/Accordion';
import AsyncPopup from '@/components/MapComponent/OpenLayersComponent/AsyncPopup/AsyncPopup';
import { taskFeaturePropertyType, taskInfoType } from '@/models/submission/submissionModel';
import { taskFeaturePropertyType, taskInfoType } from '@/models/task/taskModel';
import { isValidUrl } from '@/utilfunctions/urlChecker';

export const defaultStyles = {
Expand Down
11 changes: 11 additions & 0 deletions src/frontend/src/models/project/projectModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type osmTag = {
string: string;
};

export type dataExtractPropertyType = {
osm_id: number;
tags: Array<{ [key: string]: string }>;
timestamp: Date;
changeset: number;
version: number;
};
42 changes: 35 additions & 7 deletions src/frontend/src/views/ProjectDetailsV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import getTaskStatusStyle from '@/utilfunctions/getTaskStatusStyle';
import { defaultStyles } from '@/components/MapComponent/OpenLayersComponent/helpers/styleUtils';
import MapLegends from '@/components/MapLegends';
import Accordion from '@/components/common/Accordion';
import AsyncPopup from '@/components/MapComponent/OpenLayersComponent/AsyncPopup/AsyncPopup';
import { Geolocation } from '@capacitor/geolocation';
import { Icon, Style } from 'ol/style';
import { Motion } from '@capacitor/motion';
Expand All @@ -40,6 +41,7 @@ import { CommonActions } from '@/store/slices/CommonSlice';
import Button from '@/components/common/Button';
import ProjectInfo from '@/components/ProjectDetailsV2/ProjectInfo';
import useOutsideClick from '@/hooks/useOutsideClick';
import { dataExtractPropertyType } from '@/models/project/projectModel';
import { isValidUrl } from '@/utilfunctions/urlChecker';

const Home = () => {
Expand All @@ -49,7 +51,6 @@ const Home = () => {
const { windowSize, type } = WindowDimension();
const [divRef, toggle, handleToggle] = useOutsideClick();

const [taskId, setTaskId] = useState();
const [mainView, setView] = useState();
const [featuresLayer, setFeaturesLayer] = useState();
const [toggleGenerateModal, setToggleGenerateModal] = useState(false);
Expand All @@ -65,6 +66,7 @@ const Home = () => {
const defaultTheme = CoreModules.useAppSelector((state) => state.theme.hotTheme);
const state = CoreModules.useAppSelector((state) => state.project);
const projectInfo = CoreModules.useAppSelector((state) => state.home.selectedProject);
const selectedTask = CoreModules.useAppSelector((state) => state.task.selectedTask);
const stateSnackBar = CoreModules.useAppSelector((state) => state.home.snackbar);
const mobileFooterSelection = CoreModules.useAppSelector((state) => state.project.mobileFooterSelection);
const mapTheme = CoreModules.useAppSelector((state) => state.theme.hotTheme);
Expand Down Expand Up @@ -135,8 +137,31 @@ const Home = () => {
dispatch(GetProjectDashboard(`${import.meta.env.VITE_API_URL}/projects/project_dashboard/${decodedId}`));
}, []);

// TasksLayer(map, mainView, featuresLayer);
const projectClickOnMap = (properties, feature) => {
const dataExtractDataPopup = (properties: dataExtractPropertyType) => {
return (
<div className="fmtm-h-fit">
<h2 className="fmtm-border-b-[2px] fmtm-border-primaryRed fmtm-w-fit fmtm-pr-1">
OSM ID: #{properties?.osm_id}
</h2>
<div className="fmtm-flex fmtm-flex-col fmtm-gap-1 fmtm-mt-1">
<p>
Tags: <span className="fmtm-text-primaryRed">{properties?.tags}</span>
</p>
<p>
Timestamp: <span className="fmtm-text-primaryRed">{properties?.timestamp}</span>
</p>
<p>
Changeset: <span className="fmtm-text-primaryRed">{properties?.changeset}</span>
</p>
<p>
Version: <span className="fmtm-text-primaryRed">{properties?.version}</span>
</p>
</div>
</div>
);
};

const projectClickOnMapTask = (properties, feature) => {
setFeaturesLayer(feature, 'feature');
let extent = properties.geometry.getExtent();

Expand All @@ -147,7 +172,9 @@ const Home = () => {
block: 'center',
behavior: 'smooth',
});
setTaskId(properties.uid);

dispatch(CoreModules.TaskActions.SetSelectedTask(properties.uid));

dispatch(ProjectActions.ToggleTaskModalStatus(true));
if (windowSize.width < 768) {
map.getView().fit(extent, {
Expand Down Expand Up @@ -382,7 +409,7 @@ const Home = () => {
duration: 2000,
}}
layerProperties={{ name: 'project-area' }}
mapOnClick={projectClickOnMap}
mapOnClick={projectClickOnMapTask}
zoomToLayer
zIndex={5}
getTaskStatusStyle={(feature) => getTaskStatusStyle(feature, mapTheme)}
Expand All @@ -403,6 +430,7 @@ const Home = () => {
zIndex={5}
/>
)}
<AsyncPopup map={map} popupUI={dataExtractDataPopup} primaryKey={'osm_id'} />
{geolocationStatus && currentCoordinate?.latitude && currentCoordinate?.longitude && (
<VectorLayer
map={map}
Expand Down Expand Up @@ -485,11 +513,11 @@ const Home = () => {
</div>
{featuresLayer != undefined && (
<TaskSectionPopup
taskId={taskId}
taskId={selectedTask}
feature={featuresLayer}
body={
<div>
<DialogTaskActions map={map} view={mainView} feature={featuresLayer} taskId={taskId} />
<DialogTaskActions map={map} view={mainView} feature={featuresLayer} taskId={selectedTask} />
</div>
}
/>
Expand Down
Loading