Skip to content

Commit 9bd5a0d

Browse files
committed
Fetch exact geometry from server and simplify it on client before moving around with sketch tool
1 parent 1003e68 commit 9bd5a0d

File tree

3 files changed

+72
-4
lines changed

3 files changed

+72
-4
lines changed

package-lock.json

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@arcgis/core": "^4.23",
1818
"@esri/calcite-components": "^1.0.0-beta.78",
1919
"gl-matrix": "3.3.0",
20+
"simplify-js": "^1.2.4",
2021
"typescript": "^4.3.2",
2122
"vite": "^2.6.14"
2223
},

src/PlaceCountry.tsx

+60-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import {
44
} from "@arcgis/core/core/accessorSupport/decorators";
55
import * as promiseUtils from "@arcgis/core/core/promiseUtils";
66
import * as watchUtils from "@arcgis/core/core/watchUtils";
7+
import { Polygon } from "@arcgis/core/geometry";
8+
import FeatureLayer from "@arcgis/core/layers/FeatureLayer";
79
import { tsx } from "@arcgis/core/widgets/support/widget";
810
import Widget from "@arcgis/core/widgets/Widget";
11+
import simplify from "simplify-js";
912
import { countryLabel } from "./countryUtils";
1013
import { map, palette, view } from "./globals";
1114
import RegionEditor from "./RegionEditor";
@@ -35,7 +38,7 @@ export class PlaceCountry extends Widget {
3538
);
3639
}
3740

38-
private async queryRegion(e: MouseEvent) {
41+
private async queryRegion(e: MouseEvent, serverSide = false) {
3942
const include = map.allLayers.filter(
4043
(l) => l.type === "feature" || l.type === "graphics"
4144
);
@@ -56,7 +59,23 @@ export class PlaceCountry extends Widget {
5659
return layerIndex(b) - layerIndex(a);
5760
});
5861

59-
return results[0].graphic;
62+
const graphic = results[0].graphic;
63+
const layer = graphic.layer;
64+
if (
65+
layer.type === "feature" &&
66+
layer instanceof FeatureLayer &&
67+
serverSide
68+
) {
69+
const query = layer.createQuery();
70+
query.returnGeometry = true;
71+
query.objectIds = [graphic.getObjectId()];
72+
query.outSpatialReference = graphic.geometry.spatialReference;
73+
const response = await layer.queryFeatures(query);
74+
if (response.features.length) {
75+
return response.features[0];
76+
}
77+
}
78+
return graphic;
6079
}
6180
}
6281

@@ -110,7 +129,7 @@ export class PlaceCountry extends Widget {
110129
return;
111130
}
112131

113-
const graphic = await this.queryRegion(e);
132+
const graphic = await this.queryRegion(e, true);
114133

115134
if (graphic) {
116135
const color = palette.selectionColor;
@@ -119,10 +138,47 @@ export class PlaceCountry extends Widget {
119138
} else if (color) {
120139
e.preventDefault();
121140

141+
const clone = graphic.clone();
142+
const geometry = clone.geometry as Polygon;
143+
144+
// The further the country is in the north / south, the more we have to simplify
145+
const ymax = Math.max(
146+
Math.abs(geometry.extent.ymax),
147+
Math.abs(geometry.extent.ymin)
148+
);
149+
const tolerance = ymax / 2500;
150+
151+
let rings = geometry.rings;
152+
const maxLength = rings.reduce(
153+
(acc, cur) => Math.max(cur.length, acc),
154+
0
155+
);
156+
157+
// Filter small islands around main land
158+
rings = rings.filter((r) => r.length > maxLength / 10);
159+
160+
let before = 0;
161+
let after = 0;
162+
163+
// Simplify remaining rings
164+
rings = rings.map((ring) => {
165+
const points = ring.map((c) => {
166+
return { x: c[0], y: c[1] };
167+
});
168+
before += points.length;
169+
const simplified = simplify(points, tolerance);
170+
after += simplified.length;
171+
return simplified.map((p) => [p.x, p.y]);
172+
});
173+
174+
// console.log({ before, after, countr: countryLabel(clone) });
175+
176+
geometry.rings = rings;
177+
122178
this.regionEditor.editSelection(
123179
new SelectedRegion({
124180
color,
125-
graphic,
181+
graphic: clone,
126182
})
127183
);
128184
this.resetRegion();

0 commit comments

Comments
 (0)