well-known-parser
Version:
A WKT/WKB/EWKT/EWKB/TWKB/GeoJSON parser and serializer
129 lines (98 loc) • 3.28 kB
text/typescript
import { Geometry } from './geometry';
import type { Coordinates, GeometryOptions } from './types';
import { GEOMETRY_TYPES } from './constants';
import { Point } from './point';
import { BinaryWriter } from './binarywriter';
import type { LineString as GeoJSONLineString } from 'geojson';
export class LineString extends Geometry {
points: Point[];
constructor(points?: Point[], srid?: number) {
super();
this.points = points || [];
this.srid = srid;
if (this.points.length > 0) {
this.hasZ = this.points[0].hasZ;
this.hasM = this.points[0].hasM;
}
}
static Z(points?: Point[], srid?: number): LineString {
const lineString = new LineString(points, srid);
lineString.hasZ = true;
return lineString;
}
static M(points?: Point[], srid?: number): LineString {
const lineString = new LineString(points, srid);
lineString.hasM = true;
return lineString;
}
static ZM(points?: Point[], srid?: number): LineString {
const lineString = new LineString(points, srid);
lineString.hasZ = true;
lineString.hasM = true;
return lineString;
}
toWkt(isNested: boolean = false): string {
if (isNested) return this.toInnerWkt();
if (this.points.length === 0) {
return this.getWktType(GEOMETRY_TYPES.LineString.wkt, true);
}
return this.getWktType(GEOMETRY_TYPES.LineString.wkt, false) + this.toInnerWkt();
}
private toInnerWkt(): string {
let innerWkt = '(';
for (const point of this.points) {
innerWkt += point.toWkt(true) + ',';
}
innerWkt = innerWkt.slice(0, -1);
innerWkt += ')';
return innerWkt;
}
toWkb(parentOptions?: GeometryOptions): Buffer {
const wkb = new BinaryWriter(this.getWkbSize());
wkb.writeInt8(1);
this.writeWkbType(wkb, GEOMETRY_TYPES.LineString.wkb, parentOptions);
wkb.writeUInt32LE(this.points.length);
for (const p of this.points) {
wkb.writeBuffer(p.toWkb(parentOptions, true));
}
return wkb.buffer;
}
toTwkb(previousPoint: Point = new Point(0, 0, 0, 0), isNested: boolean = false): Buffer {
const twkb = new BinaryWriter(0, true);
const precision = Geometry.getTwkbPrecision(5, 0, 0);
const isEmpty = this.points.length === 0;
if (!isNested) {
this.writeTwkbHeader(twkb, GEOMETRY_TYPES.LineString.wkb, precision, isEmpty);
}
if (this.points.length > 0) {
twkb.writeVarInt(this.points.length);
for (const p of this.points) {
twkb.writeBuffer(p.toTwkb(previousPoint, true));
}
}
return twkb.buffer;
}
getWkbSize(): number {
let coordinateSize = 16;
if (this.hasZ) {
coordinateSize += 8;
}
if (this.hasM) {
coordinateSize += 8;
}
return 1 + 4 + 4 + this.points.length * coordinateSize;
}
toGeoJSON(): GeoJSONLineString;
toGeoJSON(isNested: true): Coordinates<GeoJSONLineString>;
toGeoJSON(isNested: boolean = false): GeoJSONLineString | Coordinates<GeoJSONLineString> {
const coordinates: Coordinates<GeoJSONLineString> = [];
for (const p of this.points) {
coordinates.push(p.toGeoJSON(true));
}
if (isNested) return coordinates;
return {
type: GEOMETRY_TYPES.LineString.geoJSON,
coordinates,
};
}
}