GeoTools集成一些細節

Geotools官網

http://docs.geotools.org/

GeoTools的Maven倉庫

關於maven倉庫配置

以前的pom文件倉庫配置是這樣子的
	  <repository>
            <id>osgeo</id>
            <name>Open Source Geospatial Foundation Repository</name>
            <url>http://download.osgeo.org/webdav/geotools/</url>
        </repository>
現在的pom文件倉庫配置是這樣子的
    <repository>
      <id>osgeo</id>
      <name>OSGeo Release Repository</name>
      <url>https://repo.osgeo.org/repository/release/</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <enabled>true</enabled>
      </releases>
    </repository>
上面的地址現在已經是404了,也沒自己看是啥時候官網取消了這個地址。
但23.0在用的時候已經把倉儲地址變了,當初使用20.0的時候老地址還是在的
總之以後就都使用新的倉儲地址了
新地址 :https://repo.osgeo.org/repository/release/

關於數據問題

GeoTools底層的幾何圖形操作用的是jts,這是一家加拿大的公司寫的,說實話代碼寫的質量不咋地。不過好歹是遵守了opengis的標準。
開源GIS庫對GIS數據的數據驗證比較嚴格,都希望數據完美的複合規範。
但現實很殘酷,特別是國土類的數據,標準簡直就是開玩笑,混跡國土這麼多年,見過的扯淡數據不勝枚舉。
商業用途的Arcgis在這方面對數據的兼容處理就強大的多,這麼多年沒怎麼費神過。
使用jts做幾何運算過程中經常會遇到各種拓撲驗證不過的問題
解決辦法約兩種

1 修改原始數據

用QGIS的數據修復功能修復一下數據,重新入庫,但絕大多數地方這個方案不可行,因爲原始數據不可動。

2 在運算之前驗證數據,如果拓撲有問題就動態修復數據

動態修復數據會稍微浪費運算時間,但起碼能處理絕大多數異常
下面貼一段代碼能修復絕大多數的拓撲問題,針對面數據
思路是stock overflow上一個老外寫的代碼,做了一點改進,原始代碼無法準確的處理多面多環的拓撲
修復思路就是先拿到外環,然後使用內環去做差異分析,這樣求出來的多環就對了。
其中環要先轉成線,因爲單純線的拓撲驗證比環的好過得多,再由線去挖空,就會避免因爲因爲壞環導致的拓撲錯誤。
原始的就不貼了,有興趣自己去上面找
分析之前調用一下validate驗證一下幾何圖形即可
public class GeometryUtils {
    public static Geometry validate(Geometry geom) {
        if (geom instanceof Polygon) {
            if (geom.isValid()) {
                geom.normalize();
                return geom;
            }
            Polygonizer polygonizer = new Polygonizer();
            addPolygon((Polygon) geom, polygonizer);
            return toPolygonGeometry(polygonizer.getPolygons(), geom.getFactory());
        } else if (geom instanceof MultiPolygon) {
            if (geom.isValid()) {
                geom.normalize();
                return geom;
            }
            Polygon[] polygons = new Polygon[geom.getNumGeometries()];
            for (int n = geom.getNumGeometries(); n-- > 0; ) {
                Polygonizer polygonizer = new Polygonizer();
                addPolygon((Polygon) geom.getGeometryN(n), polygonizer);
                Geometry geometry = toPolygonGeometry(polygonizer.getPolygons(), geom.getFactory());
                polygons[n] = (Polygon) geometry;
            }
            return geom.getFactory().createMultiPolygon(polygons);
        } else {
            return geom;
        }
    }

    public static void addPolygon(Polygon polygon, Polygonizer polygonizer) {
        addLineString(polygon.getExteriorRing(), polygonizer);
        for (int n = polygon.getNumInteriorRing(); n-- > 0; ) {
            addLineString(polygon.getInteriorRingN(n), polygonizer);
        }
    }

    public static void addLineString(LineString lineString, Polygonizer polygonizer) {
        if (lineString instanceof LinearRing) {
            lineString = lineString.getFactory().createLineString(lineString.getCoordinateSequence());
        }
        Point point = lineString.getFactory().createPoint(lineString.getCoordinateN(0));
        Geometry toAdd = lineString.union(point);
        polygonizer.add(toAdd);
    }

    public static Geometry toPolygonGeometry(Collection<Polygon> polygons, GeometryFactory factory) {
        switch (polygons.size()) {
            case 0:
                return null;
            case 1:
                return polygons.iterator().next();
            default:
                Iterator<Polygon> iter = polygons.iterator();
                Geometry ret = iter.next();
                while (iter.hasNext()) {
                    ret = ret.difference(iter.next());
                }
                return ret;
        }
    }
}

關於gt-geojson庫

這個庫總體很好,但是庫提供的GeoJSON靜態類有點坑
該類內部的GeometryJSON創建時候使用的是默認精度,但默認精度是4位啊,投影下還好,經緯度下經常會造成精度損失,第5位一下就是幾十米的誤差
沒啥好辦法,複製一下這個類把GeometryJSON屬性暴露出來,默認用了10精度
這樣子再做geojson數據轉換就字啊也不怕了
public class GeoJsonUtils {

    public static GeometryJSON gjson = new GeometryJSON(10);
    public static FeatureJSON fjson = new FeatureJSON(gjson);

    public static Object read(Object input) throws IOException {
        throw new UnsupportedOperationException();
    }

    public static void write(Object obj, Object output) throws IOException {
        if (obj instanceof Geometry) {
            gjson.write((Geometry) obj, output);
        } else if (obj instanceof Feature
                || obj instanceof FeatureCollection
                || obj instanceof CoordinateReferenceSystem) {

            if (obj instanceof SimpleFeature) {
                fjson.writeFeature((SimpleFeature) obj, output);
            } else if (obj instanceof FeatureCollection) {
                fjson.writeFeatureCollection((FeatureCollection) obj, output);
            } else if (obj instanceof CoordinateReferenceSystem) {
                fjson.writeCRS((CoordinateReferenceSystem) obj, output);
            } else {
                throw new IllegalArgumentException(
                        "Unable able to encode object of type " + obj.getClass());
            }
        }
    }
}

其他的就沒有啥需要注意的了,有問題看官網文檔

 一個小問題,關於空間分析模塊
忘記那個版本Geotools有空間分析的組件模塊,但是後來這個模塊也就不維護了
組件內部提供了圖層與圖層之間的各種空間分析能力,是指shp數據、柵格數據等
還是挺好用的,當時的代碼也找不到了,有人記得可以留言。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章