UNPKG

leaflet-polydraw

Version:

Advanced Leaflet plugin for freehand polygon drawing, with smart merging and powerful editing tools. Compatible with both Leaflet v1.x and v2.x.

249 lines 9.29 kB
import * as L from 'leaflet'; import { TurfHelper } from '../turf-helper'; import { PolygonInformationService } from '../polygon-information.service'; import type { Feature, Polygon, MultiPolygon } from 'geojson'; import type { PolydrawConfig, PolydrawPolygon, HistoryAction, LayerInteraction, PolygonStyleOverrides } from '../types/polydraw-interfaces'; import { ModeManager } from './mode-manager'; import { EventManager, PolydrawEvent, PolydrawEventCallback } from './event-manager'; import { PolygonInteractionManager } from './polygon-interaction-manager'; import type { LayerManager } from './layer-manager'; export interface MutationResult { success: boolean; featureGroups?: L.FeatureGroup[]; error?: string; } interface AddPolygonOptions { simplify?: boolean; noMerge?: boolean; mergeEditableOnly?: boolean; dynamicTolerance?: boolean; visualOptimizationLevel?: number; originalOptimizationLevel?: number; skipKinkProcessing?: boolean; targetLayerId?: string; layerColor?: string; featureId?: string; featureMetadata?: Record<string, unknown>; sourceFeatureIds?: string[]; featureInteractionOverride?: LayerInteraction; featureStyleOverrides?: PolygonStyleOverrides; featureCreatedAt?: string; featureLastModified?: string; } export interface MutationManagerDependencies { turfHelper: TurfHelper; polygonInformation: PolygonInformationService; map: L.Map; config: PolydrawConfig; modeManager: ModeManager; eventManager: EventManager; getFeatureGroups: () => L.FeatureGroup[]; saveHistoryState?: (action: HistoryAction) => void; layerManager?: LayerManager; } /** * PolygonMutationManager acts as a facade that coordinates between specialized managers. * It maintains the arrayOfFeatureGroups as the single source of truth and delegates * operations to the appropriate specialized managers. */ export declare class PolygonMutationManager { private turfHelper; private map; private config; private eventManager; private getFeatureGroups; private saveHistoryState?; private layerManager?; private geometryManager; private interactionManager; private readonly onDrawCancel; private readonly onPolygonUpdated; private readonly onMenuAction; private readonly onCheckIntersection; private readonly onSubtract; private readonly onPolygonDeleted; constructor(dependencies: MutationManagerDependencies); /** * Initialize the three specialized managers */ private initializeSpecializedManagers; /** * Set up event forwarding from specialized managers to facade */ private setupEventForwarding; dispose(): void; /** * Handle polygon modification from interaction manager */ private handlePolygonModified; /** * Handle menu actions from interaction manager */ private handleMenuAction; /** * Handle polygon menu action execution */ private executePolygonMenuAction; private normalizeMenuActionResult; private isPolygonFeature; private getBoundsForMenuAction; /** * Get the polygon interaction manager (for testing) */ get polygonInteractionManager(): PolygonInteractionManager; /** * Add event listener */ on<T extends PolydrawEvent>(event: T, callback: PolydrawEventCallback<T>): void; /** * Emit event to all listeners */ private emit; /** * Add a polygon with optional merging logic */ addPolygon(latlngs: Feature<Polygon | MultiPolygon>, options?: AddPolygonOptions): Promise<MutationResult>; private addPolygonWithMergeHandling; private preparePolygonsForAddition; /** * Subtract a polygon from existing polygons */ subtractPolygon(latlngs: Feature<Polygon | MultiPolygon>, options?: AddPolygonOptions): Promise<MutationResult>; /** * Create and add a polygon layer with all markers and interactions */ private addPolygonLayer; /** * Merge a polygon with existing intersecting polygons */ private mergePolygon; /** * Union multiple polygons together using geometry manager */ private unionPolygons; /** * Determine if intelligent merging should be allowed for a polygon * This checks if the polygon actually intersects with existing polygons */ private shouldAllowIntelligentMerge; /** * Check if a polygon is completely inside a hole of an existing polygon * This prevents incorrect merging when drawing polygons inside holes */ private isPolygonInsideExistingHole; /** * Normalize polygon coordinates to handle complex nested structures * This fixes the bug where markers are missing when drawing polygons inside holes */ private normalizePolygonCoordinates; /** * Create a polygon from GeoJSON feature */ private isPositionArrayofArrays; private isPosition; /** * Create a polygon from GeoJSON feature */ private getPolygon; private normalizeSinglePolygonFeature; /** * Internal method to add feature group to array */ private addFeatureGroupInternal; /** * Internal method to remove feature group from array and map */ private removeFeatureGroupInternal; /** * Get complete polygon GeoJSON including holes from a feature group */ private getCompletePolygonFromFeatureGroup; private getOptimizationMetadataFromFeatureGroup; private getFeatureMetadataStateFromFeatureGroup; private collectSourceFeatureIds; private resolvePrimaryFeatureMetadata; private resolvePrimaryFeatureInteractionOverride; private resolvePrimaryFeatureStyleOverrides; private cloneFeatureMetadata; private cloneStyleOverrides; private featureHasHoles; private setFeatureGroupMetadata; /** * Update marker draggable state */ updateMarkerDraggableState(): void; /** * Update all markers for edge deletion visual feedback */ updateAllMarkersForEdgeDeletion(showFeedback: boolean): void; /** * Set modifier key held state */ setModifierKeyHeld(isHeld: boolean): void; /** * Check if two polygons intersect (delegates to geometry manager) */ checkPolygonIntersection(polygon1: Feature<Polygon | MultiPolygon>, polygon2: Feature<Polygon | MultiPolygon>): boolean; /** * Get polygon center (delegates to geometry manager) */ getPolygonCenter(polygon: Feature<Polygon | MultiPolygon>): { lat: number; lng: number; } | null; /** * Get bounding box from polygon (delegates to geometry manager) */ getBoundingBox(polygon: Feature<Polygon | MultiPolygon>): { minLat: number; maxLat: number; minLng: number; maxLng: number; } | null; addMarker(latlngs: L.LatLngLiteral[], featureGroup: L.FeatureGroup, options?: { optimizationLevel?: number; originalOptimizationLevel?: number; }): void; addHoleMarker(latlngs: L.LatLngLiteral[], featureGroup: L.FeatureGroup): void; addEdgeClickListeners(polygon: L.Polygon, featureGroup: L.FeatureGroup): void; enablePolygonDragging(polygon: PolydrawPolygon, latlngs: Feature<Polygon | MultiPolygon>): void; getMarkerIndex(latlngs: L.LatLngLiteral[], position: L.LatLngLiteral): number; ensureMarkerSeparation(polygonLength: number, markers: { menu?: { index?: number; }; delete?: { index?: number; }; info?: { index?: number; }; }): { menu: number; delete: number; info: number; }; findAlternativeMarkerPosition(polygonLength: number, originalIndex: number, usedIndices: Set<number>): number; createDivIcon(processedClasses: string[]): L.DivIcon; getLatLngInfoString(latlng: L.LatLngLiteral): string; generateMenuMarkerPopup(latLngs: L.LatLngLiteral[], featureGroup: L.FeatureGroup): HTMLDivElement; getPolygonGeoJSONFromFeatureGroup(featureGroup: L.FeatureGroup): Feature<Polygon | MultiPolygon>; getTotalPolygonPerimeter(polygonGeoJSON: Feature<Polygon | MultiPolygon>): number; generateInfoMarkerPopup(area: number, perimeter: number): HTMLDivElement; onMarkerHoverForEdgeDeletion(marker: L.Marker, isHovering: boolean): void; highlightEdgeOnHover(edgePolyline: L.Polyline, isHovering: boolean): void; onEdgeClick(e: L.LeafletMouseEvent, edgePolyline: L.Polyline): void; removeFeatureGroup(featureGroup: L.FeatureGroup): void; /** * Clean up all resources associated with a feature group * This method ensures proper cleanup of event listeners and associated resources */ cleanupFeatureGroup(featureGroup: L.FeatureGroup): void; onPolygonMouseMove(e: L.LeafletMouseEvent): void; onPolygonMouseUp(e: L.LeafletMouseEvent): void; updatePolygonAfterDrag(polygon: L.Polygon): void; setSubtractVisualMode(polygon: L.Polygon, enabled: boolean): void; performModifierSubtract(draggedGeoJSON: Feature<Polygon | MultiPolygon>, originalFeatureGroup: L.FeatureGroup): void; } export {}; //# sourceMappingURL=polygon-mutation-manager.d.ts.map