@genexus/web-standard-functions
Version:
GeneXus JavaScript standard functions library for web generators
272 lines • 9.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Geography = void 0;
const helpers_1 = require("../misc/helpers");
class Geography {
constructor(str = "") {
this.parse(str);
}
/**
* Return longitude (horizontal) coordinate for the point
* @returns number
*/
get longitude() {
var _a;
return ((_a = this.point) === null || _a === void 0 ? void 0 : _a.longitude) || 0;
}
/**
* Return latitude (vertical) coordinate for the point
* @returns number
*/
get latitude() {
var _a;
return ((_a = this.point) === null || _a === void 0 ? void 0 : _a.latitude) || 0;
}
/**
* Return Spatial Reference System Identifier (SRID), identifies the reference system for the represented Geographic object
* @returns number
*/
get srid() {
(0, helpers_1.notImplemented)("Geography.srid");
return 0;
}
/**
* Return true if the Geography is emtpy
* @returns boolean
*/
isEmpty() {
return this.featureType === "";
}
/**
* Return true if the Geography is null
* @returns boolean
*/
isNull() {
return this.featureType === "";
}
/**
* Set Geography to empty value
*/
setEmpty() {
this.point = undefined;
this.line = undefined;
this.polygon = undefined;
this.featureType = "";
}
/**
* Serializes the object to string (alias for toWkt)
* @returns string
*/
toString() {
return this.toWkt();
}
/**
* Serializes the object to WKT representation
* @returns string
*/
toWkt() {
switch (this.featureType) {
case "POINT":
return `POINT (${this.longitude} ${this.latitude})`;
case "LINE":
return `LINESTRING (${this.line
.map(point => `${point.longitude} ${point.latitude}`)
.join(", ")})`;
case "POLYGON":
return `POLYGON (${this.polygon
.map(ring => `(${ring
.map(point => `${point.longitude} ${point.latitude}`)
.join(", ")})`)
.join(", ")})`;
default:
return "";
}
}
/**
* Serializes the object to GeoJSON representation
* @returns string
*/
toGeoJson() {
let geoJson;
switch (this.featureType) {
case "POINT":
geoJson = {
type: "Point",
coordinates: [this.longitude, this.latitude]
};
break;
case "LINE":
geoJson = {
type: "LineString",
coordinates: this.line.map(point => [point.longitude, point.latitude])
};
break;
case "POLYGON":
geoJson = {
type: "Polygon",
coordinates: this.polygon.map(ring => ring.map(point => [point.longitude, point.latitude]))
};
break;
default:
geoJson = {
type: "GeometryCollection",
coordinates: []
};
break;
}
return JSON.stringify(geoJson);
}
/**
* Return new instance of this Geography object
* @returns Geography
*/
toGeoPoint() {
return this.clone();
}
/**
* Return new instance of this Geography object
* @returns Geography
*/
toGeoLine() {
return this.clone();
}
/**
* Return new instance of this Geography object
* @returns Geography
*/
toGeoPolygon() {
return this.clone();
}
/**
* Load Geography object represented by the WKT text
*/
fromString(str) {
this.parse(str);
}
/**
* Return the distance (in meters) between the current point and the parameter
* @returns number
*/
distance(geo) {
return Geography.distance(this, geo);
}
/**
* Return new instance of this object
* @returns Geography
*/
clone() {
return new Geography(this.toString());
}
/**
* Returns true if the Geographic object parameter includes or intersects the current object
* @returns boolean
*/
intersect(geo) {
return Geography.intersect(this, geo);
}
/**
* Create Geography object represented by the WKT text
* @returns Geography
*/
static fromString(str) {
return new Geography(str);
}
/**
* Return the distance (in meters) between points
* @returns number
*/
static distance(from, to) {
// Haversine formula:
// a = sin(delta_lat/2) + cos(lat1).cos(lat2).sin(delta_long/2)
// c = 2.atan2(sqrt(a), sqrt(1-a))
// d = R.c
if (from.isEmpty() || to.isEmpty())
return 0;
const earthRadius = 6371;
const deltaLatitude = (to.latitude - from.latitude) * (Math.PI / 180);
const deltaLongitude = (to.longitude - from.longitude) * (Math.PI / 180);
const a1 = Math.pow(Math.sin(deltaLatitude / 2), 2);
const a2 = Math.pow(Math.sin(deltaLongitude / 2), 2);
const a3 = Math.cos(from.latitude * (Math.PI / 180)) *
Math.cos(to.latitude * (Math.PI / 180));
const a = a1 + a2 * a3;
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return Math.round(earthRadius * c * 1000); // distance in meters
}
/**
* Returns true if the two Geographic objects instersect.
* @returns boolean
*/
static intersect(a, b) {
(0, helpers_1.notImplemented)("Geography.intersect()");
return false;
}
parse(str) {
const value = str.trim();
this.setEmpty();
if (Geography.GEOGRAPHY_REGEX_TEST_COORDS.test(value)) {
this.parseCoords(value);
}
else if (Geography.GEOGRAPHY_REGEX_TEST_POINT.test(value)) {
this.parsePoint(value);
}
else if (Geography.GEOGRAPHY_REGEX_TEST_LINE.test(value)) {
this.parseLineString(value);
}
else if (Geography.GEOGRAPHY_REGEX_TEST_POLYGON.test(value)) {
this.parsePolygon(value);
}
}
parseCoords(value) {
const result = value.match(Geography.GEOGRAPHY_REGEX_PARSE_COORDS);
this.featureType = "POINT";
this.point = {
longitude: parseFloat(result[2]),
latitude: parseFloat(result[1])
};
}
parsePoint(value) {
const result = value.match(Geography.GEOGRAPHY_REGEX_PARSE_POINT);
this.featureType = "POINT";
this.point = {
longitude: parseFloat(result[1]),
latitude: parseFloat(result[2])
};
}
parseLineString(value) {
const points = value.match(Geography.GEOGRAPHY_REGEX_PARSE_LINE);
this.featureType = "LINE";
this.line = points.map(point => {
const coords = point.match(Geography.GEOGRAPHY_REGEX_PARSE_POINT_COORDS);
return {
longitude: parseFloat(coords[0]),
latitude: parseFloat(coords[1])
};
});
}
parsePolygon(value) {
const rings = value.match(Geography.GEOGRAPHY_REGEX_PARSE_POLYGON);
this.featureType = "POLYGON";
this.polygon = rings.map(ring => {
const points = ring.match(Geography.GEOGRAPHY_REGEX_PARSE_LINE);
return points.map(point => {
const coords = point.match(Geography.GEOGRAPHY_REGEX_PARSE_POINT_COORDS);
return {
longitude: parseFloat(coords[0]),
latitude: parseFloat(coords[1])
};
});
});
}
}
exports.Geography = Geography;
Geography.GEOGRAPHY_REGEX_TEST_COORDS = /^(-?\d*(?:\.\d+)?)(?:\s*,\s*| +)(-?\d*(?:\.\d+)?)$/i; // latitude,longitude
Geography.GEOGRAPHY_REGEX_TEST_POINT = /POINT\s*\(\s*(-?\d*(?:\.\d+)?) +(-?\d*(?:\.\d+)?)\s*\)/i; // POINT(longitude latitude)
Geography.GEOGRAPHY_REGEX_TEST_LINE = /LINESTRING *\( *(?:-?\d*(?:\.\d+)? +-?\d*(?:\.\d+)?(?: *, *| *\)$))+/i; // LINESTRING(longitude latitude,longitude latitude)
Geography.GEOGRAPHY_REGEX_TEST_POLYGON = /POLYGON *\( *(?:\( *(?:-?\d+(?:\.\d+)? +-?\d*(?:\.\d+)?(?: *, *))+-?\d+(?:\.\d+)? +-?\d*(?:\.\d+)? *\)(?: *, *| *\)$))+/i; // POLYGON((longitude latitude,longitude latitude),(longitude latitude,longitude latitude))
Geography.GEOGRAPHY_REGEX_PARSE_COORDS = /(-?\d*(?:\.\d+)?)(?:\s*,\s*| +)(-?\d*(?:\.\d+)?)/i;
Geography.GEOGRAPHY_REGEX_PARSE_POINT = /POINT\s*\(\s*(-?\d*(?:\.\d+)?) +(-?\d*(?:\.\d+)?)\s*\)/i;
Geography.GEOGRAPHY_REGEX_PARSE_POINT_COORDS = /-?\d+(?:\.\d+)?/g;
Geography.GEOGRAPHY_REGEX_PARSE_LINE = /(-?\d+(?:\.\d+)?) +(-?\d*(?:\.\d+)?)/g;
Geography.GEOGRAPHY_REGEX_PARSE_POLYGON = /\(((?:-?\d+(?:\.\d+)?) +(?:-?\d*(?:\.\d+)?)(?: *, *|\)))+/g;
//# sourceMappingURL=geography.js.map