Skip to content

Commit

Permalink
Merge pull request #194 from hotosm/develop
Browse files Browse the repository at this point in the history
Production release
  • Loading branch information
nrjadkry committed Sep 5, 2024
2 parents d6efa9e + f5ae21e commit 7b69c85
Show file tree
Hide file tree
Showing 26 changed files with 534 additions and 245 deletions.
55 changes: 32 additions & 23 deletions src/backend/app/tasks/splitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,30 +151,39 @@ def splitBySquare(self, meters: int) -> FeatureCollection:
polygons.append(clipped_polygon)

for small_polygon in small_polygons:
adjacent_polygons = [
large_polygon
for large_polygon in polygons
if small_polygon.touches(large_polygon)
]
if adjacent_polygons:
# Get the adjacent polygon with the minimum area
nearest_small_polygon = min(adjacent_polygons, key=lambda p: p.area)

# Merge the small polygon with the nearest large polygon
merged_polygon = unary_union([small_polygon, nearest_small_polygon])

if merged_polygon.geom_type == "MultiPolygon":
# TODO we need merge Multipolygon into single polygon later....
log.warning("Found MultiPolygon, converting to simple polygon...")
while True:
adjacent_polygons = [
large_polygon
for large_polygon in polygons
if small_polygon.touches(large_polygon)
]
if adjacent_polygons:
# Get the adjacent polygon with the minimum area
nearest_polygon = min(adjacent_polygons, key=lambda p: p.area)

# Merge the small polygon with the nearest large polygon
merged_polygon = unary_union([small_polygon, nearest_polygon])

if merged_polygon.geom_type == "MultiPolygon":
# Handle MultiPolygon by adding the original small polygon back
log.warning(
"Found MultiPolygon, adding original small polygon..."
)
polygons.append(small_polygon)
break

# Remove both the small polygon and the nearest large polygon
polygons.remove(nearest_polygon)
small_polygon = merged_polygon

# Check if the merged polygon is greater than the area threshold
if small_polygon.area >= area_threshold:
polygons.append(small_polygon)
break
else:
# If no adjacent polygon is found, add the small polygon as is
polygons.append(small_polygon)
# Option 1: Convert to convex hull (simple polygon)
# merged_polygon = merged_polygon.convex_hull
# Remove both the small polygon and the nearest large polygon
polygons.remove(nearest_small_polygon)
polygons.append(merged_polygon)
else:
# If no adjacent polygon is found, add the small polygon as is
polygons.append(small_polygon)
break

merged_geojson = FeatureCollection(
[Feature(geometry=mapping(p)) for p in polygons]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ const CreateprojectLayout = () => {
const measurementType = useTypedSelector(
state => state.createproject.measurementType,
);
const projectImage = useTypedSelector(
state => state.createproject.projectMapImage,
);
const capturedProjectMap = useTypedSelector(
state => state.createproject.capturedProjectMap,
);

const initialState: FieldValues = {
name: '',
Expand Down Expand Up @@ -202,6 +208,7 @@ const CreateprojectLayout = () => {
}

if (activeStep === 4 && !splitGeojson) return;

if (activeStep !== 5) {
dispatch(setCreateProjectState({ activeStep: activeStep + 1 }));
return;
Expand All @@ -225,6 +232,8 @@ const CreateprojectLayout = () => {
// make form data with value JSON stringify to combine value on single json / form data with only 2 keys (backend didn't found project_info on non-stringified data)
const formData = new FormData();
formData.append('project_info', JSON.stringify({ ...refactoredData }));
formData.append('image', projectImage.projectMapImage);

if (isTerrainFollow) {
formData.append('dem', data?.dem?.[0]?.file);
}
Expand Down Expand Up @@ -265,7 +274,8 @@ const CreateprojectLayout = () => {
className="!naxatw-bg-red !naxatw-text-white"
rightIcon="chevron_right"
withLoader
isLoading={isLoading || isCreatingProject}
isLoading={isLoading || isCreatingProject || !capturedProjectMap}
disabled={isLoading || isCreatingProject || !capturedProjectMap}
>
{activeStep === 5 ? 'Save' : 'Next'}
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { contributionsInfo } from '@Constants/createProject';

export default function Contributions() {
return (
<div className="naxatw-px-10 naxatw-py-5">
<p className="naxatw-text-body-btn">Conditions for Contributions</p>
<p className="naxatw-mt-2 naxatw-text-body-md">
Fill in your project basic information such as name, description,
hashtag, etc.
</p>
return contributionsInfo?.map(info => (
<div className="naxatw-px-10 naxatw-py-5" key={info.key}>
<p className="naxatw-text-body-btn">{info.key}</p>
<p className="naxatw-mt-2 naxatw-text-body-md">{info.description}</p>
</div>
);
));
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { DefineAOIInfo } from '@Constants/createProject';

export default function DefineAOI() {
return (
<div className="naxatw-px-10 naxatw-py-5">
<p className="naxatw-text-body-btn">Define Area Of Interest (AOI)</p>
<p className="naxatw-mt-2 naxatw-text-body-md">
Fill in your project basic information such as name, description,
hashtag, etc.
</p>
return DefineAOIInfo?.map(info => (
<div className="naxatw-px-2 naxatw-py-2" key={info.key}>
<p className="naxatw-text-body-btn">{info.key}</p>
<p className="naxatw-py-1 naxatw-text-body-md">{info.description}</p>
</div>
);
));
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export default function GenerateTask() {
return (
<div className="naxatw-px-10 naxatw-py-5">
<p className="naxatw-text-body-btn">Conditions for Contributions</p>
<p className="naxatw-text-body-btn">Generate task</p>
<p className="naxatw-mt-2 naxatw-text-body-md">
Fill in your project basic information such as name, description,
hashtag, etc.
Split the task into smaller chunks based on the given dimensions to
ensure more efficient and precise data collection and analysis.
</p>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import { useTypedSelector } from '@Store/hooks';
import { FlexColumn, FlexRow } from '@Components/common/Layouts';
import { keyParamsDescriptions } from '@Constants/createProject';
import {
keyParametersInfo,
keyParamsDescriptions,
} from '@Constants/createProject';

export default function KeyParameters() {
const keyParamOption = useTypedSelector(
state => state.createproject.keyParamOption,
);

return (
<>
<div className="scrollbar naxatw-max-h-[65vh] naxatw-overflow-y-auto naxatw-px-2">
{keyParamOption === 'basic' ? (
<div className="naxatw-animate-fade-up naxatw-p-5">
<p className="naxatw-text-body-btn">
Ground Sampling Distance (meter)
</p>
<p className="naxatw-mt-2 naxatw-text-body-md">
Fill in your project basic information such as name, description,
hashtag, etc.
</p>
</div>
keyParametersInfo?.map(info => (
<div className="naxatw-animate-fade-up naxatw-py-2" key={info.key}>
<p className="naxatw-text-body-btn">{info.key}</p>
<p className="naxatw-py-1 naxatw-text-body-md">
{info.description}
</p>
</div>
))
) : (
<FlexColumn gap={2} className="naxatw-animate-fade-up">
{keyParamsDescriptions.map(desc => (
Expand All @@ -31,6 +34,6 @@ export default function KeyParameters() {
))}
</FlexColumn>
)}
</>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import useDrawTool from '@Components/common/MapLibreComponents/useDrawTool';
import { drawStyles } from '@Constants/map';
import { setCreateProjectState } from '@Store/actions/createproject';
import hasErrorBoundary from '@Utils/hasErrorBoundary';
import BaseLayerSwitcherUI from '@Components/common/BaseLayerSwitcher';
import LocateUser from '@Components/common/MapLibreComponents/LocateUser';

const MapSection = ({
onResetButtonClick,
Expand Down Expand Up @@ -104,6 +106,9 @@ const MapSection = ({
position: 'relative',
}}
>
<BaseLayerSwitcherUI />
<LocateUser isMapLoaded={isMapLoaded} />

{(drawNoFlyZoneEnable || drawProjectAreaEnable) && (
<div className="naxatw-absolute naxatw-right-[calc(50%_-_75px)] naxatw-top-2 naxatw-z-50 naxatw-flex naxatw-h-9 naxatw-w-[150px] naxatw-rounded-lg naxatw-bg-white">
<div className="naxatw-flex naxatw-w-full naxatw-items-center naxatw-justify-evenly">
Expand Down Expand Up @@ -173,8 +178,6 @@ const MapSection = ({
},
}}
/>

<BaseLayerSwitcher />
</MapContainer>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect } from 'react';
import { useCallback, useEffect } from 'react';
import { useTypedSelector } from '@Store/hooks';
import { LngLatBoundsLike, Map } from 'maplibre-gl';
import { useMapLibreGLMap } from '@Components/common/MapLibreComponents';
Expand All @@ -9,13 +9,20 @@ import { GeojsonType } from '@Components/common/MapLibreComponents/types';
import getBbox from '@turf/bbox';
import { FeatureCollection } from 'geojson';
import hasErrorBoundary from '@Utils/hasErrorBoundary';
import { useTypedDispatch } from '@UserModule/store/hooks';
import {
saveProjectImageFile,
setCreateProjectState,
} from '@Store/actions/createproject';

const MapSection = () => {
const dispatch = useTypedDispatch();
const { map, isMapLoaded } = useMapLibreGLMap({
mapOptions: {
zoom: 5,
center: [84.124, 28.3949],
maxZoom: 19,
preserveDrawingBuffer: true,
},
disableRotation: true,
});
Expand All @@ -26,13 +33,50 @@ const MapSection = () => {
const splitGeojson = useTypedSelector(
state => state.createproject.splitGeojson,
);
const capturedProjectMap = useTypedSelector(
state => state.createproject.capturedProjectMap,
);

useEffect(() => {
if (!projectArea) return;
const bbox = getBbox(projectArea as FeatureCollection);
map?.fitBounds(bbox as LngLatBoundsLike, { padding: 25 });
}, [map, projectArea]);

// eslint-disable-next-line no-unused-vars
const takeScreenshot = useCallback(async () => {
if (!map || !isMapLoaded || !splitGeojson) return;
// const data = map.getCanvas().toDataURL('image/jpeg', 0.95);
map.getCanvas().toBlob(
(blob: any) => {
const file = new File([blob], 'project.png', { type: blob.type });
dispatch(
saveProjectImageFile({
projectMapImage: file,
}),
);
dispatch(
setCreateProjectState({
capturedProjectMap: true,
}),
);
},
'image/png',
0.95,
);
}, [map, dispatch, isMapLoaded, splitGeojson]);

useEffect(() => {
if (!map || !isMapLoaded || !splitGeojson || capturedProjectMap)
return () => {};
// wait 1sec for split geojson is loaded and visible on map and capture
const captureTimeout = setTimeout(() => {
takeScreenshot();
}, 1000);

return () => clearTimeout(captureTimeout);
}, [map, takeScreenshot, isMapLoaded, splitGeojson, capturedProjectMap]);

return (
<MapContainer
map={map}
Expand All @@ -42,6 +86,7 @@ const MapSection = () => {
height: '448px',
}}
>
<BaseLayerSwitcher />
{!splitGeojson && (
<VectorLayer
map={map as Map}
Expand Down Expand Up @@ -69,12 +114,24 @@ const MapSection = () => {
type: 'fill',
paint: {
'fill-color': '#328ffd',
'fill-outline-color': '#D33A38',
'fill-opacity': 0.2,
},
}}
/>
<BaseLayerSwitcher />
<VectorLayer
map={map as Map}
isMapLoaded={isMapLoaded}
id="split-area-outline"
geojson={splitGeojson as GeojsonType}
visibleOnMap={!!splitGeojson}
layerOptions={{
type: 'line',
paint: {
'line-color': '#D33A38',
'line-width': 1,
},
}}
/>
</MapContainer>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ export default function GenerateTask({ formProps }: { formProps: any }) {
className="naxatw-mt-4 naxatw-bg-red"
onClick={() => {
if (!projectArea) return;
dispatch(
setCreateProjectState({
splitGeojson: null,
capturedProjectMap: false,
}),
);
mutate(payload);
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ import PreviewImage from './PreviewImage';

const ImageBoxPopOver = () => {
const dispatch = useTypedDispatch();
const { projectId, taskId } = useParams();

// const { taskId, projectId } = useParams();
const pathname = window.location.pathname?.split('/');
const projectId = pathname?.[2];
const taskId = pathname?.[4];

const uploadedFilesNumber = useRef(0);
const [imageObject, setImageObject] = useState<any[]>([]);
Expand Down
Loading

0 comments on commit 7b69c85

Please sign in to comment.