如何配置SimpleFeatureTypeBuilder在WGS84地图上构建面向中心的地精投影多边形?

时间:2018-08-09 16:10:57

标签: geotools h3

我正在尝试使用Geotools用H3网格定义的图块来绘制历史政治领土。我的输入shapefile使用WGS84 / EPSG:4326 CRS。 H3十六进制网格是面向中心的gnomonic投影,但我假设它们仍使用WGS84 CRS。 (据我所知,这仅是Kevin Sahr在DGGS软件中使用的,该软件启发了H3项目。)

我得到一些奇怪的结果,我怀疑问题是因为我没有在我的方法中处理侏儒投影。既不放置六边形,也不将生成的多边形保存在shapefile输出中。

这是我的方法:

  1. 获取区域(多边形和多面体)的形状文件
  2. 使用h3.polyfillAddress()方法提取边界以收集分辨率为3(或在某些情况下为4)的该边界的六边形
  3. 使用Geotools SimpleFeatureTypeBuilder
  4. 为该组六边形构建并保存一个shapefile。

Unresolved Projection of H3 Tiles onto EPSG:4326 (WGS84) Map of Central Asian Khanates in 1815

输入多边形的geojson输入位于:https://pastebin.com/wH1SgCY8

H3磁贴的geojson输出位于:https://pastebin.com/0Zuc7awv

地图中心附近的shapefile(使用QGIS查看的Prime Meridian / Equator)似乎是正确的,但离中心较远的地方却得到了奇怪的结果。投影显然是一个问题,但是我不知道奇怪的填充结果是由H3的填充方法的某些限制引起的,还是因为在尝试进行填充操作之前应该已经处理了输入边界的投影。

我的SimpleFeatureTypeBuilder使用WGS84 CRS指定输出。在构建每个多边形之前,我应该对它们进行一些变换吗?

代码如下:

   private static void saveShapefile(String name, String abb, Set<String> hexes) throws IOException {
    /*
    Takes a country name, it's abbreviation and a set of hexagons that will represent it and writes out a shapefile

     */
    String filename = "src/main/data/hexMaps/politicalBoundaryHexes_" + yearString + "_" + name + ".shp";
    File file = new File(filename);

    H3Core h3 = H3Core.newInstance();
    List<SimpleFeature> features = new ArrayList<>();
    GeometryFactory gf = JTSFactoryFinder.getGeometryFactory();

    DefaultFeatureCollection output = new DefaultFeatureCollection();

    final SimpleFeatureType HEX = createFeatureType();
    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(HEX);

    ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
    Map<String, Serializable> params = new HashMap<>();
    params.put("url", file.toURI().toURL());
    params.put("create spatial index", Boolean.TRUE);

    ShapefileDataStore dataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
    dataStore.createSchema(HEX);

    int index = 0;
    for (String h:hexes) {
        List<GeoCoord> geocoords = h3.h3ToGeoBoundary(h);
        int numVerts = geocoords.size();
        Coordinate[] coordinates = new Coordinate[numVerts + 1];
        if(debugging){System.out.println("Processing hex " + index + ", @ " + h);}
        for (int i=0; i<geocoords.size(); i++){
            coordinates[i] = new Coordinate(geocoords.get(i).lat, geocoords.get(i).lng);
        }
        coordinates[numVerts] = new Coordinate(geocoords.get(0).lat, geocoords.get(0).lng);
        Polygon polygon = gf.createPolygon(coordinates);
        Object[] values = new Object[]{polygon, index, h};
        index++;
        featureBuilder.addAll(values);

        SimpleFeature polyFeature = featureBuilder.buildFeature(h);
        features.add(polyFeature);
    }

    org.geotools.data.Transaction transaction = new DefaultTransaction("create");
    String typeName = dataStore.getTypeNames()[0];
    SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName);

    if (featureSource instanceof SimpleFeatureStore) {
        SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
        SimpleFeatureCollection collection = new ListFeatureCollection(HEX, features);
        featureStore.setTransaction(transaction);
        try {
            featureStore.addFeatures(collection);
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        } finally {
            transaction.close();
        }
    } else {
        System.out.println("Writing the Shapefile failed.");
        System.exit(1); // Failure!
    }
}

private static SimpleFeatureType createFeatureType() {
    SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
    builder.setName("polygon");
    builder.setCRS(DefaultGeographicCRS.WGS84);
    builder.add("the_geom", Polygon.class);
    builder.add("id", Long.class);
    builder.add("address", String.class);
    final SimpleFeatureType TYPE = builder.buildFeatureType();
    return TYPE;
}

0 个答案:

没有答案