JTS(Geometry)(轉)


原文鏈接:http://blog.csdn.net/cdl2008sky/article/details/7268577

空間數據模型
(1)、JTS Geometry model 
(2)、ISO Geometry model (Geometry Plugin and JTS Wrapper Plugin)
GeoTools has two implementations of these interfaces:
Geometry Plugin a port of JTS 1.7 to the ISO Geometry interfaces

JTS Wrapper Plugin an implementation that delegates all the work to JTS

JTS包結構

系(linearref包)、計算交點(noding包)、幾何圖形操作(operation包)、平面圖(planargraph包)、多邊形化(polygnize包)、精度(precision)、工具(util包)

重點理解JTS Geometry model
(1) JTS提供了如下的空間數據類型
     Point     
     MultiPoint
     LineString     
     LinearRing  封閉的線條
     MultiLineString    多條線
     Polygon
     MultiPolygon         

     GeometryCollection  包括點,線,面

(2) 支持接口
Coordinate
   Coordinate(坐標)是用來存儲坐標的輕便的類。它不同於點,點是Geometry的子類。不像模范Point的對象(包含額外的信息,例如一個信包,一個精確度模型和空間參考系統信息),Coordinate只包含縱座標值和存取方法。
Envelope(矩形)
   一個具體的類,包含一個最大和最小的x 值和y 值。
GeometryFactory
   GeometryFactory提供一系列的有效方法用來構造來自Coordinate類的Geometry對象。支持接口

 

import org.geotools.geometry.jts.JTSFactoryFinder;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;

/**  

 * Class GeometryDemo.java 

 * Description Geometry 幾何實體的創建,讀取操作

 * Company mapbar 

 * author Chenll E-mail: Chenll@mapbar.com

 * Version 1.0 

 * Date 2012-2-17 上午11:08:50

 */
public class GeometryDemo {

    private GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );
    
    /**
     * create a point
     * @return
     */
    public Point createPoint(){
        Coordinate coord = new Coordinate(109.013388, 32.715519);
        Point point = geometryFactory.createPoint( coord );
        return point;
    }
    
    /**
     * create a rectangle(矩形)
     * @return
     */
    public Envelope createEnvelope(){
        Envelope envelope = new Envelope(0,1,0,2);
        return envelope;
    }
    
    /**
     * create a point by WKT
     * @return
     * @throws ParseException 
     */
    public Point createPointByWKT() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        Point point = (Point) reader.read("POINT (109.013388 32.715519)");
        return point;
    }
    
    /**
     * create multiPoint by wkt
     * @return
     */
    public MultiPoint createMulPointByWKT()throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        MultiPoint mpoint = (MultiPoint) reader.read("MULTIPOINT(109.013388 32.715519,119.32488 31.435678)");
        return mpoint;
    }
    /**
     * 
     * create a line
     * @return
     */
    public LineString createLine(){
        Coordinate[] coords  = new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)};
        LineString line = geometryFactory.createLineString(coords);
        return line;
    }
    
    /**
     * create a line by WKT
     * @return
     * @throws ParseException
     */
    public LineString createLineByWKT() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        LineString line = (LineString) reader.read("LINESTRING(0 0, 2 0)");
        return line;
    }
    
    /**
     * create multiLine 
     * @return
     */
    public MultiLineString createMLine(){
        Coordinate[] coords1  = new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)};
        LineString line1 = geometryFactory.createLineString(coords1);
        Coordinate[] coords2  = new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)};
        LineString line2 = geometryFactory.createLineString(coords2);
        LineString[] lineStrings = new LineString[2];
        lineStrings[0]= line1;
        lineStrings[1] = line2;
        MultiLineString ms = geometryFactory.createMultiLineString(lineStrings);
        return ms;
    }
    
    /**
     * create multiLine by WKT
     * @return
     * @throws ParseException
     */
    public MultiLineString createMLineByWKT()throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        MultiLineString line = (MultiLineString) reader.read("MULTILINESTRING((0 0, 2 0),(1 1,2 2))");
        return line;
    }
    
    /**
     * create a polygon(多邊形) by WKT
     * @return
     * @throws ParseException
     */
    public Polygon createPolygonByWKT() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        Polygon polygon = (Polygon) reader.read("POLYGON((20 10, 30 0, 40 10, 30 20, 20 10))");
        return polygon;
    }
    
    /**
     * create multi polygon by wkt
     * @return
     * @throws ParseException
     */
    public MultiPolygon createMulPolygonByWKT() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        MultiPolygon mpolygon = (MultiPolygon) reader.read("MULTIPOLYGON(((40 10, 30 0, 40 10, 30 20, 40 10),(30 10, 30 0, 40 10, 30 20, 30 10)))");
        return mpolygon;
    }
    
    /**
     * create GeometryCollection  contain point or multiPoint or line or multiLine or polygon or multiPolygon
     * @return
     * @throws ParseException
     */
    public GeometryCollection createGeoCollect() throws ParseException{
        LineString line = createLine();
        Polygon poly =  createPolygonByWKT();
        Geometry g1 = geometryFactory.createGeometry(line);
        Geometry g2 = geometryFactory.createGeometry(poly);
        Geometry[] garray = new Geometry[]{g1,g2};
        GeometryCollection gc = geometryFactory.createGeometryCollection(garray);
        return gc;
    }
    
    /**
     * create a Circle  創建一個圓,圓心(x,y) 半徑RADIUS
     * @param x
     * @param y
     * @param RADIUS
     * @return
     */
    public Polygon createCircle(double x, double y, final double RADIUS){
        final int SIDES = 32;//圓上面的點個數
        Coordinate coords[] = new Coordinate[SIDES+1];
        for( int i = 0; i < SIDES; i++){
            double angle = ((double) i / (double) SIDES) * Math.PI * 2.0;
            double dx = Math.cos( angle ) * RADIUS;
            double dy = Math.sin( angle ) * RADIUS;
            coords[i] = new Coordinate( (double) x + dx, (double) y + dy );
        }
        coords[SIDES] = coords[0];
        LinearRing ring = geometryFactory.createLinearRing( coords );
        Polygon polygon = geometryFactory.createPolygon( ring, null );
        return polygon;
    }
    
    /**
     * @param args
     * @throws ParseException 
     */
    public static void main(String[] args) throws ParseException {
        GeometryDemo gt = new GeometryDemo();
        Polygon p = gt.createCircle(0, 1, 2);
        //圓上所有的坐標(32個)
        Coordinate coords[] = p.getCoordinates();
        for(Coordinate coord:coords){
            System.out.println(coord.x+","+coord.y);
        }
        Envelope envelope = gt.createEnvelope();
        System.out.println(envelope.centre());
    }
}

 

WKT簡介

WKT - 概念

WKT(Well-known text)是一種文本標記語言,用於表示矢量幾何對象、空間參照系統及空間參照系統之間的轉換。它的二進制表示方式,亦即WKB(well-known binary)則勝於在傳輸和在數據庫中存儲相同的信息。該格式由開放地理空間聯盟(OGC)制定。

WKT - 幾何對象

WKT可以表示的幾何對象包括:點,線,多邊形,TIN(不規則三角網)及多面體。可以通過幾何集合的方式來表示不同維度的幾何對象。

幾何物體的坐標可以是2D(x,y),3D(x,y,z),4D(x,y,z,m),加上一個屬於線性參照系統的m值。

以下為幾何WKT字串樣例:

 

POINT(6 10)
LINESTRING(3 4,10 50,20 25)
POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2))
MULTIPOINT(3.5 5.6, 4.8 10.5)
MULTILINESTRING((3 4,10 50,20 25),(-5 -8,-10 -8,-15 -4))
MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2)),((6 3,9 2,9 4,6 3)))
GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))
POINT ZM (1 1 5 60)
POINT M (1 1 80)
POINT EMPTY
MULTIPOLYGON EMPTY
 
OpenGIS的說明書中還規定了空間對象的內部存儲格式要包括一個空間參考系統標識(SRID)。當創建空間對象並向數據插入的時候需要這樣的SRID。下面是一個有效創建和插入一個OGC空間對象的語句: 
 INSERT INTO SPATIALTabLE ( THE_GEOM, THE_NAME ) 
 
 
  VALUES ( GeomFromText(''POINT(-126.4 45.32)'', 312), ''A Place'' ) 
 
 
  注意:上面的THE_GEOM字段是GEOMETRY類型,該類型的對象可以用WKB定義,也可以用WKT定義。如:
 
  
 geometry = GeomFromWKB(bytea WKB, SRID); 
 
 
  geometry = GeometryFromText(text WKT, SRID); 
 
 
  所以GeomFromText(''POINT(-126.4 45.32)'', 312)中的POINT(-126.4 45.32)就是WKT,312就是這個空間對象的SRID。
 
  
PostGIS的EWKB, EWKT 
 
 
  OGC的格式只支持2D的地理要素,而且其相關聯的SRID不能嵌入到輸入輸出表達中。PostGIS的擴展格式目前是OGC格式的超集,也就是說只要是有效的WKB或WKT就是有效的EWKB或EWKT。當然,如果今后OGC發布與該擴展格式相沖突的新格式,那么這種超集的情況就會有所變化了。PostGIS的EWKB, EWKT增加了對3DZ,3DM和4D坐標的支持,並可嵌入SRID信息。
 
  下面是一些EWKT的例子: 
 
 
  POINT(0 0 0)-- XYZ 
 
 
  SRID=32632;POINT(0 0) – XY with SRID 
 
 
  由於SRID可以嵌入到EWKT或EWKB中,空間對象的定義就可以簡化為:
 
  geometry = GeomFromEWKB(bytea EWKB);
 
  geometry = GeomFromEWKT(text EWKT);
 
  那么,相數據庫中插入PostGIS空間對象就可以寫成:
 
  INSERT INTO SPATIALTabLE ( THE_GEOM, THE_NAME )
 
  VALUES ( GeomFromText(''POINT(-126.4 45.32 312)''), ''A Place'' )

WKT - 空間參照系統

一個表示空間參照系統的WKT字串描述了空間物體的測地基准、大地水准面、坐標系統及地圖投影。
WKT在許多GIS程序中被廣泛采用。ESRI亦在其shape文件格式(*.prj)中使用WKT。
以下是空間參照系統的WKT表示樣例:
COMPD_CS["OSGB36 / British National Grid + ODN",
PROJCS["OSGB 1936 / British National Grid",
GEOGCS["OSGB 1936",
DATUM["OSGB_1936",
SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],
TOWGS84[375,-111,431,0,0,0,0],
AUTHORITY["EPSG","6277"]],
PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
UNIT["DMSH",0.0174532925199433,AUTHORITY["EPSG","9108"]],
AXIS["Lat",NORTH],
AXIS["Long",EAST],
AUTHORITY["EPSG","4277"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",49],
PARAMETER["central_meridian",-2],
PARAMETER["scale_factor",0.999601272],
PARAMETER["false_easting",400000],
PARAMETER["false_northing",-100000],
UNIT["metre",1,AUTHORITY["EPSG","9001"]],
AXIS["E",EAST],
AXIS["N",NORTH],
AUTHORITY["EPSG","27700"]],
VERT_CS["Newlyn",
VERT_DATUM["Ordnance Datum Newlyn",2005,AUTHORITY["EPSG","5101"]],
UNIT["metre",1,AUTHORITY["EPSG","9001"]],
AXIS["Up",UP],
AUTHORITY["EPSG","5701"]],
AUTHORITY["EPSG","7405"]
 

基礎知識:坐標參照系有三種最常見的子類:地心坐標系(geocentric cs、GEOCCS),地理坐標系(geographic cs、GEOGCS),和投影坐標系(projected cs、PROJCS)以及相互之間的關系,可以參考《坐標參照系》。投影參數內容:Ellipsoid 、 Datum ;Projection,可以參考《地圖投影為什么》。

坐標系的文字描述的擴展BN范式(EBNF)定義如下:
<coordinate system> = <projected cs> | <geographic cs> | <geocentric cs>

 

 

<projection> = PROJECTION["<name>"]

<parameter> = PARAMETER["<name>", <value>]

<value> = <number>

 

 

<datum> = DATUM["<name>", <spheroid>]

<spheroid> = SPHEROID["<name>", <semi-major axis>, <inverse flattening>]

<semi-major axis> = <number> NOTE: semi-major axis is measured in meters and must be > 0.

<inverse flattening> = <number>

<prime meridian> = PRIMEM["<name>", <longitude>]

<longitude> = <number>

 

 

<angular unit> = <unit>

<linear unit> = <unit>

<unit> = UNIT["<name>", <conversion factor>]

<conversion factor> = <number>

以下示例說明,參照上述參數,然后比瓢畫葫蘆即可自行用WKT創建坐標系。

地理坐標系的格式:<geographic cs> = GEOGCS["<name>", <datum>, <prime meridian>, <angular unit>]

WGS1984的地理坐標系WKT形式:
GEOGCS["WGS 84", 
DATUM["WGS_1984", 
SPHEROID["WGS 84", 6378137, 298.257223563, AUTHORITY["EPSG", "7030"]], 
AUTHORITY["EPSG", "6326"]], 
PRIMEM["Greenwich", 0, AUTHORITY["EPSG", "8901"]], 
UNIT["degree", 0.0174532925199433, AUTHORITY["EPSG", "9122"]],
AUTHORITY["EPSG", "4326"]]

投影坐標系的格式:<projected cs> = PROJCS["<name>", <geographic cs>, <projection>, {<parameter>,}* <linear unit>]

WGS1984地理坐標,統一橫軸墨卡托(UTM)投影,中央經線117E的投影坐標系WKT形式:

PROJCS["WGS 84 / UTM zone 50N", 
GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84", 6378137, 298.257223563, AUTHORITY["EPSG", "7030"]], AUTHORITY["EPSG", "6326"]], PRIMEM["Greenwich", 0, AUTHORITY["EPSG", "8901"]], UNIT["degree", 0.0174532925199433, AUTHORITY["EPSG", "9122"]], AUTHORITY["EPSG", "4326"]], 
PROJECTION["Transverse_Mercator"], 
PARAMETER["latitude_of_origin", 0], 
PARAMETER["central_meridian", 117], 
PARAMETER["scale_factor", 0.9996], 
PARAMETER["false_easting", 500000], 
PARAMETER["false_northing", 0], 
UNIT["metre", 1, AUTHORITY["EPSG", "9001"]], 
AUTHORITY["EPSG", "32650"]]

地心坐標系格式相似於地理坐標系:<geocentric cs> = GEOCCS["<name>", <datum>, <prime meridian>, <linear unit>]

參數中出現AUTHORITY是EPSG的玩意,在自定義坐標系時可以忽略,我會在后面詳細介紹EPSG相關內容。WKT更具體的可參考OGC相關文檔:如SFA、《SF for OLE/COM》等。

 

練習:給出下屬投影坐標系參數,請用WKT方式表述。
投影參數:橢球體,Krasovsky_1940;基准面,北京1954;投影:蘭勃特雙標准緯線,25N,47N;中央經線,117E。

 

參考答案:

PROJCS["liongg",
GEOGCS["GCS_Beijing_1954",
DATUM["D_Beijing_1954",SPHEROID["Krasovsky_1940",6378245.0,298.3]],
PRIMEM["Greenwich",0.0],
UNIT["Degree",0.0174532925199433]],
PROJECTION["Lambert_Conformal_Conic"],
PARAMETER["False_Easting",20500000.0],
PARAMETER["False_Northing",0.0],
PARAMETER["Central_Meridian",0.0],
PARAMETER["Standard_Parallel_1",25.0],
PARAMETER["Standard_Parallel_2",47.0],
PARAMETER["Scale_Factor",1.0],
PARAMETER["Latitude_Of_Origin",0.0],
UNIT["Meter",1.0]]

 

有個偷懶的方法就是用商業軟件譬如ArcGIS按照參數新建投影,然后在.prj文件中提取投影內容並修改。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM