Skip to content

Instantly share code, notes, and snippets.

@bchilcott
Created September 8, 2023 20:29
Show Gist options
  • Save bchilcott/9d7c7d133a7a001a489d7ad7871765f4 to your computer and use it in GitHub Desktop.
Save bchilcott/9d7c7d133a7a001a489d7ad7871765f4 to your computer and use it in GitHub Desktop.
TS Pogging
import { useEffect, useRef } from 'react';
import { FeatureModel } from '@luciad/ria/model/feature/FeatureModel.js';
import { FeatureLayer } from '@luciad/ria/view/feature/FeatureLayer.js';
import { MemoryStore } from '@luciad/ria/model/store/MemoryStore.js';
import { useMap } from './MapContext';
import { Feature } from '@luciad/ria/model/feature/Feature.js';
import { CoordinateReference } from '@luciad/ria/reference/CoordinateReference.js';
import { Shape } from '@luciad/ria/shape/Shape.js';
type FeatureMap<S extends Shape> = Map<string | number, Feature<S>>;
export type PolylineMap = Map<string | number, [number, number][]>;
export default function createShapeLayerComponent<S extends Shape, D>(
createFeature: (reference: CoordinateReference, shapeData: D) => S
) {
return ({ shapes }: { shapes: Map<string | number, D> }) => {
const map = useMap();
const layerRef = useRef<FeatureLayer | null>(null);
const featuresMapRef = useRef<FeatureMap<S>>(new Map());
useEffect(() => {
if (!map) return;
if (!layerRef.current) {
const store = new MemoryStore<Feature<S>>();
const model = new FeatureModel(store);
const layer = new FeatureLayer(model);
map.layerTree.addChild(layer, 'top');
layerRef.current = layer;
}
shapes.forEach((shapeData, id) => {
const existingFeature = featuresMapRef.current.get(id);
if (existingFeature) {
const updatedShape = createFeature(map.reference, shapeData);
existingFeature.shape = updatedShape;
layerRef.current?.model.put(existingFeature);
} else {
const newShape = createFeature(map.reference, shapeData);
const newFeature = new Feature(newShape);
layerRef.current?.model.add(newFeature);
featuresMapRef.current.set(id, newFeature);
}
});
featuresMapRef.current.forEach((feature, fid) => {
if (!shapes.has(fid)) {
layerRef.current!.model.remove(feature.id);
featuresMapRef.current.delete(fid);
}
});
}, [map, shapes]);
useEffect(() => {
return () => {
if (layerRef.current) {
map && map.layerTree.removeChild(layerRef.current);
layerRef.current = null;
}
};
}, [map]);
return null;
};
}
const PolylineLayer = createShapeLayerComponent(createPolyline);
const PolygonLayer = createShapeLayerComponent(createPolygon);
const PointLayer = createShapeLayerComponent(createPoint);
// etc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment