Skip to content

Commit

Permalink
validation and minor bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
shyambhongle committed Dec 20, 2024
1 parent 8e70768 commit 483fda5
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 66 deletions.
2 changes: 1 addition & 1 deletion src/components/home/ProjectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ const ProjectModal = (props: Props) => {
)
try {
const parsedGeometry = JSON.parse(currentSiteData[0].geometry)
const newCoords = getRandomPointInPolygon(parsedGeometry.coordinates[0], 1)
const newCoords = getRandomPointInPolygon(parsedGeometry.coordinates[0])
const { geoJSON } = makeInterventionGeoJson('Point', [newCoords], 'sd')
const bounds = bbox(geoJSON)
dispatch(updateMapBounds({ bounds: bounds, key: 'DISPLAY_MAP' }))
Expand Down
2 changes: 1 addition & 1 deletion src/components/intervention/InterventionHeaderList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,6 @@ const styles = StyleSheet.create({
borderColor: Colors.GRAY_LIGHT,
borderRadius: 20,
borderWidth: 0.5,
marginRight:'1%'
marginRight:10
}
})
16 changes: 11 additions & 5 deletions src/screens/AddMeasurementView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ const AddMeasurement = () => {
const handleHeightChange = (text: string) => {
setHeightErrorMessage('');
const regex = /^(?!0*(\.0+)?$)(\d+(\.\d+)?|\.\d+)$/;
const isValid = regex.test(text)
const finalText = text.replace(/,/g, '.');
const isValid = regex.test(finalText)
// Ensure there is at most one decimal point
if (isValid) {
setHeight(text);
Expand All @@ -84,7 +85,8 @@ const AddMeasurement = () => {
const handleDiameterChange = (text: string) => {
setWidthErrorMessage('');
const regex = /^(?!0*(\.0+)?$)(\d+(\.\d+)?|\.\d+)$/;
const isValid = regex.test(text)
const finalText = text.replace(/,/g, '.');
const isValid = regex.test(finalText)
if (isValid) {
setWidth(text);
} else {
Expand All @@ -97,7 +99,9 @@ const AddMeasurement = () => {


const onSubmit = () => {
const validationObject = measurementValidation(height, width, isNonISUCountry);
const updatedHeight = height.replace(/,/g, '.');
const updatedWidth = width.replace(/,/g, '.');
const validationObject = measurementValidation(updatedHeight, updatedWidth, isNonISUCountry);
const { diameterErrorMessage, heightErrorMessage, isRatioCorrect } = validationObject;
setHeightErrorMessage(heightErrorMessage)
setWidthErrorMessage(diameterErrorMessage)
Expand Down Expand Up @@ -141,6 +145,8 @@ const AddMeasurement = () => {
}

const submitDetails = async () => {
const updatedHeight = height.replace(/,/g, '.');
const updatedWidth = width.replace(/,/g, '.');
const { lat, long, accuracy } = getUserLocation()
const treeDetails: SampleTree = {
tree_id: id,
Expand All @@ -156,11 +162,11 @@ const AddMeasurement = () => {
cdn_image_url: '',
specie_name: SampleTreeData.current_species.scientificName,
specie_diameter: getConvertedDiameter(
width,
updatedWidth,
isNonISUCountry
),
specie_height: getConvertedHeight(
height,
updatedHeight,
isNonISUCountry
),
tag_id: tagId,
Expand Down
2 changes: 1 addition & 1 deletion src/screens/InterventionFormView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ const InterventionFormView = () => {
el => el.id === registerForm.site_id,
)
const parsedGeometry = JSON.parse(currentSiteData[0].geometry)
const newCoords = getRandomPointInPolygon(parsedGeometry.coordinates[0], 1)
const newCoords = getRandomPointInPolygon(parsedGeometry.coordinates[0])
return [newCoords]
}

Expand Down
14 changes: 8 additions & 6 deletions src/screens/ReviewTreeDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,12 @@ const ReviewTreeDetails = () => {
let hasError = false;

const handleHeightValidation = () => {
const updatedHeight = openEditModal.value.replace(/,/g, '.');
const regex = /^(?!0*(\.0+)?$)(\d+(\.\d+)?|\.\d+)$/;
const isValid = regex.test(openEditModal.value)
const isValid = regex.test(updatedHeight)
if (isValid) {
const validationObject = measurementValidation(
openEditModal.value,
updatedHeight,
treeDetails.specie_diameter,
isNonISUCountry,
);
Expand All @@ -179,7 +180,7 @@ const ReviewTreeDetails = () => {
hasError = true
} else {
finalDetails.specie_height = getConvertedHeight(
Number(openEditModal.value),
Number(updatedHeight),
isNonISUCountry
)
}
Expand All @@ -192,12 +193,13 @@ const ReviewTreeDetails = () => {
};

const handleDiameterValidation = () => {
const updatedWidth = openEditModal.value.replace(/,/g, '.');
const regex = /^(?!0*(\.0+)?$)(\d+(\.\d+)?|\.\d+)$/;
const isValid = regex.test(openEditModal.value)
const isValid = regex.test(updatedWidth)
if (isValid) {
const validationObject = measurementValidation(
treeDetails.specie_height,
openEditModal.value,
updatedWidth,
isNonISUCountry,
);
setInputErrorMessage(validationObject.diameterErrorMessage);
Expand All @@ -209,7 +211,7 @@ const ReviewTreeDetails = () => {
hasError = true
} else {
finalDetails.specie_diameter = getConvertedDiameter(
Number(openEditModal.value),
Number(updatedWidth),
isNonISUCountry
)
}
Expand Down
23 changes: 15 additions & 8 deletions src/screens/TreeRemeasurementView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ const TreeRemeasurementView = () => {

const handleSkip = async () => {
setShowSkipModal(false)
const updatedHeight = height.replace(/,/g, '.');
const updatedWidth = width.replace(/,/g, '.');
const { lat, long } = getUserLocation()
const isWithin20m = isWithinRange(lat, long, treeDetails.latitude, treeDetails.longitude)
const param: History = {
Expand All @@ -143,11 +145,11 @@ const TreeRemeasurementView = () => {
imageUrl: imageUri,
cdnImageUrl: '',
diameter: isAlive ? getConvertedDiameter(
width,
updatedWidth,
isNonISUCountry,
) : treeDetails.specie_diameter,
height: isAlive ? getConvertedHeight(
height,
updatedHeight,
isNonISUCountry,
) : treeDetails.specie_height,
appMetadata: '',
Expand Down Expand Up @@ -193,11 +195,12 @@ const TreeRemeasurementView = () => {
const handleHeightChange = (text: string) => {
setHeightErrorMessage('');
const regex = /^(?!0*(\.0+)?$)(\d+(\.\d+)?|\.\d+)$/;
const isValid = regex.test(text)
const updatedHeight = text.replace(/,/g, '.');
const isValid = regex.test(updatedHeight)
// Ensure there is at most one decimal point
if (isValid) {
setHeight(text);
const convertedHeight = height ? getConvertedHeight(text, isNonISUCountry) : 0;
const convertedHeight = height ? getConvertedHeight(updatedHeight, isNonISUCountry) : 0;
if (convertedHeight < DBHInMeter) {
setDiameterLabel(i18next.t('label.measurement_basal_diameter'));
} else {
Expand All @@ -211,9 +214,10 @@ const TreeRemeasurementView = () => {
const handleDiameterChange = (text: string) => {
setWidthErrorMessage('');
const regex = /^(?!0*(\.0+)?$)(\d+(\.\d+)?|\.\d+)$/;
const isValid = regex.test(text)
const updatedWidth = text.replace(/,/g, '.');
const isValid = regex.test(updatedWidth)
if (isValid) {
setWidth(text);
setWidth(updatedWidth);
} else {
setWidthErrorMessage('Please provide the correct diameter.')
}
Expand Down Expand Up @@ -273,8 +277,11 @@ const TreeRemeasurementView = () => {
}

const submitHandler = async (gpsValidated?: boolean) => {
const finalHeight = height || treeDetails.specie_height
const finalWidth = width || treeDetails.specie_diameter
const updatedHeight = height.replace(/,/g, '.');
const updatedWidth = width.replace(/,/g, '.');

const finalHeight = updatedHeight || treeDetails.specie_height
const finalWidth = updatedWidth || treeDetails.specie_diameter
const { lat, long } = getUserLocation()
const isWithin20m = isWithinRange(lat, long, treeDetails.latitude, treeDetails.longitude)

Expand Down
79 changes: 35 additions & 44 deletions src/utils/helpers/generatePointInPolygon.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import seedrandom from 'seedrandom';


/**
* Generates a random point coordinate within a given polygon.
*
* @param {Array} polygon - An array of coordinate arrays representing the polygon.
* @param {number} index - An index to differentiate points for polygons with similar coordinates.
* @returns {Array} The random point coordinate [longitude, latitude].
*/
export const getRandomPointInPolygon = (polygon, index) => {
export const getRandomPointInPolygon = (polygon) => {
// Calculate the bounding box of the polygon
const bounds = polygon.reduce(
(prev, curr) => {
Expand All @@ -23,45 +20,39 @@ export const getRandomPointInPolygon = (polygon, index) => {
{ minLon: Infinity, maxLon: -Infinity, minLat: Infinity, maxLat: -Infinity }
);

// Create a seed based on the polygon's coordinates and the index
const seed = JSON.stringify(polygon) + index;
const rng = seedrandom(seed);

// Generate a random point within the bounding box
let randomPoint;
let isInPolygon = false;
while (!isInPolygon) {
const lon = bounds.minLon + rng() * (bounds.maxLon - bounds.minLon);
const lat = bounds.minLat + rng() * (bounds.maxLat - bounds.minLat);
randomPoint = [lon, lat];

// Check if the random point is within the polygon
isInPolygon = isPointInPolygon(randomPoint, polygon);
// Helper function to check if a point is inside the polygon
const isPointInPolygon = (point, polygon) => {
let inside = false;
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
const xi = polygon[i][0], yi = polygon[i][1];
const xj = polygon[j][0], yj = polygon[j][1];

const intersect = ((yi > point[1]) !== (yj > point[1]))
&& (point[0] < (xj - xi) * (point[1] - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};

// Generate random points until we find one inside the polygon
let attempts = 0;
const maxAttempts = 1000; // Prevent infinite loop

while (attempts < maxAttempts) {
const randomLon = bounds.minLon + Math.random() * (bounds.maxLon - bounds.minLon);
const randomLat = bounds.minLat + Math.random() * (bounds.maxLat - bounds.minLat);

if (isPointInPolygon([randomLon, randomLat], polygon)) {
return [randomLon, randomLat, 0]; // Adding 0 for elevation to match input format
}

attempts++;
}

return randomPoint;

// If we couldn't find a point after max attempts, return center of bounding box
return [
(bounds.minLon + bounds.maxLon) / 2,
(bounds.minLat + bounds.maxLat) / 2,
0
];
};

/**
* Checks if a point is within a given polygon.
*
* @param {Array} point - The point coordinate [longitude, latitude].
* @param {Array} polygon - An array of coordinate arrays representing the polygon.
* @returns {boolean} True if the point is within the polygon, false otherwise.
*/
function isPointInPolygon(point, polygon) {
const [x, y] = point;
let isInside = false;

for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
const [x1, y1] = polygon[i];
const [x2, y2] = polygon[j];

const intersect =
y1 > y !== y2 > y && x < ((x2 - x1) * (y - y1)) / (y2 - y1) + x1;

if (intersect) isInside = !isInside;
}

return isInside;
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ const getEntireSiteCheck = (data: any) => {
if (typeof publicData === 'object' && publicData !== null && !Array.isArray(publicData)) {
for (const key in publicData) {
if (key == 'isEntireSite') { // optional: ensure the property is not inherited
if (publicData[key] === 'false' || publicData[key] === false) {
return false
}
return true
}
}
Expand Down

0 comments on commit 483fda5

Please sign in to comment.