module.exports = Point; var util = require('util'); var Geometry = require('./geometry'); var Types = require('./types'); var BinaryWriter = require('./binarywriter'); var ZigZag = require('./zigzag.js'); function Point(x, y, z, m, srid) { Geometry.call(this); this.x = x; this.y = y; this.z = z; this.m = m; this.srid = srid; this.hasZ = typeof this.z !== 'undefined'; this.hasM = typeof this.m !== 'undefined'; } util.inherits(Point, Geometry); Point.Z = function (x, y, z, srid) { var point = new Point(x, y, z, undefined, srid); point.hasZ = true; return point; }; Point.M = function (x, y, m, srid) { var point = new Point(x, y, undefined, m, srid); point.hasM = true; return point; }; Point.ZM = function (x, y, z, m, srid) { var point = new Point(x, y, z, m, srid); point.hasZ = true; point.hasM = true; return point; }; Point._parseWkt = function (value, options) { var point = new Point(); point.srid = options.srid; point.hasZ = options.hasZ; point.hasM = options.hasM; if (value.isMatch(['EMPTY'])) return point; value.expectGroupStart(); var coordinate = value.matchCoordinate(options); point.x = coordinate.x; point.y = coordinate.y; point.z = coordinate.z; point.m = coordinate.m; value.expectGroupEnd(); return point; }; Point._parseWkb = function (value, options) { var point = Point._readWkbPoint(value, options); point.srid = options.srid; return point; }; Point._readWkbPoint = function (value, options) { return new Point(value.readDouble(), value.readDouble(), options.hasZ ? value.readDouble() : undefined, options.hasM ? value.readDouble() : undefined); }; Point._parseTwkb = function (value, options) { var point = new Point(); point.hasZ = options.hasZ; point.hasM = options.hasM; if (options.isEmpty) return point; point.x = ZigZag.decode(value.readVarInt()) / options.precisionFactor; point.y = ZigZag.decode(value.readVarInt()) / options.precisionFactor; point.z = options.hasZ ? ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor : undefined; point.m = options.hasM ? ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor : undefined; return point; }; Point._readTwkbPoint = function (value, options, previousPoint) { previousPoint.x += ZigZag.decode(value.readVarInt()) / options.precisionFactor; previousPoint.y += ZigZag.decode(value.readVarInt()) / options.precisionFactor; if (options.hasZ) previousPoint.z += ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor; if (options.hasM) previousPoint.m += ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor; return new Point(previousPoint.x, previousPoint.y, previousPoint.z, previousPoint.m); }; Point._parseGeoJSON = function (value) { return Point._readGeoJSONPoint(value.coordinates); }; Point._readGeoJSONPoint = function (coordinates) { if (coordinates.length === 0) return new Point(); if (coordinates.length > 2) return new Point(coordinates[0], coordinates[1], coordinates[2]); return new Point(coordinates[0], coordinates[1]); }; Point.prototype.toWkt = function () { if (typeof this.x === 'undefined' && typeof this.y === 'undefined' && typeof this.z === 'undefined' && typeof this.m === 'undefined') return this._getWktType(Types.wkt.Point, true); return this._getWktType(Types.wkt.Point, false) + '(' + this._getWktCoordinate(this) + ')'; }; Point.prototype.toWkb = function (parentOptions) { var wkb = new BinaryWriter(this._getWkbSize()); wkb.writeInt8(1); this._writeWkbType(wkb, Types.wkb.Point, parentOptions); if (typeof this.x === 'undefined' && typeof this.y === 'undefined') { wkb.writeDoubleLE(NaN); wkb.writeDoubleLE(NaN); if (this.hasZ) wkb.writeDoubleLE(NaN); if (this.hasM) wkb.writeDoubleLE(NaN); } else { this._writeWkbPoint(wkb); } return wkb.buffer; }; Point.prototype._writeWkbPoint = function (wkb) { wkb.writeDoubleLE(this.x); wkb.writeDoubleLE(this.y); if (this.hasZ) wkb.writeDoubleLE(this.z); if (this.hasM) wkb.writeDoubleLE(this.m); }; Point.prototype.toTwkb = function () { var twkb = new BinaryWriter(0, true); var precision = Geometry.getTwkbPrecision(5, 0, 0); var isEmpty = typeof this.x === 'undefined' && typeof this.y === 'undefined'; this._writeTwkbHeader(twkb, Types.wkb.Point, precision, isEmpty); if (!isEmpty) this._writeTwkbPoint(twkb, precision, new Point(0, 0, 0, 0)); return twkb.buffer; }; Point.prototype._writeTwkbPoint = function (twkb, precision, previousPoint) { var x = this.x * precision.xyFactor; var y = this.y * precision.xyFactor; var z = this.z * precision.zFactor; var m = this.m * precision.mFactor; twkb.writeVarInt(ZigZag.encode(x - previousPoint.x)); twkb.writeVarInt(ZigZag.encode(y - previousPoint.y)); if (this.hasZ) twkb.writeVarInt(ZigZag.encode(z - previousPoint.z)); if (this.hasM) twkb.writeVarInt(ZigZag.encode(m - previousPoint.m)); previousPoint.x = x; previousPoint.y = y; previousPoint.z = z; previousPoint.m = m; }; Point.prototype._getWkbSize = function () { var size = 1 + 4 + 8 + 8; if (this.hasZ) size += 8; if (this.hasM) size += 8; return size; }; Point.prototype.toGeoJSON = function (options) { var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); geoJSON.type = Types.geoJSON.Point; if (typeof this.x === 'undefined' && typeof this.y === 'undefined') geoJSON.coordinates = []; else if (typeof this.z !== 'undefined') geoJSON.coordinates = [this.x, this.y, this.z]; else geoJSON.coordinates = [this.x, this.y]; return geoJSON; };