Skip to content

Commit

Permalink
chore(gis): Clean up API and extract common helpers (#3147)
Browse files Browse the repository at this point in the history
  • Loading branch information
ibgreen authored Oct 20, 2024
1 parent 6e2afc4 commit cd64ff1
Show file tree
Hide file tree
Showing 40 changed files with 582 additions and 300 deletions.
40 changes: 20 additions & 20 deletions modules/gis/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ export {
} from './lib/geoarrow/geoparquet-metadata';
export {unpackJSONStringMetadata} from './lib/geoarrow/geoparquet-metadata';

// Utilities
export {transformBinaryCoords, transformGeoJsonCoords} from './lib/api/transform-coordinates';
//
export type {GeojsonGeometryInfo} from './lib/geometry-api/geometry-info';
export {getGeometryInfo} from './lib/geometry-api/geometry-info';

// Binary Geometries
// export {flatGeojsonToBinary} from './lib/binary-features/flat-geojson-to-binary';
// export {geojsonToBinary} from './lib/binary-features/geojson-to-binary';
// export {geojsonToFlatGeojson} from './lib/binary-features/geojson-to-flat-geojson';
// export {binaryToGeojson, binaryToGeometry} from './lib/binary-features/binary-to-geojson';
// Binary Geometry Utilities
export type {BinaryGeometryInfo} from './lib/binary-geometry-api/binary-geometry-info';
export {getBinaryGeometryInfo} from './lib/binary-geometry-api/binary-geometry-info';
export {
transformBinaryCoords,
transformGeoJsonCoords
} from './lib/binary-geometry-api/transform-coordinates';

// TABLE CONVERSION
export {convertGeoArrowToTable} from './lib/table-converters/convert-geoarrow-table';
Expand Down Expand Up @@ -48,24 +51,22 @@ export {
} from './lib/feature-collection-converters/convert-binary-features-to-geojson';

// GEOMETRY ENCODING DETECTION
export {isTWKB} from './lib/geometry-converters/wkt/convert-twkb-to-geojson';
export {isWKB} from './lib/geometry-converters/wkt/helpers/parse-wkb-header';
export {isWKT} from './lib/geometry-converters/wkt/convert-wkt-to-geojson';
export {isWKB, isTWKB, isWKT} from './lib/geometry-converters/wkb/helpers/parse-wkb-header';

export type {WKBHeader} from './lib/geometry-converters/wkt/helpers/parse-wkb-header';
export {WKT_MAGIC_STRINGS} from './lib/geometry-converters/wkt/convert-wkt-to-geojson';
export type {WKBHeader} from './lib/geometry-converters/wkb/helpers/wkb-types';
export {WKT_MAGIC_STRINGS} from './lib/geometry-converters/wkb/helpers/wkb-types';

// GEOMETRY CONVERSION
export {convertBinaryGeometryToGeometry} from './lib/geometry-converters/convert-binary-geometry-to-geojson';

export {convertWKTToGeometry} from './lib/geometry-converters/wkt/convert-wkt-to-geojson';
export {convertWKBToGeometry} from './lib/geometry-converters/wkt/convert-wkb-to-geojson';
export {convertWKBToBinaryGeometry} from './lib/geometry-converters/wkt/convert-wkb-to-binary-geometry';
export {convertTWKBToGeometry} from './lib/geometry-converters/wkt/convert-twkb-to-geojson';
export {convertWKTToGeometry} from './lib/geometry-converters/wkb/convert-wkt-to-geometry';
export {convertWKBToGeometry} from './lib/geometry-converters/wkb/convert-wkb-to-geometry';
export {convertWKBToBinaryGeometry} from './lib/geometry-converters/wkb/convert-wkb-to-binary-geometry';
export {convertTWKBToGeometry} from './lib/geometry-converters/wkb/convert-twkb-to-geometry';

export {convertGeometryToWKT} from './lib/geometry-converters/wkt/convert-geojson-to-wkt';
export {convertGeometryToWKB} from './lib/geometry-converters/wkt/convert-geojson-to-wkb';
export {convertGeometryToTWKB} from './lib/geometry-converters/wkt/convert-geojson-to-twkb';
export {convertGeometryToWKT} from './lib/geometry-converters/wkb/convert-geometry-to-wkt';
export {convertGeometryToWKB} from './lib/geometry-converters/wkb/convert-geometry-to-wkb';
export {convertGeometryToTWKB} from './lib/geometry-converters/wkb/convert-geometry-to-twkb';

// CRS
export type {WKTCRS, ParseWKTCRSOptions} from './lib//wkt-crs/parse-wkt-crs';
Expand Down Expand Up @@ -94,5 +95,4 @@ export {updateBoundsFromGeoArrowSamples} from './lib/geoarrow/get-arrow-bounds';
// EXPERIMENTAL APIs

export {encodeHex, decodeHex} from './lib/utils/hex-transcoder';
export {extractGeometryInfo as _extractGeometryInfo} from './lib/feature-collection-converters/helpers/extract-geometry-info';
export {extractNumericPropTypes as _extractNumericPropTypes} from './lib/feature-collection-converters/convert-flat-geojson-to-binary-features';
75 changes: 75 additions & 0 deletions modules/gis/src/lib/binary-geometry-api/binary-geometry-info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// loaders.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors

import type {BinaryGeometry} from '@loaders.gl/schema';

/**
* Information about a binary geometry
*/
export type BinaryGeometryInfo = {
/** The GeoJSON style geometry type corresponding to this particular binary geometry */
multiGeometryType:
| 'Point'
| 'LineString'
| 'Polygon'
| 'MultiPoint'
| 'MultiLineString'
| 'MultiPolygon';
/** Is this a "Multi" version of the binary geometry? */
isMultiGeometry: boolean;
/** How many dimensions are the coordinates? */
dimension: number;
/** How many points does this geometry have? */
pointCount: number;
/** How many coordinates does this geometry have? */
coordinateCount: number;
};

/**
* @returns information about a binary geometry
*/
export function getBinaryGeometryInfo(geometry: BinaryGeometry): BinaryGeometryInfo {
return {
isMultiGeometry: isMultiGeometryType(geometry),
multiGeometryType: getMultiGeometryType(geometry),
dimension: geometry.positions.size,
pointCount: geometry.positions.value.length / geometry.positions.size,
coordinateCount: geometry.positions.value.length
};
}

/** @returns true if a binary geometry corresponds to a MultiPoint, MultiLineString or MultiPolygon */
function isMultiGeometryType(geometry: BinaryGeometry) {
switch (geometry.type) {
case 'Point':
const {positions} = geometry;
return positions.value.length / positions.size > 1;
case 'LineString':
const {pathIndices} = geometry;
return pathIndices.value.length > 1;
case 'Polygon':
const {polygonIndices} = geometry;
return polygonIndices.value.length > 1;
default:
return false;
}
}

/**
* @returns geometry type of binary geometry, including MultiPoint, MultiLineString or MultiPolygon
*/
function getMultiGeometryType(geometry: BinaryGeometry) {
const isMulti = isMultiGeometryType(geometry);
switch (geometry.type) {
case 'Point':
return isMulti ? 'MultiPoint' : 'Point';
case 'LineString':
return isMulti ? 'MultiLineString' : 'LineString';
case 'Polygon':
return isMulti ? 'MultiPolygon' : 'Polygon';
default:
// @ts-expect-error
throw new Error(`Illegal geometry type: ${type}`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ function transformBinaryGeometryPositions(binaryGeometry: BinaryGeometry, fn: Tr

/**
* Apply transformation to every coordinate of GeoJSON features
*
* @param features Array of GeoJSON features
* @param fn Function to call on each coordinate
* @return Transformed GeoJSON features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import type {
FlatPoint,
FlatLineString,
FlatPolygon,
GeojsonGeometryInfo,
TypedArray
} from '@loaders.gl/schema';
import {GeojsonGeometryInfo} from '../geometry-api/geometry-info';
import {
PropArrayConstructor,
Lines,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import type {Feature, BinaryFeatureCollection} from '@loaders.gl/schema';

import {extractGeometryInfo} from './helpers/extract-geometry-info';
import {getGeometryInfo} from '../geometry-api/geometry-info';
import {convertGeojsonToFlatGeojson} from './convert-geojson-to-flat-geojson';
import {convertFlatGeojsonToBinaryFeatureCollection} from './convert-flat-geojson-to-binary-features';

Expand All @@ -29,7 +29,7 @@ export function convertGeojsonToBinaryFeatureCollection(
features: Feature[],
options: GeojsonToBinaryOptions = {fixRingWinding: true, triangulate: true}
): BinaryFeatureCollection {
const geometryInfo = extractGeometryInfo(features);
const geometryInfo = getGeometryInfo(features);
const coordLength = geometryInfo.coordLength;
const {fixRingWinding} = options;
const flatFeatures = convertGeojsonToFlatGeojson(features, {coordLength, fixRingWinding});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,29 @@
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors

import type {Feature, GeojsonGeometryInfo} from '@loaders.gl/schema';
import type {Feature} from '@loaders.gl/schema';

/** Aggregate information for converting GeoJSON into other formats */
export type GeojsonGeometryInfo = {
coordLength: number;
pointPositionsCount: number;
pointFeaturesCount: number;
linePositionsCount: number;
linePathsCount: number;
lineFeaturesCount: number;
polygonPositionsCount: number;
polygonObjectsCount: number;
polygonRingsCount: number;
polygonFeaturesCount: number;
};

/**
* Initial scan over GeoJSON features
* Counts number of coordinates of each geometry type and
* keeps track of the max coordinate dimensions
*/
// eslint-disable-next-line complexity, max-statements
export function extractGeometryInfo(features: Feature[]): GeojsonGeometryInfo {
export function getGeometryInfo(features: Feature[]): GeojsonGeometryInfo {
// Counts the number of _positions_, so [x, y, z] counts as one
let pointPositionsCount = 0;
let pointFeaturesCount = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import type {
Geometry,
GeoArrowEncoding
} from '@loaders.gl/schema';
import {convertWKBToGeometry} from './wkt/convert-wkb-to-geojson';
import {convertWKTToGeometry} from './wkt/convert-wkt-to-geojson';
import {convertWKBToGeometry} from './wkb/convert-wkb-to-geometry';
import {convertWKTToGeometry} from './wkb/convert-wkt-to-geometry';

/**
* parse geometry from arrow data that is returned from processArrowData()
Expand Down
8 changes: 4 additions & 4 deletions modules/gis/src/lib/geometry-converters/convert-to-geojson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

import type {Geometry, BinaryGeometry} from '@loaders.gl/schema';

import {convertGeometryToWKB} from './wkt/convert-geojson-to-wkb';
import {convertGeometryToWKT} from './wkt/convert-geojson-to-wkt';
import {convertWKBToBinaryGeometry} from './wkt/convert-wkb-to-binary-geometry';
import {convertWKTToGeometry} from './wkt/convert-wkt-to-geojson';
import {convertGeometryToWKB} from './wkb/convert-geometry-to-wkb';
import {convertGeometryToWKT} from './wkb/convert-geometry-to-wkt';
import {convertWKBToBinaryGeometry} from './wkb/convert-wkb-to-binary-geometry';
import {convertWKTToGeometry} from './wkb/convert-wkt-to-geometry';

import {convertBinaryGeometryToGeometry} from './convert-binary-geometry-to-geojson';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {
} from '@loaders.gl/schema';

import {BinaryWriter} from '../../utils/binary-writer';
import {WKBGeometryType} from './helpers/parse-wkb-header';
import {WKBGeometryType} from './helpers/wkb-types';

type TWKBPrecision = {
xy: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,9 @@ import type {
MultiPolygon,
GeometryCollection
} from '@loaders.gl/schema';

import {WKBGeometryType, WKBOptions} from './helpers/wkb-types';
import {BinaryWriter} from '../../utils/binary-writer';

/**
* Integer code for geometry type
* Reference: https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary
*/
export enum WKB {
Point = 1,
LineString = 2,
Polygon = 3,
MultiPoint = 4,
MultiLineString = 5,
MultiPolygon = 6,
GeometryCollection = 7
}

/**
* Options for encodeWKB
*/
type WKBOptions = {
/** Does the GeoJSON input have Z values? */
hasZ?: boolean;

/** Does the GeoJSON input have M values? */
hasM?: boolean;

/** Spatial reference for input GeoJSON */
srid?: any;
};

/**
* Encodes a GeoJSON object into WKB
* @param geojson A GeoJSON Feature or Geometry
Expand Down Expand Up @@ -108,7 +80,7 @@ function encodePoint(coordinates: Point['coordinates'], options: WKBOptions): Ar
const writer = new BinaryWriter(getPointSize(options));

writer.writeInt8(1);
writeWkbType(writer, WKB.Point, options);
writeWkbType(writer, WKBGeometryType.Point, options);

// I believe this special case is to handle writing Point(NaN, NaN) correctly
if (typeof coordinates[0] === 'undefined' && typeof coordinates[1] === 'undefined') {
Expand Down Expand Up @@ -162,7 +134,7 @@ function encodeLineString(

writer.writeInt8(1);

writeWkbType(writer, WKB.LineString, options);
writeWkbType(writer, WKBGeometryType.LineString, options);
writer.writeUInt32LE(coordinates.length);

for (const coordinate of coordinates) {
Expand All @@ -185,7 +157,7 @@ function encodePolygon(coordinates: Polygon['coordinates'], options: WKBOptions)

writer.writeInt8(1);

writeWkbType(writer, WKB.Polygon, options);
writeWkbType(writer, WKBGeometryType.Polygon, options);
const [exteriorRing = [], ...interiorRings] = coordinates;

if (exteriorRing.length > 0) {
Expand Down Expand Up @@ -235,7 +207,7 @@ function encodeMultiPoint(multiPoint: MultiPoint, options: WKBOptions) {

writer.writeInt8(1);

writeWkbType(writer, WKB.MultiPoint, options);
writeWkbType(writer, WKBGeometryType.MultiPoint, options);
writer.writeUInt32LE(points.length);

for (const point of points) {
Expand Down Expand Up @@ -265,7 +237,7 @@ function encodeMultiLineString(multiLineString: MultiLineString, options: WKBOpt

writer.writeInt8(1);

writeWkbType(writer, WKB.MultiLineString, options);
writeWkbType(writer, WKBGeometryType.MultiLineString, options);
writer.writeUInt32LE(lineStrings.length);

for (const lineString of lineStrings) {
Expand Down Expand Up @@ -295,7 +267,7 @@ function encodeMultiPolygon(multiPolygon: MultiPolygon, options: WKBOptions): Ar

writer.writeInt8(1);

writeWkbType(writer, WKB.MultiPolygon, options);
writeWkbType(writer, WKBGeometryType.MultiPolygon, options);
writer.writeUInt32LE(polygons.length);

for (const polygon of polygons) {
Expand Down Expand Up @@ -325,7 +297,7 @@ function encodeGeometryCollection(

writer.writeInt8(1);

writeWkbType(writer, WKB.GeometryCollection, options);
writeWkbType(writer, WKBGeometryType.GeometryCollection, options);
writer.writeUInt32LE(collection.geometries.length);

for (const geometry of collection.geometries) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type {
MultiPolygon
} from '@loaders.gl/schema';
import {BinaryReader} from '../../utils/binary-reader';
import {WKBGeometryType} from './helpers/parse-wkb-header';
import {WKBGeometryType} from './helpers/wkb-types';

/**
* Check if an array buffer might be a TWKB array buffer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import {
concatenateBinaryPointGeometries,
concatenateBinaryLineGeometries,
concatenateBinaryPolygonGeometries
} from '../../api/binary-geometry-utils';
import {parseWKBHeader, WKBGeometryType} from './helpers/parse-wkb-header';
} from '../../binary-geometry-api/concat-binary-geometry';
import {concatTypedArrays} from '../../utils/concat-typed-arrays';
import {WKBGeometryType} from './helpers/wkb-types';
import {parseWKBHeader} from './helpers/parse-wkb-header';

export function convertWKBToBinaryGeometry(arrayBuffer: ArrayBuffer): BinaryGeometry {
const dataView = new DataView(arrayBuffer);
Expand Down
Loading

0 comments on commit cd64ff1

Please sign in to comment.