125 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
| 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++;
 | |
| };
 |