You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.4 KiB
124 lines
3.4 KiB
module.exports = WktParser; |
|
|
|
var Types = require('./types'); |
|
var Point = require('./point'); |
|
|
|
function WktParser(value) { |
|
this.value = value; |
|
this.position = 0; |
|
} |
|
|
|
WktParser.prototype.match = function (tokens) { |
|
this.skipWhitespaces(); |
|
|
|
for (var i = 0; i < tokens.length; i++) { |
|
if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { |
|
this.position += tokens[i].length; |
|
return tokens[i]; |
|
} |
|
} |
|
|
|
return null; |
|
}; |
|
|
|
WktParser.prototype.matchRegex = function (tokens) { |
|
this.skipWhitespaces(); |
|
|
|
for (var i = 0; i < tokens.length; i++) { |
|
var match = this.value.substring(this.position).match(tokens[i]); |
|
|
|
if (match) { |
|
this.position += match[0].length; |
|
return match; |
|
} |
|
} |
|
|
|
return null; |
|
}; |
|
|
|
WktParser.prototype.isMatch = function (tokens) { |
|
this.skipWhitespaces(); |
|
|
|
for (var i = 0; i < tokens.length; i++) { |
|
if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { |
|
this.position += tokens[i].length; |
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
}; |
|
|
|
WktParser.prototype.matchType = function () { |
|
var geometryType = this.match([Types.wkt.Point, Types.wkt.LineString, Types.wkt.Polygon, Types.wkt.MultiPoint, |
|
Types.wkt.MultiLineString, Types.wkt.MultiPolygon, Types.wkt.GeometryCollection]); |
|
|
|
if (!geometryType) |
|
throw new Error('Expected geometry type'); |
|
|
|
return geometryType; |
|
}; |
|
|
|
WktParser.prototype.matchDimension = function () { |
|
var dimension = this.match(['ZM', 'Z', 'M']); |
|
|
|
switch (dimension) { |
|
case 'ZM': return { hasZ: true, hasM: true }; |
|
case 'Z': return { hasZ: true, hasM: false }; |
|
case 'M': return { hasZ: false, hasM: true }; |
|
default: return { hasZ: false, hasM: false }; |
|
} |
|
}; |
|
|
|
WktParser.prototype.expectGroupStart = function () { |
|
if (!this.isMatch(['('])) |
|
throw new Error('Expected group start'); |
|
}; |
|
|
|
WktParser.prototype.expectGroupEnd = function () { |
|
if (!this.isMatch([')'])) |
|
throw new Error('Expected group end'); |
|
}; |
|
|
|
WktParser.prototype.matchCoordinate = function (options) { |
|
var match; |
|
|
|
if (options.hasZ && options.hasM) |
|
match = this.matchRegex([/^(\S*)\s+(\S*)\s+(\S*)\s+([^\s,)]*)/]); |
|
else if (options.hasZ || options.hasM) |
|
match = this.matchRegex([/^(\S*)\s+(\S*)\s+([^\s,)]*)/]); |
|
else |
|
match = this.matchRegex([/^(\S*)\s+([^\s,)]*)/]); |
|
|
|
if (!match) |
|
throw new Error('Expected coordinates'); |
|
|
|
if (options.hasZ && options.hasM) |
|
return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4])); |
|
else if (options.hasZ) |
|
return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3])); |
|
else if (options.hasM) |
|
return new Point(parseFloat(match[1]), parseFloat(match[2]), undefined, parseFloat(match[3])); |
|
else |
|
return new Point(parseFloat(match[1]), parseFloat(match[2])); |
|
}; |
|
|
|
WktParser.prototype.matchCoordinates = function (options) { |
|
var coordinates = []; |
|
|
|
do { |
|
var startsWithBracket = this.isMatch(['(']); |
|
|
|
coordinates.push(this.matchCoordinate(options)); |
|
|
|
if (startsWithBracket) |
|
this.expectGroupEnd(); |
|
} while (this.isMatch([','])); |
|
|
|
return coordinates; |
|
}; |
|
|
|
WktParser.prototype.skipWhitespaces = function () { |
|
while (this.position < this.value.length && this.value[this.position] === ' ') |
|
this.position++; |
|
};
|
|
|