Skip to content

Commit

Permalink
feat: support polyline and point on reearth/core (#606)
Browse files Browse the repository at this point in the history
  • Loading branch information
keiya01 committed Apr 11, 2023
1 parent 968a9dd commit abd9a3c
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 29 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
"axios": "1.2.2",
"cesium": "1.104.0",
"cesium-dnd": "1.1.0",
"cesium-mvt-imagery-provider": "1.2.4",
"cesium-mvt-imagery-provider": "^1.3.0",
"core-js": "3.27.1",
"crypto-js": "4.1.1",
"csv-parse": "5.3.3",
Expand Down
4 changes: 3 additions & 1 deletion src/core/engines/Cesium/Feature/Raster/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ function Raster({ isVisible, layer, property, evalFeature }: Props) {
export default memo(
Raster,
(prev, next) =>
// In Raster component, we only use polygon, so we only check polygon in layer props.
// In Raster component, we only use polygon, polyline and marker, so we only check polygon in layer props.
isEqual(extractSimpleLayer(prev.layer)?.polygon, extractSimpleLayer(next.layer)?.polygon) &&
isEqual(extractSimpleLayer(prev.layer)?.polyline, extractSimpleLayer(next.layer)?.polyline) &&
isEqual(extractSimpleLayer(prev.layer)?.marker, extractSimpleLayer(next.layer)?.marker) &&
isEqual(extractSimpleLayerData(prev.layer), extractSimpleLayerData(next.layer)) &&
isEqual(prev.property, next.property) &&
prev.isVisible === next.isVisible &&
Expand Down
151 changes: 128 additions & 23 deletions src/core/engines/Cesium/Feature/Raster/mvt.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { VectorTileFeature } from "@mapbox/vector-tile";
import type { Polygon, LineString, Point } from "@turf/turf";
import { ImageryLayerFeatureInfo } from "cesium";
import { MVTImageryProvider } from "cesium-mvt-imagery-provider";
import { useEffect, useMemo, useRef } from "react";

import type { ComputedFeature, Feature, PolygonAppearance } from "../../..";
import type {
ComputedFeature,
Feature,
PolygonAppearance,
Geometry,
PolylineAppearance,
MarkerAppearance,
} from "../../..";
import { usePick, extractSimpleLayer, generateIDWithMD5 } from "../utils";

import { useData, useImageryProvider } from "./hooks";
Expand All @@ -25,6 +33,8 @@ export const useMVT = ({

const layerSimple = extractSimpleLayer(layer);
const layerPolygonAppearance = usePick(layerSimple?.polygon, polygonAppearanceFields);
const layerPolylineAppearance = usePick(layerSimple?.polyline, polylineAppearanceFields);
const layerMarkerAppearance = usePick(layerSimple?.marker, markerAppearanceFields);

const updatedAt = useRef<number>();

Expand All @@ -51,28 +61,73 @@ export const useMVT = ({
if (cachedStyle) {
return cachedStyle;
}
const appearanceType = (() => {
switch (VectorTileFeature.types[mvtFeature.type]) {
case "Polygon":
return "polygon";
case "LineString":
return "polyline";
case "Point":
return "marker";
}
})();
const computedFeature = ((): ComputedFeature | void => {
const layer = cachedCalculatedLayerRef.current?.layer;
if (
layer?.type === "simple" &&
VectorTileFeature.types[mvtFeature.type] === "Polygon"
) {
const feature = makeFeatureFromPolygon("", mvtFeature, tile);
if (layer?.type !== "simple") {
return;
}
const feature = makeFeature("", mvtFeature, tile, appearanceType);
if (feature) {
return evalFeature?.(layer, feature);
}
})();

const polygon = computedFeature?.polygon;
const style = {
fillStyle:
(polygon?.fill ?? true) && (polygon?.show ?? true)
? polygon?.fillColor
: "rgba(0,0,0,0)", // hide the feature
strokeStyle:
polygon?.stroke && (polygon?.show ?? true) ? polygon?.strokeColor : "rgba(0,0,0,0)", // hide the feature
lineWidth: polygon?.strokeWidth,
lineJoin: polygon?.lineJoin,
};
const style = (() => {
if (appearanceType === "polygon") {
const polygon = computedFeature?.polygon;
return {
fillStyle:
(polygon?.fill ?? true) && (polygon?.show ?? true)
? polygon?.fillColor
: "rgba(0,0,0,0)", // hide the feature
strokeStyle:
polygon?.stroke && (polygon?.show ?? true)
? polygon?.strokeColor
: "rgba(0,0,0,0)", // hide the feature
lineWidth: polygon?.strokeWidth,
lineJoin: polygon?.lineJoin,
};
}
if (appearanceType === "polyline") {
const polyline = computedFeature?.polyline;
return {
fillStyle:
(polyline?.strokeColor ?? true) && (polyline?.show ?? true)
? polyline?.strokeColor
: "rgba(0,0,0,0)", // hide the feature
strokeStyle:
polyline?.strokeColor && (polyline?.show ?? true)
? polyline?.strokeColor
: "rgba(0,0,0,0)", // hide the feature
lineWidth: polyline?.strokeWidth,
};
}
if (appearanceType === "marker") {
const marker = computedFeature?.marker;
return {
fillStyle:
(marker?.pointColor ?? true) && (marker?.show ?? true)
? marker?.pointColor
: "rgba(0,0,0,0)", // hide the feature
strokeStyle:
marker?.pointColor && (marker?.show ?? true)
? marker?.pointColor
: "rgba(0,0,0,0)", // hide the feature
lineWidth: marker?.pointSize,
};
}
return;
})();
cachedStyleMap.set(styleCacheKey, style);
return style;
},
Expand All @@ -81,10 +136,20 @@ export const useMVT = ({
if (!layer) {
return;
}
const appearanceType = (() => {
switch (VectorTileFeature.types[mvtFeature.type]) {
case "Polygon":
return "polygon";
case "LineString":
return "polyline";
case "Point":
return "marker";
}
})();
const id = mvtFeature.id
? String(mvtFeature.id)
: idFromGeometry(mvtFeature.loadGeometry(), tile);
const feature = evalFeature(layer, makeFeatureFromPolygon(id, mvtFeature, tile));
const feature = evalFeature(layer, makeFeature(id, mvtFeature, tile, appearanceType));
const info = new ImageryLayerFeatureInfo();
info.data = {
layerId: layer?.id,
Expand All @@ -108,12 +173,22 @@ export const useMVT = ({
credit,
evalFeature,
layerPolygonAppearance,
layerPolylineAppearance,
layerMarkerAppearance,
],
);

const cacheKeyForUpdatedAt = useMemo(
() =>
JSON.stringify(layerPolygonAppearance) +
JSON.stringify(layerPolylineAppearance) +
JSON.stringify(layerMarkerAppearance),
[layerPolygonAppearance, layerPolylineAppearance, layerMarkerAppearance],
);

useEffect(() => {
updatedAt.current = Date.now();
}, [JSON.stringify(layerPolygonAppearance)]); // eslint-disable-line react-hooks/exhaustive-deps
}, [cacheKeyForUpdatedAt]); // eslint-disable-line react-hooks/exhaustive-deps

useEffect(() => {
cachedCalculatedLayerRef.current = layer;
Expand All @@ -133,20 +208,42 @@ const idFromGeometry = (
return generateIDWithMD5(id);
};

const makeFeatureFromPolygon = (
const makeFeature = (
id: string,
feature: VectorTileFeature,
tile: TileCoords,
appearance: "polygon" | "polyline" | "marker",
): Feature => {
const geometry = feature.loadGeometry();
const coordinates = geometry.map(points => points.map(p => [p.x, p.y]));
const [type, coordinates] = (() => {
if (appearance === "polygon") {
return [
"Polygon" as Polygon["type"],
geometry.map(points => points.map(p => [p.x, p.y])) as Polygon["coordinates"],
];
}
if (appearance === "polyline") {
return [
"LineString" as LineString["type"],
geometry[0].map(p => [p.x, p.y]) as LineString["coordinates"],
];
}
if (appearance === "marker") {
return [
"Point" as Point["type"],
[geometry[0][0].x, geometry[0][0].y] as Point["coordinates"],
];
}

throw new Error(`Unexpected appearance ${appearance}`);
})();
return {
type: "feature",
id,
geometry: {
type: "Polygon",
type,
coordinates,
},
} as Geometry,
properties: feature.properties,
range: {
x: tile.x,
Expand All @@ -165,3 +262,11 @@ const polygonAppearanceFields: (keyof PolygonAppearance)[] = [
"strokeWidth",
"lineJoin",
];

const polylineAppearanceFields: (keyof PolylineAppearance)[] = [
"show",
"strokeColor",
"strokeWidth",
];

const markerAppearanceFields: (keyof MarkerAppearance)[] = ["show", "pointColor", "pointSize"];
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7803,10 +7803,10 @@ cesium-dnd@1.1.0:
resolved "https://registry.yarnpkg.com/cesium-dnd/-/cesium-dnd-1.1.0.tgz#30c7232eec9f84ad0d4f2c959cbd61ac29028086"
integrity sha512-Peo0bGIg5eOO/BrVDCovkPhQnWW3GBAjVnghh5NVmavDZjqS+A5R4Yj3IOG9tmYNSdtunsDqj5yxnMxQWx/KAA==

cesium-mvt-imagery-provider@1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/cesium-mvt-imagery-provider/-/cesium-mvt-imagery-provider-1.2.4.tgz#bcbef0953c444b9147535fd15247d32147ece173"
integrity sha512-0sJQ6qc2Uhqz45IOtlQeq1IZly2hGtLgBOBRQSNjATSydOPhikGB43BOJBKBl97vFmf/n2+5XBJ9RVhBlM8/Ew==
cesium-mvt-imagery-provider@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/cesium-mvt-imagery-provider/-/cesium-mvt-imagery-provider-1.3.0.tgz#0237804e87aefc0801f6bb66de2602b5a78447aa"
integrity sha512-+6YOnYPBJKUF/ICIaGIQoa9MrsZeKi4F6Sko3yS42003B4x8MRwSXj498XvPGnPnGl0zkb5K5xOxkeuysyDrdQ==
dependencies:
"@mapbox/vector-tile" "1.3.1"
pbf "3.2.1"
Expand Down

0 comments on commit abd9a3c

Please sign in to comment.