Package ca.carleton.gcrc.geom.wkt

Source Code of ca.carleton.gcrc.geom.wkt.WktParser

package ca.carleton.gcrc.geom.wkt;

import java.io.BufferedReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.List;
import java.util.Vector;

import ca.carleton.gcrc.geom.Geometry;
import ca.carleton.gcrc.geom.GeometryCollection;
import ca.carleton.gcrc.geom.LineString;
import ca.carleton.gcrc.geom.MultiPoint;
import ca.carleton.gcrc.geom.MultiLineString;
import ca.carleton.gcrc.geom.MultiPolygon;
import ca.carleton.gcrc.geom.Point;
import ca.carleton.gcrc.geom.Polygon;

public class WktParser {

  public WktParser(){
   
  }
 
  public Geometry parseWkt(String wktString) throws Exception {
    StringReader sr = new StringReader(wktString);
    return parseWkt(sr);
  }
 
  public Geometry parseWkt(Reader reader) throws Exception {
    BufferedReader bufReader = new BufferedReader(reader);
    return parseGeometry(bufReader);
  }
 
  private Geometry parseGeometry(BufferedReader bufReader) throws Exception {
   
    Geometry geometry = null;
    try {
      skipWhiteSpaces(bufReader);
      String identifier = readIdentifier(bufReader);
     
      if( "point".equalsIgnoreCase(identifier) ) {
        geometry = parsePoint(bufReader);
       
      } else if( "linestring".equalsIgnoreCase(identifier) ) {
        geometry = parseLineString(bufReader);
         
      } else if( "polygon".equalsIgnoreCase(identifier) ) {
        geometry = parsePolygon(bufReader);
       
      } else if( "multipoint".equalsIgnoreCase(identifier) ) {
        geometry = parseMultiPoint(bufReader);
       
      } else if( "multilinestring".equalsIgnoreCase(identifier) ) {
        geometry = parseMultiLineString(bufReader);
       
      } else if( "multipolygon".equalsIgnoreCase(identifier) ) {
        geometry = parseMultiPolygon(bufReader);
       
      } else if( "geometrycollection".equalsIgnoreCase(identifier) ) {
        geometry = parseGeometryCollection(bufReader);
         
      } else {
        throw new Exception("Unrecognized WKT type: "+identifier);
      }
     
    } catch(Exception e) {
      throw new Exception("Error occurred while parsing a WKT string", e);
    }
   
    return geometry;
  }
 
  private int skipWhiteSpaces(BufferedReader br) throws Exception {
    int numberOfWhite = 0;
   
    br.mark(1);
    int c = br.read();
    while( c >= 0 ){
      if( ' ' == c
       || '\n' == c
       || '\r' == c
       || '\t' == c ) {
        // must skip this
        br.mark(1);
        c = br.read();
        ++numberOfWhite;
      } else {
        // Return character to stream and exit
        br.reset();
        c = -1;
      }
    }
   
    return numberOfWhite;
  }
// 
//  private void popWhiteSpaces(BufferedReader br) throws Exception {
//    int c = skipWhiteSpaces(br);
//    if( c > 0 ) {
//      // good
//    } else {
//      throw new Exception("Expected a whitespace");
//    }
//  }
 
  private void popLeftParen(BufferedReader br) throws Exception {
    int c = br.read();
    if( '(' == c ) {
      // good
    } else {
      throw new Exception("Expected '('");
    }
  }
 
  private void popRightParen(BufferedReader br) throws Exception {
    int c = br.read();
    if( ')' == c ) {
      // good
    } else {
      throw new Exception("Expected ')'");
    }
  }
 
  private void popComma(BufferedReader br) throws Exception {
    int c = br.read();
    if( ',' == c ) {
      // good
    } else {
      throw new Exception("Expected ','");
    }
  }
 
  private boolean checkForLeftParen(BufferedReader br) throws Exception {
    br.mark(1);
    int c = br.read();
    br.reset();
    if( '(' == c ) {
      return true;
    } else {
      return false;
    }
  }
 
  private boolean checkForRightParen(BufferedReader br) throws Exception {
    br.mark(1);
    int c = br.read();
    br.reset();
    if( ')' == c ) {
      return true;
    } else {
      return false;
    }
  }
 
  private boolean checkForRightParenOrComma(BufferedReader br) throws Exception {
    br.mark(1);
    int c = br.read();
    br.reset();
    if( ')' == c ) {
      return true;
    } else if( ',' == c ) {
      return true;
    } else {
      return false;
    }
  }
 
  private String readIdentifier(BufferedReader br) throws Exception {
    StringBuilder sb = new StringBuilder();
   
    br.mark(1);
    int c = br.read();
    while( c >= 0 ){
      if( c >= 'a'
       && c <= 'z' ) {
        // must keep this
        sb.append( (char)c );
       
        br.mark(1);
        c = br.read();
       
      } else if( c >= 'A'
       && c <= 'Z' ) {
        // must keep this
        sb.append( (char)c );
       
        br.mark(1);
        c = br.read();
       
      } else {
        // Return character to stream and exit
        br.reset();
        c = -1;
      }
    }
   
    return sb.toString();
  }
 
  private double parsePosition(BufferedReader br) throws Exception {
    StringBuilder sb = new StringBuilder();
    int significant = 0;

    // Parse sign
    br.mark(1);
    int c = br.read();
    if( '+' == c ) {
      // OK
    } else if( '-' == c ) {
      sb.append( (char)c );
    } else {
      br.reset();
    }
   
    // Parse integer portion
    br.mark(1);
    c = br.read();
    while( c >= '0' && c <= '9' ){
      sb.append( (char)c );
      ++significant;
     
      br.mark(1);
      c = br.read();
    }
    br.reset();
   
    // Check for decimal
    br.mark(1);
    c = br.read();
    if( c != '.' ) {
      br.reset();
    } else {
      sb.append( (char)c );
     
      // Parse decimal portion
      br.mark(1);
      c = br.read();
      while( c >= '0' && c <= '9' ){
        sb.append( (char)c );
        ++significant;
       
        br.mark(1);
        c = br.read();
      }
      br.reset();
    }
   
    if( significant < 1 ) {
      throw new Exception("Expected a position");
    }
   
    double position = Double.parseDouble( sb.toString() );
    return position;
  }
 
  private List<Number> parsePositions(BufferedReader br) throws Exception {
    List<Number> positions = new Vector<Number>();
   
    skipWhiteSpaces(br);
   
    double position = parsePosition(br);
    positions.add(position);
   
    int whites = skipWhiteSpaces(br);
    boolean isEndOfPositions = checkForRightParen(br);
    while( false == isEndOfPositions && whites > 0 ){
      position = parsePosition(br);
      positions.add(position);
     
      whites = skipWhiteSpaces(br);
      isEndOfPositions = checkForRightParenOrComma(br);
    }
   
    return positions;
  }
 
  private Point parsePoint(BufferedReader br) throws Exception {
   
    skipWhiteSpaces(br);
    popLeftParen(br);
   
    List<Number> positions = parsePositions(br);
    if( positions.size() < 2 ){
      throw new Exception("A point must have 2 or more positions");
    }
   
    skipWhiteSpaces(br);
    popRightParen(br);

    Point point = new Point(positions);
    return point;
  }
 
  private LineString parseLineString(BufferedReader br) throws Exception {
    LineString lineString = new LineString();
   
    skipWhiteSpaces(br);
    popLeftParen(br);
   
    // Accumulate points
    boolean done = false;
    do {
      List<Number> positions = parsePositions(br);
      if( positions.size() < 2 ){
        throw new Exception("A point must have 2 or more positions");
      }

      Point point = new Point(positions);
      lineString.addPoint(point);
     
      if( checkForRightParen(br) ) {
        done = true;
      } else {
        popComma(br);
      }
     
    } while( !done );
   
    popRightParen(br);
   
    return lineString;
  }
 
  private Polygon parsePolygon(BufferedReader br) throws Exception {
    Polygon polygon = new Polygon();
   
    skipWhiteSpaces(br);
    popLeftParen(br);
   
    LineString ls = parseLineString(br);
    polygon.addLinearRing(ls);
    skipWhiteSpaces(br);
    while( false == checkForRightParen(br) ){
      popComma(br);
     
      ls = parseLineString(br);
      polygon.addLinearRing(ls);
      skipWhiteSpaces(br);
    }
   
    popRightParen(br);
   
    return polygon;
  }
 
  private MultiPoint parseMultiPoint(BufferedReader br) throws Exception {
    MultiPoint multiPoint = new MultiPoint();
   
    skipWhiteSpaces(br);
    popLeftParen(br);
   
    boolean done = false;
    do {
      skipWhiteSpaces(br);
      if( checkForLeftParen(br) ) {
        Point point = parsePoint(br);
        multiPoint.addPoint(point);
      } else {
        List<Number> positions = parsePositions(br);
        if( positions.size() < 2 ){
          throw new Exception("A point must have 2 or more positions");
        }

        Point point = new Point(positions);
        multiPoint.addPoint(point);
      }

      if( checkForRightParen(br) ) {
        done = true;
      } else {
        popComma(br);
      }
     
    } while(!done);
   
    popRightParen(br);
   
    return multiPoint;
  }
 
  private MultiLineString parseMultiLineString(BufferedReader br) throws Exception {
    MultiLineString multiLineString = new MultiLineString();
   
    skipWhiteSpaces(br);
    popLeftParen(br);
   
    boolean done = false;
    do {
      skipWhiteSpaces(br);

      LineString lineString = parseLineString(br);
      multiLineString.addLineString(lineString);

      if( checkForRightParen(br) ) {
        done = true;
      } else {
        popComma(br);
      }
     
    } while(!done);
   
    popRightParen(br);
   
    return multiLineString;
  }
 
  private MultiPolygon parseMultiPolygon(BufferedReader br) throws Exception {
    MultiPolygon multiPolygon = new MultiPolygon();
   
    skipWhiteSpaces(br);
    popLeftParen(br);
   
    boolean done = false;
    do {
      skipWhiteSpaces(br);

      Polygon polygon = parsePolygon(br);
      multiPolygon.addPolygon(polygon);

      if( checkForRightParen(br) ) {
        done = true;
      } else {
        popComma(br);
      }
     
    } while(!done);
   
    popRightParen(br);
   
    return multiPolygon;
  }
 
  private GeometryCollection parseGeometryCollection(BufferedReader br) throws Exception {
    GeometryCollection geometryCollection = new GeometryCollection();
   
    skipWhiteSpaces(br);
    popLeftParen(br);
   
    boolean done = false;
    do {
      skipWhiteSpaces(br);

      Geometry geometry = parseGeometry(br);
      geometryCollection.addGeometry(geometry);

      if( checkForRightParen(br) ) {
        done = true;
      } else {
        popComma(br);
      }
     
    } while(!done);
   
    popRightParen(br);
   
    return geometryCollection;
  }
}
TOP

Related Classes of ca.carleton.gcrc.geom.wkt.WktParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.