@chelone/core 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assistant/assistant-session.d.ts +28 -0
- package/dist/assistant/assistant-session.js +208 -0
- package/dist/assistant/echo-transport.d.ts +7 -0
- package/dist/assistant/echo-transport.js +28 -0
- package/dist/assistant/http-transport.d.ts +10 -0
- package/dist/assistant/http-transport.js +98 -0
- package/dist/assistant/types.d.ts +54 -0
- package/dist/auth/access-control.d.ts +13 -5
- package/dist/auth/access-control.js +25 -21
- package/dist/auth/auth-options.d.ts +21 -17
- package/dist/auth/auth-options.js +80 -48
- package/dist/auth/permission-matrix.d.ts +12 -0
- package/dist/auth/permission-matrix.js +67 -0
- package/dist/auth/types.d.ts +14 -4
- package/dist/block-editor/block-document.d.ts +60 -0
- package/dist/block-editor/block-document.js +143 -0
- package/dist/block-editor/data-blocks.d.ts +63 -0
- package/dist/block-editor/data-blocks.js +117 -0
- package/dist/chart/chart-data.d.ts +25 -0
- package/dist/chart/chart-data.js +61 -0
- package/dist/command-menu/hotkey.js +58 -47
- package/dist/command-menu/recents.js +8 -11
- package/dist/command-menu/registry.d.ts +9 -5
- package/dist/command-menu/registry.js +36 -46
- package/dist/controller/calendar-dates.js +82 -113
- package/dist/controller/calendar-events.js +93 -88
- package/dist/controller/client-list-controller.d.ts +2 -2
- package/dist/controller/client-list-controller.js +251 -254
- package/dist/controller/data-table-columns.d.ts +2 -0
- package/dist/controller/data-table-columns.js +50 -56
- package/dist/controller/deep-equal.d.ts +1 -0
- package/dist/controller/deep-equal.js +14 -0
- package/dist/controller/filter-toggle.js +36 -44
- package/dist/controller/in-place-editor.d.ts +42 -0
- package/dist/controller/in-place-editor.js +42 -0
- package/dist/controller/infinite-list-controller.js +220 -190
- package/dist/controller/inspector.d.ts +49 -0
- package/dist/controller/inspector.js +64 -0
- package/dist/controller/job-monitor.d.ts +41 -0
- package/dist/controller/job-monitor.js +49 -0
- package/dist/controller/kanban-board.d.ts +2 -3
- package/dist/controller/kanban-board.js +43 -24
- package/dist/controller/list-controller.d.ts +5 -5
- package/dist/controller/list-controller.js +444 -400
- package/dist/controller/list-params.js +96 -87
- package/dist/controller/pivot-grid.d.ts +36 -0
- package/dist/controller/pivot-grid.js +99 -0
- package/dist/controller/prev-next.d.ts +2 -2
- package/dist/controller/prev-next.js +74 -54
- package/dist/controller/record-controllers.d.ts +14 -6
- package/dist/controller/record-controllers.js +288 -257
- package/dist/controller/record-diff.d.ts +21 -0
- package/dist/controller/record-diff.js +50 -0
- package/dist/controller/record-timeline.d.ts +35 -0
- package/dist/controller/record-timeline.js +48 -0
- package/dist/controller/record-tree.js +57 -47
- package/dist/controller/record-workflow.d.ts +38 -16
- package/dist/controller/record-workflow.js +85 -64
- package/dist/controller/reference-many-controller.js +198 -192
- package/dist/controller/reference-one-controller.d.ts +1 -1
- package/dist/controller/reference-one-controller.js +63 -56
- package/dist/controller/saved-queries.js +104 -91
- package/dist/controller/translate-fallback.js +10 -6
- package/dist/csv/export.d.ts +2 -1
- package/dist/csv/export.js +43 -40
- package/dist/csv/import-controller.js +185 -169
- package/dist/csv/match-headers.js +29 -22
- package/dist/csv/parse-with.js +60 -54
- package/dist/csv/run-import.js +69 -72
- package/dist/csv/validate-rows.d.ts +1 -1
- package/dist/csv/validate-rows.js +65 -52
- package/dist/data/cache-ops.d.ts +5 -4
- package/dist/data/cache-ops.js +208 -190
- package/dist/data/combine-data-providers.js +25 -23
- package/dist/data/data-provider-log.d.ts +45 -0
- package/dist/data/data-provider-log.js +93 -0
- package/dist/data/errors.js +14 -10
- package/dist/data/fake-provider.d.ts +6 -3
- package/dist/data/fake-provider.js +129 -114
- package/dist/data/fetch-utils.js +61 -44
- package/dist/data/filter-branch.d.ts +5 -0
- package/dist/data/filter-branch.js +10 -0
- package/dist/data/get-many-aggregate.js +84 -76
- package/dist/data/http-error.js +17 -12
- package/dist/data/keys.js +50 -36
- package/dist/data/mutation-options.d.ts +14 -9
- package/dist/data/mutation-options.js +93 -109
- package/dist/data/query-options.js +73 -68
- package/dist/data/remove-empty.d.ts +3 -0
- package/dist/data/remove-empty.js +11 -0
- package/dist/data/undoable.d.ts +2 -2
- package/dist/data/undoable.js +190 -174
- package/dist/data/with-lifecycle-callbacks.d.ts +45 -17
- package/dist/data/with-lifecycle-callbacks.js +66 -52
- package/dist/environment/application-update-store.js +58 -55
- package/dist/environment/offline-store.js +21 -21
- package/dist/form/array-binding.d.ts +30 -11
- package/dist/form/array-binding.js +184 -166
- package/dist/form/choice-ids.d.ts +7 -0
- package/dist/form/choice-ids.js +11 -0
- package/dist/form/choices-controller.d.ts +3 -2
- package/dist/form/choices-controller.js +302 -275
- package/dist/form/date-format.d.ts +38 -0
- package/dist/form/date-format.js +89 -0
- package/dist/form/dirty-values.d.ts +2 -2
- package/dist/form/dirty-values.js +22 -11
- package/dist/form/duration.d.ts +22 -0
- package/dist/form/duration.js +49 -0
- package/dist/form/edit-create-form.d.ts +12 -5
- package/dist/form/edit-create-form.js +243 -188
- package/dist/form/event-value.d.ts +6 -0
- package/dist/form/event-value.js +17 -0
- package/dist/form/field-error.d.ts +14 -0
- package/dist/form/field-error.js +28 -0
- package/dist/form/field-name.d.ts +20 -0
- package/dist/form/field-name.js +6 -0
- package/dist/form/filter-form-values.js +63 -49
- package/dist/form/form-controller.d.ts +9 -1
- package/dist/form/form-controller.js +165 -160
- package/dist/form/form-groups.d.ts +4 -3
- package/dist/form/form-groups.js +79 -79
- package/dist/form/form-handle.d.ts +175 -0
- package/dist/form/form-handle.js +68 -0
- package/dist/form/input-binding.d.ts +56 -31
- package/dist/form/input-binding.js +169 -118
- package/dist/form/input-values.d.ts +130 -0
- package/dist/form/input-values.js +177 -0
- package/dist/form/json-text.js +51 -37
- package/dist/form/save-pipeline.d.ts +6 -8
- package/dist/form/save-pipeline.js +91 -82
- package/dist/form/set-form-values.d.ts +6 -0
- package/dist/form/set-form-values.js +10 -0
- package/dist/form/source.js +97 -65
- package/dist/form/text-of.d.ts +2 -0
- package/dist/form/text-of.js +7 -0
- package/dist/form/validators.d.ts +58 -19
- package/dist/form/validators.js +97 -71
- package/dist/geo/bbox.d.ts +5 -4
- package/dist/geo/bbox.js +69 -48
- package/dist/geo/bounds.d.ts +14 -3
- package/dist/geo/bounds.js +98 -68
- package/dist/geo/constraints.js +88 -93
- package/dist/geo/coordinates.js +31 -23
- package/dist/geo/editor.d.ts +13 -13
- package/dist/geo/editor.js +176 -153
- package/dist/geo/geocoding.d.ts +4 -4
- package/dist/geo/geocoding.js +38 -41
- package/dist/geo/geojson.d.ts +12 -74
- package/dist/geo/geojson.js +52 -40
- package/dist/geo/geometry-math.d.ts +4 -4
- package/dist/geo/geometry-math.js +100 -93
- package/dist/geo/index.d.ts +7 -6
- package/dist/geo/map-layers.d.ts +42 -7
- package/dist/geo/map-layers.js +88 -62
- package/dist/geo/map-style.js +31 -32
- package/dist/geo/messages.js +48 -45
- package/dist/geo/nominatim.js +88 -80
- package/dist/geo/osm-presets.d.ts +4 -3
- package/dist/geo/osm-presets.js +108 -86
- package/dist/geo/osm-tags.js +14 -12
- package/dist/geo/overpass.d.ts +14 -2
- package/dist/geo/overpass.js +83 -90
- package/dist/geo/shape-value.d.ts +9 -5
- package/dist/geo/shape-value.js +169 -146
- package/dist/geo/snap-to-roads.d.ts +3 -3
- package/dist/geo/snap-to-roads.js +55 -50
- package/dist/geo/throttle.js +36 -39
- package/dist/guards.d.ts +37 -0
- package/dist/guards.js +62 -0
- package/dist/i18n/default-messages.js +34 -29
- package/dist/i18n/english-messages.js +187 -189
- package/dist/i18n/i18n.d.ts +8 -2
- package/dist/i18n/i18n.js +47 -48
- package/dist/i18n/inflection.d.ts +34 -0
- package/dist/i18n/inflection.js +82 -0
- package/dist/i18n/messages.d.ts +10 -2
- package/dist/i18n/messages.js +17 -4
- package/dist/i18n/missing-keys.d.ts +19 -0
- package/dist/i18n/missing-keys.js +68 -0
- package/dist/i18n/translatable.d.ts +16 -1
- package/dist/i18n/translatable.js +40 -47
- package/dist/index.d.ts +96 -22
- package/dist/index.js +52 -257
- package/dist/json/deep-equal.d.ts +8 -0
- package/dist/json/deep-equal.js +24 -0
- package/dist/json/strip-json-comments.js +38 -42
- package/dist/noop.d.ts +2 -0
- package/dist/noop.js +4 -0
- package/dist/notification/error-message.d.ts +2 -0
- package/dist/notification/error-message.js +10 -0
- package/dist/notification/notification-store.d.ts +3 -2
- package/dist/notification/notification-store.js +41 -45
- package/dist/onboarding-tour/placement.d.ts +34 -0
- package/dist/onboarding-tour/placement.js +67 -0
- package/dist/onboarding-tour/tour-controller.d.ts +25 -0
- package/dist/onboarding-tour/tour-controller.js +50 -0
- package/dist/realtime/add-events-for-mutations.js +75 -81
- package/dist/realtime/announce-lock.d.ts +7 -0
- package/dist/realtime/announce-lock.js +18 -0
- package/dist/realtime/broadcast-channel-transport.d.ts +14 -0
- package/dist/realtime/broadcast-channel-transport.js +69 -0
- package/dist/realtime/copy-members.js +22 -14
- package/dist/realtime/in-memory-lock-provider.js +41 -60
- package/dist/realtime/live.js +95 -101
- package/dist/realtime/lock-options.js +16 -16
- package/dist/realtime/lock-session.js +91 -78
- package/dist/realtime/memory-transport.js +26 -67
- package/dist/realtime/presence.js +120 -122
- package/dist/realtime/realtime-data-provider.d.ts +10 -0
- package/dist/realtime/realtime-data-provider.js +45 -42
- package/dist/realtime/reconnect-backoff.d.ts +15 -0
- package/dist/realtime/reconnect-backoff.js +17 -0
- package/dist/realtime/sse-transport.d.ts +31 -0
- package/dist/realtime/sse-transport.js +235 -0
- package/dist/realtime/status-store.js +23 -28
- package/dist/realtime/topic-hub.d.ts +24 -0
- package/dist/realtime/topic-hub.js +66 -0
- package/dist/realtime/topics.js +10 -12
- package/dist/realtime/types.js +10 -12
- package/dist/realtime/unread-count.js +21 -21
- package/dist/realtime/websocket-transport.d.ts +32 -0
- package/dist/realtime/websocket-transport.js +306 -0
- package/dist/resource/describe-resource.d.ts +2 -0
- package/dist/resource/describe-resource.js +232 -219
- package/dist/resource/get-at-path.js +29 -14
- package/dist/resource/identifier.d.ts +18 -0
- package/dist/resource/identifier.js +27 -0
- package/dist/resource/record.d.ts +4 -0
- package/dist/resource/record.js +10 -0
- package/dist/resource/register.d.ts +7 -0
- package/dist/resource/registry-store.d.ts +45 -15
- package/dist/resource/registry-store.js +67 -60
- package/dist/resource/registry.d.ts +10 -0
- package/dist/resource/registry.js +8 -4
- package/dist/resource/source-path.d.ts +16 -1
- package/dist/rich-text/rich-text-extras.d.ts +132 -0
- package/dist/rich-text/rich-text-extras.js +179 -0
- package/dist/rich-text/rich-text-image.d.ts +124 -0
- package/dist/rich-text/rich-text-image.js +163 -0
- package/dist/rich-text/rich-text.d.ts +62 -0
- package/dist/rich-text/rich-text.js +142 -0
- package/dist/router/location.d.ts +22 -4
- package/dist/router/location.js +41 -18
- package/dist/router/match.js +47 -39
- package/dist/router/paths.js +40 -34
- package/dist/router/record-from-location.d.ts +1 -1
- package/dist/router/record-from-location.js +25 -17
- package/dist/store/adapters.js +51 -55
- package/dist/store/micro-store.js +57 -59
- package/dist/store/shallow-equal.d.ts +12 -0
- package/dist/store/shallow-equal.js +20 -0
- package/dist/store/store.js +54 -57
- package/package.json +13 -11
package/dist/geo/geojson.js
CHANGED
|
@@ -1,57 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
1
|
+
import { isJsonObject, isRecord } from "../guards.js";
|
|
2
|
+
// src/geo/geojson.ts
|
|
4
3
|
function isFiniteNumber(value) {
|
|
5
|
-
|
|
4
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
6
5
|
}
|
|
7
6
|
function isPosition(value) {
|
|
8
|
-
|
|
7
|
+
return Array.isArray(value) && value.length >= 2 && value.every(isFiniteNumber);
|
|
9
8
|
}
|
|
9
|
+
/** Checks `depth` levels of arrays above the positions (0 is a position). */
|
|
10
10
|
function isNested(value, depth) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
if (depth === 0) return isPosition(value);
|
|
12
|
+
return Array.isArray(value) && value.every((item) => isNested(item, depth - 1));
|
|
13
|
+
}
|
|
14
|
+
/** Array depth above the positions, per geometry type. */
|
|
15
|
+
var COORDINATE_DEPTH = {
|
|
16
|
+
Point: 0,
|
|
17
|
+
MultiPoint: 1,
|
|
18
|
+
LineString: 1,
|
|
19
|
+
MultiLineString: 2,
|
|
20
|
+
Polygon: 2,
|
|
21
|
+
MultiPolygon: 3
|
|
21
22
|
};
|
|
23
|
+
/** True for exactly four finite numbers. */
|
|
22
24
|
function isGeoBBox(value) {
|
|
23
|
-
|
|
25
|
+
return Array.isArray(value) && value.length === 4 && value.every(isFiniteNumber);
|
|
24
26
|
}
|
|
27
|
+
/** The `bbox` member of an object: 4 numbers, or 6 when it carries altitude. */
|
|
25
28
|
function hasValidBBox(value) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
const { bbox } = value;
|
|
30
|
+
if (bbox === void 0) return true;
|
|
31
|
+
return Array.isArray(bbox) && (bbox.length === 4 || bbox.length === 6) && bbox.every(isFiniteNumber);
|
|
29
32
|
}
|
|
30
33
|
function isGeoGeometry(value) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
if (!isRecord(value) || !hasValidBBox(value)) return false;
|
|
35
|
+
if (value.type === "GeometryCollection") return Array.isArray(value.geometries) && value.geometries.every(isGeoGeometry);
|
|
36
|
+
const depth = typeof value.type === "string" && Object.hasOwn(COORDINATE_DEPTH, value.type) ? COORDINATE_DEPTH[value.type] : void 0;
|
|
37
|
+
return depth !== void 0 && isNested(value.coordinates, depth);
|
|
38
|
+
}
|
|
39
|
+
/** A Polygon or a MultiPolygon, the geometries turf's area operations take. */
|
|
40
|
+
function isGeoArea(value) {
|
|
41
|
+
return isGeoGeometry(value) && (value.type === "Polygon" || value.type === "MultiPolygon");
|
|
37
42
|
}
|
|
38
43
|
function isGeoFeature(value) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (value.geometry !== null && !isGeoGeometry(value.geometry)) return false;
|
|
43
|
-
return value.properties === void 0 || value.properties === null || isRecord(value.properties);
|
|
44
|
+
if (!isRecord(value) || value.type !== "Feature" || !hasValidBBox(value)) return false;
|
|
45
|
+
if (value.geometry !== null && !isGeoGeometry(value.geometry)) return false;
|
|
46
|
+
return value.properties === void 0 || value.properties === null || isJsonObject(value.properties);
|
|
44
47
|
}
|
|
45
48
|
function isGeoFeatureCollection(value) {
|
|
46
|
-
|
|
49
|
+
return isRecord(value) && value.type === "FeatureCollection" && hasValidBBox(value) && Array.isArray(value.features) && value.features.every(isGeoFeature);
|
|
47
50
|
}
|
|
48
51
|
function isGeoJsonValue(value) {
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
return isGeoGeometry(value) || isGeoFeature(value) || isGeoFeatureCollection(value);
|
|
53
|
+
}
|
|
54
|
+
/** The features MapLibre draws: a feature with a null geometry has nothing to draw. */
|
|
55
|
+
function placedFeatures(collection) {
|
|
56
|
+
const features = [];
|
|
57
|
+
for (const feature of collection.features) {
|
|
58
|
+
const { geometry } = feature;
|
|
59
|
+
if (geometry !== null) features.push({
|
|
60
|
+
...feature,
|
|
61
|
+
geometry
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
...collection,
|
|
66
|
+
features
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export { isGeoArea, isGeoBBox, isGeoFeature, isGeoFeatureCollection, isGeoGeometry, isGeoJsonValue, placedFeatures };
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Geometry } from "geojson";
|
|
2
2
|
/**
|
|
3
3
|
* Area in square metres on a sphere of radius 6378137 m, as `@turf/area`
|
|
4
4
|
* computes it. Holes are subtracted. `0` for every type but Polygon and
|
|
5
5
|
* MultiPolygon.
|
|
6
6
|
*/
|
|
7
|
-
export declare function geoAreaM2(geometry:
|
|
7
|
+
export declare function geoAreaM2(geometry: Geometry): number;
|
|
8
8
|
/**
|
|
9
9
|
* True when two non-adjacent segments of a ring or a line cross or touch.
|
|
10
10
|
* Rings of one polygon, or polygons of one collection, are not compared with
|
|
11
11
|
* each other.
|
|
12
12
|
*/
|
|
13
|
-
export declare function hasSelfIntersection(geometry:
|
|
14
|
-
type Area = Extract<
|
|
13
|
+
export declare function hasSelfIntersection(geometry: Geometry): boolean;
|
|
14
|
+
type Area = Extract<Geometry, {
|
|
15
15
|
type: "Polygon" | "MultiPolygon";
|
|
16
16
|
}>;
|
|
17
17
|
/**
|
|
@@ -1,120 +1,127 @@
|
|
|
1
|
-
|
|
1
|
+
// src/geo/geometry-math.ts
|
|
2
|
+
var EARTH_RADIUS_M = 6378137;
|
|
2
3
|
function toRadians(degrees) {
|
|
3
|
-
|
|
4
|
+
return degrees * Math.PI / 180;
|
|
4
5
|
}
|
|
6
|
+
/** An element of an array whose index the caller keeps in range. */
|
|
5
7
|
function at(positions, index) {
|
|
6
|
-
|
|
8
|
+
const position = positions[index];
|
|
9
|
+
if (!position) throw new RangeError(`No position at index ${index}`);
|
|
10
|
+
return position;
|
|
11
|
+
}
|
|
12
|
+
/** Longitude and latitude; `NaN` for one a short position lacks. */
|
|
13
|
+
function xy([x = NaN, y = NaN]) {
|
|
14
|
+
return [x, y];
|
|
7
15
|
}
|
|
8
16
|
function samePosition(a, b) {
|
|
9
|
-
|
|
17
|
+
const [ax, ay] = xy(a);
|
|
18
|
+
const [bx, by] = xy(b);
|
|
19
|
+
return ax === bx && ay === by;
|
|
10
20
|
}
|
|
21
|
+
/** Drops a closing position that repeats the first one. */
|
|
11
22
|
function openRing(ring) {
|
|
12
|
-
|
|
13
|
-
|
|
23
|
+
const last = ring[ring.length - 1];
|
|
24
|
+
return ring.length > 1 && last && samePosition(at(ring, 0), last) ? ring.slice(0, -1) : ring;
|
|
14
25
|
}
|
|
26
|
+
/** Unsigned area of one ring on the sphere. */
|
|
15
27
|
function ringAreaM2(ring) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
const points = openRing(ring);
|
|
29
|
+
const count = points.length;
|
|
30
|
+
if (count < 3) return 0;
|
|
31
|
+
let sum = 0;
|
|
32
|
+
for (let i = 0; i < count; i++) {
|
|
33
|
+
const before = at(points, (i + count - 1) % count);
|
|
34
|
+
const here = at(points, i);
|
|
35
|
+
const after = at(points, (i + 1) % count);
|
|
36
|
+
sum += (toRadians(xy(after)[0]) - toRadians(xy(before)[0])) * Math.sin(toRadians(xy(here)[1]));
|
|
37
|
+
}
|
|
38
|
+
return Math.abs(sum * EARTH_RADIUS_M * EARTH_RADIUS_M / 2);
|
|
27
39
|
}
|
|
28
40
|
function polygonAreaM2(rings) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
(area, hole) => area - ringAreaM2(hole),
|
|
33
|
-
ringAreaM2(outer)
|
|
34
|
-
);
|
|
41
|
+
const [outer, ...holes] = rings;
|
|
42
|
+
if (!outer) return 0;
|
|
43
|
+
return holes.reduce((area, hole) => area - ringAreaM2(hole), ringAreaM2(outer));
|
|
35
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Area in square metres on a sphere of radius 6378137 m, as `@turf/area`
|
|
47
|
+
* computes it. Holes are subtracted. `0` for every type but Polygon and
|
|
48
|
+
* MultiPolygon.
|
|
49
|
+
*/
|
|
36
50
|
function geoAreaM2(geometry) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
(total, polygon) => total + polygonAreaM2(polygon),
|
|
41
|
-
0
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
return 0;
|
|
51
|
+
if (geometry.type === "Polygon") return polygonAreaM2(geometry.coordinates);
|
|
52
|
+
if (geometry.type === "MultiPolygon") return geometry.coordinates.reduce((total, polygon) => total + polygonAreaM2(polygon), 0);
|
|
53
|
+
return 0;
|
|
45
54
|
}
|
|
55
|
+
/** Twice the signed area of the triangle `a`, `b`, `c`. */
|
|
46
56
|
function cross(a, b, c) {
|
|
47
|
-
|
|
57
|
+
const [ax, ay] = xy(a);
|
|
58
|
+
const [bx, by] = xy(b);
|
|
59
|
+
const [cx, cy] = xy(c);
|
|
60
|
+
return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax);
|
|
48
61
|
}
|
|
49
62
|
function onSegment(a, b, point) {
|
|
50
|
-
|
|
63
|
+
const [ax, ay] = xy(a);
|
|
64
|
+
const [bx, by] = xy(b);
|
|
65
|
+
const [px, py] = xy(point);
|
|
66
|
+
return px >= Math.min(ax, bx) && px <= Math.max(ax, bx) && py >= Math.min(ay, by) && py <= Math.max(ay, by);
|
|
51
67
|
}
|
|
68
|
+
/** True when the segments share any point, a touch or an overlap included. */
|
|
52
69
|
function segmentsMeet(a, b, c, d) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
return abc === 0 && onSegment(a, b, c) || abd === 0 && onSegment(a, b, d) || cda === 0 && onSegment(c, d, a) || cdb === 0 && onSegment(c, d, b);
|
|
70
|
+
const abc = cross(a, b, c);
|
|
71
|
+
const abd = cross(a, b, d);
|
|
72
|
+
const cda = cross(c, d, a);
|
|
73
|
+
const cdb = cross(c, d, b);
|
|
74
|
+
if ((abc > 0 && abd < 0 || abc < 0 && abd > 0) && (cda > 0 && cdb < 0 || cda < 0 && cdb > 0)) return true;
|
|
75
|
+
return abc === 0 && onSegment(a, b, c) || abd === 0 && onSegment(a, b, d) || cda === 0 && onSegment(c, d, a) || cdb === 0 && onSegment(c, d, b);
|
|
61
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* True when two segments that do not follow each other share a point.
|
|
79
|
+
* `closed` makes the last segment follow the first.
|
|
80
|
+
*/
|
|
62
81
|
function pathSelfIntersects(positions, closed) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (segmentsMeet(
|
|
71
|
-
at(points, i),
|
|
72
|
-
at(points, (i + 1) % points.length),
|
|
73
|
-
at(points, j),
|
|
74
|
-
at(points, (j + 1) % points.length)
|
|
75
|
-
)) {
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return false;
|
|
82
|
+
const points = positions.filter((position, index) => index === 0 || !samePosition(position, at(positions, index - 1)));
|
|
83
|
+
const segments = closed ? points.length : points.length - 1;
|
|
84
|
+
for (let i = 0; i < segments; i++) for (let j = i + 2; j < segments; j++) {
|
|
85
|
+
if (closed && i === 0 && j === segments - 1) continue;
|
|
86
|
+
if (segmentsMeet(at(points, i), at(points, (i + 1) % points.length), at(points, j), at(points, (j + 1) % points.length))) return true;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
81
89
|
}
|
|
82
90
|
function lineSelfIntersects(line) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
const first = line[0];
|
|
92
|
+
const last = line[line.length - 1];
|
|
93
|
+
const closed = line.length > 3 && first !== void 0 && last !== void 0 && samePosition(first, last);
|
|
94
|
+
return pathSelfIntersects(closed ? line.slice(0, -1) : line, closed);
|
|
87
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* True when two non-adjacent segments of a ring or a line cross or touch.
|
|
98
|
+
* Rings of one polygon, or polygons of one collection, are not compared with
|
|
99
|
+
* each other.
|
|
100
|
+
*/
|
|
88
101
|
function hasSelfIntersection(geometry) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
);
|
|
98
|
-
case "MultiPolygon":
|
|
99
|
-
return geometry.coordinates.some(
|
|
100
|
-
(polygon) => polygon.some((ring) => pathSelfIntersects(openRing(ring), true))
|
|
101
|
-
);
|
|
102
|
-
case "GeometryCollection":
|
|
103
|
-
return geometry.geometries.some(hasSelfIntersection);
|
|
104
|
-
default:
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
102
|
+
switch (geometry.type) {
|
|
103
|
+
case "LineString": return lineSelfIntersects(geometry.coordinates);
|
|
104
|
+
case "MultiLineString": return geometry.coordinates.some(lineSelfIntersects);
|
|
105
|
+
case "Polygon": return geometry.coordinates.some((ring) => pathSelfIntersects(openRing(ring), true));
|
|
106
|
+
case "MultiPolygon": return geometry.coordinates.some((polygon) => polygon.some((ring) => pathSelfIntersects(openRing(ring), true)));
|
|
107
|
+
case "GeometryCollection": return geometry.geometries.some(hasSelfIntersection);
|
|
108
|
+
default: return false;
|
|
109
|
+
}
|
|
107
110
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
111
|
+
/**
|
|
112
|
+
* `result` in the type of `value`, so it stays editable by the input that owns
|
|
113
|
+
* the field. `null` when a Polygon would have to hold several pieces.
|
|
114
|
+
*/
|
|
115
|
+
var areaInTypeOf = (value, result) => {
|
|
116
|
+
if (value.type === "MultiPolygon") return result.type === "Polygon" ? {
|
|
117
|
+
type: "MultiPolygon",
|
|
118
|
+
coordinates: [result.coordinates]
|
|
119
|
+
} : result;
|
|
120
|
+
if (result.type === "Polygon") return result;
|
|
121
|
+
const [only, ...rest] = result.coordinates;
|
|
122
|
+
return only && rest.length === 0 ? {
|
|
123
|
+
type: "Polygon",
|
|
124
|
+
coordinates: only
|
|
125
|
+
} : null;
|
|
120
126
|
};
|
|
127
|
+
export { areaInTypeOf, geoAreaM2, hasSelfIntersection };
|
package/dist/geo/index.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
export { aspectLockedBBox, bboxToPolygon, polygonToBBox } from "./bbox.js";
|
|
2
|
+
export type { LngLatBox } from "./bounds.js";
|
|
2
3
|
export { geoBounds, isLngLatBox } from "./bounds.js";
|
|
3
4
|
export { countVertices, maxVertices, minAreaM2, minVertices, noSelfIntersection, } from "./constraints.js";
|
|
4
5
|
export { latitude, longitude, toCoordinate } from "./coordinates.js";
|
|
5
|
-
export type { EditorSnapshotFeature, EditorStyles } from "./editor.js";
|
|
6
|
+
export type { EditorFeature, EditorSnapshotFeature, EditorStyles, } from "./editor.js";
|
|
6
7
|
export { editorStyles, fromEditorFeatures, toEditorFeatures } from "./editor.js";
|
|
7
8
|
export type { GeocodeQuery, GeocodeQueryOptions, GeocodeRequestOptions, GeocodeResult, GeocodeSearchOptions, GeocodingProvider, ReverseGeocodeQueryOptions, } from "./geocoding.js";
|
|
8
9
|
export { geocodeQueryOptions, reverseGeocodeQueryOptions } from "./geocoding.js";
|
|
9
|
-
export type {
|
|
10
|
-
export { isGeoBBox, isGeoFeature, isGeoFeatureCollection, isGeoGeometry, isGeoJsonValue, } from "./geojson.js";
|
|
10
|
+
export type { Feature, FeatureCollection, Geometry } from "./geojson.js";
|
|
11
|
+
export { isGeoArea, isGeoBBox, isGeoFeature, isGeoFeatureCollection, isGeoGeometry, isGeoJsonValue, placedFeatures, } from "./geojson.js";
|
|
11
12
|
export { areaInTypeOf, geoAreaM2, hasSelfIntersection, } from "./geometry-math.js";
|
|
12
|
-
export type { ShapeLayerSpec, ShapeStyle } from "./map-layers.js";
|
|
13
|
+
export type { CircleLayerSpec, FillLayerSpec, LineLayerSpec, ShapeLayerSpec, ShapeStyle, } from "./map-layers.js";
|
|
13
14
|
export { asFeatureCollection, DEFAULT_SHAPE_STYLE, shapeLayerSpecs, } from "./map-layers.js";
|
|
14
15
|
export type { MapStyleInput, MapStyleSpec, RasterTileStyleOptions, } from "./map-style.js";
|
|
15
16
|
export { expandTileUrl, latLngToLngLat, lngLatToLatLng, rasterTileStyle, } from "./map-style.js";
|
|
@@ -20,8 +21,8 @@ export type { OsmElementType, OsmPreset, OsmPresetName, OverpassQuerySources, }
|
|
|
20
21
|
export { buildOverpassQuery, findPresetForTags, OSM_PRESETS, } from "./osm-presets.js";
|
|
21
22
|
export type { OsmTagFilter, OsmTagInput } from "./osm-tags.js";
|
|
22
23
|
export { tagToFilter } from "./osm-tags.js";
|
|
23
|
-
export type { OverpassProvider, OverpassProviderOptions, OverpassQuery, OverpassQueryOptions, OverpassRequestOptions, } from "./overpass.js";
|
|
24
|
-
export { createOverpassProvider, OverpassError, OverpassRateLimitError, OverpassTimeoutError, overpassQueryOptions, } from "./overpass.js";
|
|
24
|
+
export type { OverpassAnswer, OverpassElement, OverpassProvider, OverpassProviderOptions, OverpassQuery, OverpassQueryOptions, OverpassRequestOptions, } from "./overpass.js";
|
|
25
|
+
export { createOverpassProvider, isOverpassAnswer, OverpassError, OverpassRateLimitError, OverpassTimeoutError, overpassQueryOptions, } from "./overpass.js";
|
|
25
26
|
export type { FeaturesToShapeOptions, ShapeValue, ShapeValueKind, } from "./shape-value.js";
|
|
26
27
|
export { featuresToShape, heldFeatures, shapeToFeatures } from "./shape-value.js";
|
|
27
28
|
export type { OsrmProviderOptions, RoutingProvider } from "./snap-to-roads.js";
|
package/dist/geo/map-layers.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FeatureCollection, Geometry } from "geojson";
|
|
2
|
+
import type { JsonObject } from "../guards.js";
|
|
2
3
|
export interface ShapeStyle {
|
|
3
4
|
color?: string;
|
|
4
5
|
/** Line width in pixels. */
|
|
@@ -19,19 +20,53 @@ export declare const DEFAULT_SHAPE_STYLE: {
|
|
|
19
20
|
readonly pointColor: "#3b82f6";
|
|
20
21
|
readonly pointRadius: 7;
|
|
21
22
|
};
|
|
22
|
-
|
|
23
|
+
/** `["==", ["geometry-type"], type]`: `geometry-type` is the base type for the Multi types. */
|
|
24
|
+
type GeometryTypeTest<TType extends "Polygon" | "LineString" | "Point"> = [
|
|
25
|
+
"==",
|
|
26
|
+
[
|
|
27
|
+
"geometry-type"
|
|
28
|
+
],
|
|
29
|
+
TType
|
|
30
|
+
];
|
|
31
|
+
export interface FillLayerSpec {
|
|
23
32
|
id: string;
|
|
24
|
-
type: "fill"
|
|
33
|
+
type: "fill";
|
|
25
34
|
source: string;
|
|
26
|
-
filter:
|
|
27
|
-
paint:
|
|
35
|
+
filter: GeometryTypeTest<"Polygon">;
|
|
36
|
+
paint: {
|
|
37
|
+
"fill-color": string;
|
|
38
|
+
"fill-opacity": number;
|
|
39
|
+
};
|
|
28
40
|
}
|
|
41
|
+
export interface LineLayerSpec {
|
|
42
|
+
id: string;
|
|
43
|
+
type: "line";
|
|
44
|
+
source: string;
|
|
45
|
+
filter: ["any", GeometryTypeTest<"LineString">, GeometryTypeTest<"Polygon">];
|
|
46
|
+
paint: {
|
|
47
|
+
"line-color": string;
|
|
48
|
+
"line-width": number;
|
|
49
|
+
"line-opacity": number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export interface CircleLayerSpec {
|
|
53
|
+
id: string;
|
|
54
|
+
type: "circle";
|
|
55
|
+
source: string;
|
|
56
|
+
filter: GeometryTypeTest<"Point">;
|
|
57
|
+
paint: {
|
|
58
|
+
"circle-color": string;
|
|
59
|
+
"circle-radius": number;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export type ShapeLayerSpec = FillLayerSpec | LineLayerSpec | CircleLayerSpec;
|
|
29
63
|
/**
|
|
30
64
|
* Fill, line and point layers for one GeoJSON source. `geometry-type` returns
|
|
31
65
|
* the base type for the Multi types too, so they need no filter of their own.
|
|
32
66
|
* The line layer also matches Polygon, so `color`, `weight` and `opacity` give
|
|
33
67
|
* polygons an outline.
|
|
34
68
|
*/
|
|
35
|
-
export declare function shapeLayerSpecs(sourceId: string, style: ShapeStyle): [
|
|
69
|
+
export declare function shapeLayerSpecs(sourceId: string, style: ShapeStyle): [FillLayerSpec, LineLayerSpec, CircleLayerSpec];
|
|
36
70
|
/** Never throws: anything that is not GeoJSON becomes an empty collection. */
|
|
37
|
-
export declare function asFeatureCollection(value: unknown):
|
|
71
|
+
export declare function asFeatureCollection(value: unknown): FeatureCollection<Geometry | null, JsonObject | null>;
|
|
72
|
+
export {};
|
package/dist/geo/map-layers.js
CHANGED
|
@@ -1,67 +1,93 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { isGeoFeature, isGeoFeatureCollection, isGeoGeometry } from "./geojson.js";
|
|
2
|
+
// src/geo/map-layers.ts
|
|
3
|
+
var DEFAULT_SHAPE_STYLE = {
|
|
4
|
+
color: "#3388ff",
|
|
5
|
+
weight: 3,
|
|
6
|
+
opacity: 1,
|
|
7
|
+
fillOpacity: .2,
|
|
8
|
+
pointColor: "#3b82f6",
|
|
9
|
+
pointRadius: 7
|
|
9
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Fill, line and point layers for one GeoJSON source. `geometry-type` returns
|
|
13
|
+
* the base type for the Multi types too, so they need no filter of their own.
|
|
14
|
+
* The line layer also matches Polygon, so `color`, `weight` and `opacity` give
|
|
15
|
+
* polygons an outline.
|
|
16
|
+
*/
|
|
10
17
|
function shapeLayerSpecs(sourceId, style) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
18
|
+
const color = style.color ?? DEFAULT_SHAPE_STYLE.color;
|
|
19
|
+
return [
|
|
20
|
+
{
|
|
21
|
+
id: `${sourceId}-fill`,
|
|
22
|
+
type: "fill",
|
|
23
|
+
source: sourceId,
|
|
24
|
+
filter: [
|
|
25
|
+
"==",
|
|
26
|
+
["geometry-type"],
|
|
27
|
+
"Polygon"
|
|
28
|
+
],
|
|
29
|
+
paint: {
|
|
30
|
+
"fill-color": style.fillColor ?? color,
|
|
31
|
+
"fill-opacity": style.fillOpacity ?? DEFAULT_SHAPE_STYLE.fillOpacity
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: `${sourceId}-line`,
|
|
36
|
+
type: "line",
|
|
37
|
+
source: sourceId,
|
|
38
|
+
filter: [
|
|
39
|
+
"any",
|
|
40
|
+
[
|
|
41
|
+
"==",
|
|
42
|
+
["geometry-type"],
|
|
43
|
+
"LineString"
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
"==",
|
|
47
|
+
["geometry-type"],
|
|
48
|
+
"Polygon"
|
|
49
|
+
]
|
|
50
|
+
],
|
|
51
|
+
paint: {
|
|
52
|
+
"line-color": color,
|
|
53
|
+
"line-width": style.weight ?? DEFAULT_SHAPE_STYLE.weight,
|
|
54
|
+
"line-opacity": style.opacity ?? DEFAULT_SHAPE_STYLE.opacity
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: `${sourceId}-point`,
|
|
59
|
+
type: "circle",
|
|
60
|
+
source: sourceId,
|
|
61
|
+
filter: [
|
|
62
|
+
"==",
|
|
63
|
+
["geometry-type"],
|
|
64
|
+
"Point"
|
|
65
|
+
],
|
|
66
|
+
paint: {
|
|
67
|
+
"circle-color": style.pointColor ?? DEFAULT_SHAPE_STYLE.pointColor,
|
|
68
|
+
"circle-radius": style.pointRadius ?? DEFAULT_SHAPE_STYLE.pointRadius
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
];
|
|
49
72
|
}
|
|
73
|
+
/** Never throws: anything that is not GeoJSON becomes an empty collection. */
|
|
50
74
|
function asFeatureCollection(value) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
75
|
+
if (isGeoFeatureCollection(value)) return value;
|
|
76
|
+
if (isGeoFeature(value)) return {
|
|
77
|
+
type: "FeatureCollection",
|
|
78
|
+
features: [value]
|
|
79
|
+
};
|
|
80
|
+
if (isGeoGeometry(value)) return {
|
|
81
|
+
type: "FeatureCollection",
|
|
82
|
+
features: [{
|
|
83
|
+
type: "Feature",
|
|
84
|
+
geometry: value,
|
|
85
|
+
properties: {}
|
|
86
|
+
}]
|
|
87
|
+
};
|
|
88
|
+
return {
|
|
89
|
+
type: "FeatureCollection",
|
|
90
|
+
features: []
|
|
91
|
+
};
|
|
62
92
|
}
|
|
63
|
-
export {
|
|
64
|
-
DEFAULT_SHAPE_STYLE,
|
|
65
|
-
asFeatureCollection,
|
|
66
|
-
shapeLayerSpecs
|
|
67
|
-
};
|
|
93
|
+
export { DEFAULT_SHAPE_STYLE, asFeatureCollection, shapeLayerSpecs };
|