wktparser.js
3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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++;
};