Skip to content

Commit

Permalink
The feature geometry typings have been updated to accurately support …
Browse files Browse the repository at this point in the history
…the appropriate coordinate types based on the specific geometry type.

Signed-off-by: Tim Deubler <[email protected]>
  • Loading branch information
TerminalTim committed Feb 2, 2024
1 parent eb8bd43 commit 5c6c3ad
Show file tree
Hide file tree
Showing 16 changed files with 58 additions and 41 deletions.
7 changes: 7 additions & 0 deletions packages/common/src/geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,12 @@ export default {
signedArea *= 3;

return signedArea ? [cx / signedArea + x0, cy / signedArea + y0] : [x1, y1];
},

intersectBBox(ax: number, ax2: number, ay: number, ay2: number, bx: number, bx2: number, by: number, by2: number): boolean {
return ax <= bx2 &&
bx <= ax2 &&
ay <= by2 &&
by <= ay2;
}
};
12 changes: 9 additions & 3 deletions packages/core/src/features/Feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import {JSUtils} from '@here/xyz-maps-common';
import {FeatureProvider} from '../providers/FeatureProvider';
import {GeoJSONFeature, GeoJSONBBox} from './GeoJSON';
import {GeoJSONFeature, GeoJSONBBox, GeoJSONCoordinate} from './GeoJSON';

/**
* represents a Feature in GeoJSON Feature format.
Expand Down Expand Up @@ -86,7 +86,13 @@ export class Feature<GeometryType = string> implements GeoJSONFeature<GeometryTy
*/
geometry: {
type: 'Point' | 'MultiPoint' | 'LineString' | 'MultiLineString' | 'Polygon' | 'MultiPolygon' | GeometryType | string,
coordinates: any[]
coordinates: GeometryType extends 'Point' ? GeoJSONCoordinate :
GeometryType extends 'MultiPoint' ? GeoJSONCoordinate[] :
GeometryType extends 'LineString' ? GeoJSONCoordinate[] :
GeometryType extends 'MultiLineString' ? GeoJSONCoordinate[][] :
GeometryType extends 'Polygon' ? GeoJSONCoordinate[][] :
GeometryType extends 'MultiPolygon' ? GeoJSONCoordinate[][][] :
GeoJSONCoordinate | GeoJSONCoordinate[] | GeoJSONCoordinate[][] | GeoJSONCoordinate[][][]
/**
* cached polygon centroid
* @internal
Expand All @@ -106,7 +112,7 @@ export class Feature<GeometryType = string> implements GeoJSONFeature<GeometryTy
// need for quick data merge across multiple tile searches
private _m: number = 0;

constructor(feature: GeoJSONFeature, prov?: FeatureProvider) {
constructor(feature: GeoJSONFeature<GeometryType>, prov?: FeatureProvider) {
this.id = feature.id;

this.properties = feature.properties;
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/features/GeoJSON.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,14 @@ export interface GeoJSONFeature<GeometryType = string> {
*/
geometry: {
type: 'Point' | 'MultiPoint' | 'LineString' | 'MultiLineString' | 'Polygon' | 'MultiPolygon' | GeometryType | string,
coordinates: GeoJSONCoordinate | GeoJSONCoordinate[] | GeoJSONCoordinate[][] | GeoJSONCoordinate[][][]
coordinates: GeometryType extends 'Point' ? GeoJSONCoordinate :
GeometryType extends 'MultiPoint' ? GeoJSONCoordinate[] :
GeometryType extends 'LineString' ? GeoJSONCoordinate[] :
GeometryType extends 'MultiLineString' ? GeoJSONCoordinate[][] :
GeometryType extends 'Polygon' ? GeoJSONCoordinate[][] :
GeometryType extends 'MultiPolygon' ? GeoJSONCoordinate[][][] :
GeoJSONCoordinate | GeoJSONCoordinate[] | GeoJSONCoordinate[][] | GeoJSONCoordinate[][][]
// coordinates: GeoJSONCoordinate | GeoJSONCoordinate[] | GeoJSONCoordinate[][] | GeoJSONCoordinate[][][]
};
}

Expand Down
12 changes: 7 additions & 5 deletions packages/core/src/features/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
*/

import {Feature} from '../features/Feature';
type Point = [number, number, number?];
import {GeoJSONCoordinate} from '@here/xyz-maps-core';
type Point = number[];
type BBox = number[];
type Coordinates = Array<Point>;

Expand Down Expand Up @@ -57,29 +58,30 @@ const updateLineStringBBox = (lineString: Coordinates, bbox?: BBox) => {

const calcBBox = (feature: Feature, bbox?: BBox): BBox | false => {
const geoType = feature.geometry.type;
const coordinates = feature.geometry.coordinates;

if (geoType == 'Point') {
const coordinates = (<Feature<'Point'>>feature).geometry.coordinates;
if (bbox) {
updatePointBBox(<[number, number]>coordinates, bbox);
} else {
bbox = [coordinates[0], coordinates[1], coordinates[0], coordinates[1]];
}
} else {
bbox = bbox || [Infinity, Infinity, -Infinity, -Infinity];
const coordinates = feature.geometry.coordinates;

if (geoType == 'MultiLineString') {
for (let ls = 0; ls < coordinates.length; ls++) {
updateLineStringBBox(coordinates[ls], bbox);
updateLineStringBBox((coordinates as GeoJSONCoordinate[][])[ls], bbox);
}
} else if (geoType == 'MultiPolygon') {
for (let p = 0; p < coordinates.length; p++) {
updateLineStringBBox(coordinates[p][0], bbox);
}
} else if (geoType == 'LineString' || geoType == 'MultiPoint') {
updateLineStringBBox(coordinates, bbox);
updateLineStringBBox((coordinates as GeoJSONCoordinate[]), bbox);
} else if (geoType == 'Polygon') {
updateLineStringBBox(coordinates[0], bbox);
updateLineStringBBox((coordinates as GeoJSONCoordinate[][])[0], bbox);
} else {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/providers/FeatureProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ export class FeatureProvider extends Provider {
const start = {distance: Infinity, feature: null, point: null, index: null};
for (let feature of features) {
if (feature.geometry.type != 'LineString') continue;
const {coordinates} = feature.geometry;
const coordinates = feature.geometry.coordinates as GeoJSONCoordinate[];
const last = coordinates.length - 1;
const result = findNearestCoordinate(point, [coordinates[0], coordinates[last]]);
if (result.distance < start.distance) {
Expand Down
4 changes: 2 additions & 2 deletions packages/display/src/displays/webgl/buffer/createBuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import {geometry, TaskManager} from '@here/xyz-maps-common';
import {GeometryBuffer} from './GeometryBuffer';
import {getValue, parseStyleGroup} from '../../styleTools';
import {Feature, LinearGradient, StyleGroup, Tile, TileLayer, webMercator} from '@here/xyz-maps-core';
import {Feature, GeoJSONCoordinate, LinearGradient, StyleGroup, Tile, TileLayer, webMercator} from '@here/xyz-maps-core';
import {Layer} from '../../Layers';
import {CollisionGroup, FeatureFactory, GroupMap} from './FeatureFactory';
import {GlyphTexture} from '../GlyphTexture';
Expand Down Expand Up @@ -72,7 +72,7 @@ const handlePolygons = (

if (anchor == 'Centroid') {
const {geometry} = feature;
center = geometry._c = geometry._c || centroid(geometry.type == 'Polygon' ? geometry.coordinates : geometry.coordinates[0]);
center = geometry._c = geometry._c || centroid(<GeoJSONCoordinate[][]>(geometry.type == 'Polygon' ? geometry.coordinates : geometry.coordinates[0]));
} else {
center = [bbox[0] + (bbox[2] - bbox[0]) / 2, bbox[1] + (bbox[3] - bbox[1]) / 2];
}
Expand Down
6 changes: 3 additions & 3 deletions packages/display/src/geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* License-Filename: LICENSE
*/

import {geometry} from '@here/xyz-maps-common';

let UNDEF;

export type Point = number[];
Expand Down Expand Up @@ -104,9 +106,7 @@ export const isInBox = (x: number, y: number, xmin: number, ymin: number, xmax:
};


export const intersectBBox = (ax: number, ax2: number, ay: number, ay2: number, bx: number, bx2: number, by: number, by2: number): boolean => {
return ax <= bx2 && bx <= ax2 && ay <= by2 && by <= ay2;
};
export const intersectBBox = geometry.intersectBBox;

export const getDistance = (p1x: number, p1y: number, p2x: number, p2y: number): number => {
const dx = p1x - p2x;
Expand Down
2 changes: 1 addition & 1 deletion packages/display/src/search/Hit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {Map} from '../Map';
import {Feature} from '@here/xyz-maps-core';
import {intersectBBox, intersectLineLine} from '../geometry';

type Point = [number, number, number?];
type Point = number[]; // [number, number, number?];
type Coordinates = Point | Point[] | Point[][] | Point[][][];

const pointInPolygon = (x: number, y: number, poly: Point[]): boolean => {
Expand Down
4 changes: 2 additions & 2 deletions packages/editor/src/features/Overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ class Overlay {
addRect(minLon: number, minLat: number, maxLon: number, maxLat: number, properties) {
return this.addFeature(
createFeature('Polygon', createRect(minLon, minLat, maxLon, maxLat), properties)
);
) as Feature<'Polygon'>;
}


Expand Down Expand Up @@ -214,7 +214,7 @@ class Overlay {
},
type: 'Feature',
properties: props || {}
}, prepareStyle(style));
}, prepareStyle(style)) as Feature<'LineString'>;
}


Expand Down
6 changes: 3 additions & 3 deletions packages/editor/src/features/area/AreaShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ let UNDEF;
* The AreaShape is only existing if the corresponding Area feature is "selected" and user based geometry editing with touch/mouse interaction is activated.
* @see {@link Area.select}
*/
class AreaShape extends Feature {
class AreaShape extends Feature<'Point'> {
/**
* The feature class of an AreaShape Feature is "AREA_SHAPE".
*/
Expand All @@ -185,14 +185,14 @@ class AreaShape extends Feature {
index: number;
hole: number;
poly: number;
}
};

constructor(area: Area, x: number, y: number, indexData: number[], polyTools) {
polygonTools = polyTools;

const internalEditor: InternalEditor = area._e();
const zLayer = internalEditor.display.getLayers().indexOf(internalEditor.getLayer(area)) + 1;
const geojson: GeoJSONFeature = {
const geojson: GeoJSONFeature<'Point'> = {
type: 'Feature',
geometry: {
type: 'Point',
Expand Down
6 changes: 3 additions & 3 deletions packages/editor/src/features/area/HeightKnob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ const getAreaCenter = (area: Area): number[] => {
};


class HeightKnob extends Feature {
class HeightKnob extends Feature<'Point'> {
__: PrivateData;

properties: {}
properties: {};

constructor(area: Area, altitude: number, polyTools) {
polygonTools = polyTools;
Expand All @@ -71,7 +71,7 @@ class HeightKnob extends Feature {

const [lon, lat] = getAreaCenter(area);

const geojson: GeoJSONFeature = {
const geojson: GeoJSONFeature<'Point'> = {
type: 'Feature',
geometry: {
type: 'Point',
Expand Down
2 changes: 1 addition & 1 deletion packages/editor/src/features/link/VirtualShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type VirtualLinkShapeProperties = {
parent: Navlink
};

class VirtualLinkShape extends Feature {
class VirtualLinkShape extends Feature<'Point'> {
id: string;
private x: number;
private y: number;
Expand Down
9 changes: 2 additions & 7 deletions packages/editor/src/geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import {GeoJSONCoordinate as Point} from '@here/xyz-maps-core';
import {geotools, vec3} from '@here/xyz-maps-common';
import {geometry, geotools, vec3} from '@here/xyz-maps-common';


const MATH = Math;
Expand Down Expand Up @@ -63,12 +63,7 @@ export const isPntInRect = (px: number, py: number, x1: number, y1: number, x2:
return px >= x1 && px <= x2 && py >= y1 && py <= y2;
};

export const intersectBBox = (ax: number, ax2: number, ay: number, ay2: number, bx: number, bx2: number, by: number, by2: number) => {
return ax <= bx2 &&
bx <= ax2 &&
ay <= by2 &&
by <= ay2;
};
export const intersectBBox = geometry.intersectBBox;

export const getAngle = (p1: Point, p2: Point): number => {
const dx = p2[0] - p1[0];
Expand Down
2 changes: 1 addition & 1 deletion packages/editor/src/tools/rangeSelector/RangeMarker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function getPointAtLine(
}


class RangeMarker extends Feature {
class RangeMarker extends Feature<'Point'> {
static initStyle(styleGroup: MarkerStyle[]): MarkerStyle[] {
styleGroup = JSUtils.clone(styleGroup);
for (let style of styleGroup) {
Expand Down
8 changes: 4 additions & 4 deletions packages/editor/src/tools/transformer/Knob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import InternalEditor from '../../IEditor';
import Overlay from '../../features/Overlay';
import Transformer from './Transformer';

export class Knob extends Feature {
protected _o: Overlay
protected __: { [ev: string]: (e, dx?: number, dy?: number) => void }
export class Knob extends Feature<'Point'> {
protected _o: Overlay;
protected __: { [ev: string]: (e, dx?: number, dy?: number) => void };
protected transformer: Transformer;

constructor(
Expand All @@ -34,7 +34,7 @@ export class Knob extends Feature {
properties = {},
style?: Style | Style[]
) {
const geojson: GeoJSONFeature = {
const geojson: GeoJSONFeature<'Point'> = {
type: 'Feature',
geometry: {
type: 'Point',
Expand Down
8 changes: 4 additions & 4 deletions packages/editor/src/tools/transformer/ScaleBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* License-Filename: LICENSE
*/

import {Feature, Style} from '@here/xyz-maps-core';
import {Feature, GeoJSONCoordinate, Style} from '@here/xyz-maps-core';
import Overlay from '../../features/Overlay';
import InternalEditor from '../../IEditor';
import Transformer, {Corner} from './Transformer';
Expand Down Expand Up @@ -55,7 +55,7 @@ class ScaleBox {

this.buffer = buffer;

const selectors = [
const selectors: Feature<'Polygon'|'LineString'>[] = [
overlay.addRect(0, 0, 0, 0, {
type: 'TRANSFORMER_SCALE_BOX'
})
Expand Down Expand Up @@ -85,7 +85,7 @@ class ScaleBox {
const {index, vertical} = this.properties;

let i: Corner = index == Corner.topLeft ? Corner.bottomLeft : index - 1;
let line = selectors[i + 1].geometry.coordinates;
let line = selectors[i + 1].geometry.coordinates as GeoJSONCoordinate[];
// const [line0, line1] = transformer.getRotatedBoundingBox(true)[i];

if (flipped) {
Expand Down Expand Up @@ -147,7 +147,7 @@ class ScaleBox {

const {index, vertical} = this.properties;
const i: Corner = index == Corner.topLeft ? Corner.bottomLeft : index - 1;
const [line0, line1] = selectors[i + 1].geometry.coordinates;
const [line0, line1] = selectors[i + 1].geometry.coordinates as GeoJSONCoordinate[];
// [line0, line1] = transformer.getRotatedBoundingBox(true)[i];

let line0px = map.getPixelCoord(line0);
Expand Down

0 comments on commit 5c6c3ad

Please sign in to comment.