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数据、栅格数据等
还是挺好用的,当时的代码也找不到了,有人记得可以留言。

你可能感兴趣的:(开源GIS大杂烩)