Skip to content
Open
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
26 changes: 11 additions & 15 deletions src/rule/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,25 @@ import CheapRuler from 'cheap-ruler';
import type { MapEntity } from '../entities/entity';
import { ClusterCache } from '../entities/ClusterCache';
import * as Rules from './rules';
import {
FIRE_BUFFER_IN_METER
} from '../../SETTINGS';
import { FIRE_BUFFER_IN_METER } from '../../SETTINGS';

export const clusterCache = new ClusterCache(); // instantiate here and use it as a global cache when calculating clusters
export const ruler = new CheapRuler(57.5, 'meters');
export enum Severity {
None = 0,
Low = 1,
Medium = 2,
High = 3
High = 3,
}

export class Rule {
private _severity: Severity;
private _triggered: boolean;
private _callback: (entity: MapEntity) => { triggered: boolean; shortMessage?: string; message?: string };

private _callback: (
entity: MapEntity,
ruleMessage: string,
) => { triggered: boolean; shortMessage?: string; message?: string };

public message: string;
public shortMessage: string;

Expand All @@ -34,7 +35,7 @@ export class Rule {
}

public checkRule(entity: MapEntity) {
const result = this._callback(entity);
const result = this._callback(entity, this.message);
this._triggered = result.triggered;
if (result.shortMessage) this.shortMessage = result.shortMessage;
if (result.message) this.message = result.message;
Expand Down Expand Up @@ -97,7 +98,9 @@ export function generateRulesForEditor(groups: any, placementLayers: any): () =>
placementLayers,
Severity.High,
'Too large/close to others!',
'For fire safety, we need to add a bit of open space (' + FIRE_BUFFER_IN_METER + 'm2) between these camps (or if not next to any camps, this camp simply too big)',
'For fire safety, we need to add a bit of open space (' +
FIRE_BUFFER_IN_METER +
'm2) between these camps (or if not next to any camps, this camp simply too big)',
),
Rules.isNotInsideBoundaries(
groups.area,
Expand Down Expand Up @@ -131,13 +134,6 @@ export function generateRulesForEditor(groups: any, placementLayers: any): () =>
'Close to the sanctuary',
'This area is in the viscinity of the sanctuary, please be mindful of what energy your camp is releasing and how it may effect the santuarcy',
),
// Special notification when on the western meadow
Rules.isOverlappingOrContained(
groups.redsoundzone,
Severity.Low,
'In the western meadow',
"You're in the western meadow, please be extra careful of keeping the land in good condition and do not put your overnight camp here unless necessary, public dreams are prefered",
),
];
}

Expand Down
64 changes: 38 additions & 26 deletions src/rule/rules/isOverlappingOrContained.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,48 @@
import * as Turf from '@turf/turf';
import { Severity, Rule } from '../index';

export const isOverlappingOrContained = (
layerGroup: any,
severity: Severity,
shortMsg: string,
message: string
) => new Rule(severity, shortMsg, message, (entity) => {
let geoJson = entity.toGeoJSON();
let overlap = false;
export const isOverlappingOrContained = (layerGroup: any, severity: Severity, shortMsg: string, message: string) =>
new Rule(severity, shortMsg, message, (entity, ruleMessage) => {
let geoJson = entity.toGeoJSON();
let overlap = false;

layerGroup.eachLayer((layer) => {
//@ts-ignore
let otherGeoJson = layer.toGeoJSON();
if (!layerGroup) {
console.warn('No layer group provided in isOverlappingOrContained:', { ruleMessage, entity });
return { triggered: false };
}

layerGroup.eachLayer((layer) => {
//@ts-ignore
let otherGeoJson = layer.toGeoJSON();

//Loop through all features if it is a feature collection
if (otherGeoJson.features) {
for (let i = 0; i < otherGeoJson.features.length; i++) {
if (Turf.booleanOverlap(geoJson, otherGeoJson.features[i]) ||
Turf.booleanContains(otherGeoJson.features[i], geoJson)) {
//Loop through all features if it is a feature collection
if (otherGeoJson.features) {
for (let i = 0; i < otherGeoJson.features.length; i++) {
if (
Turf.booleanOverlap(geoJson, otherGeoJson.features[i]) ||
Turf.booleanContains(otherGeoJson.features[i], geoJson)
) {
overlap = true;
return; // Break out of the inner loop
}
}
} else if (geoJson.geometry.type === otherGeoJson.geometry.type) {
if (Turf.booleanOverlap(geoJson, otherGeoJson) || Turf.booleanContains(otherGeoJson, geoJson)) {
overlap = true;
return; // Break out of the inner loop
return; // Break out of the loop once an overlap is found
}
} else {
console.warn('Mismatched types in isOverlappingOrContained:', {
ruleMessage,
geoJson,
otherGeoJson,
});
}
} else if (Turf.booleanOverlap(geoJson, otherGeoJson) || Turf.booleanContains(otherGeoJson, geoJson)) {
overlap = true;
}

if (overlap) {
return; // Break out of the loop once an overlap is found
}
});
if (overlap) {
return; // Break out of the loop once an overlap is found
}
});

return { triggered: overlap };
});
return { triggered: overlap };
});