geotools - 如何配置 SimpleFeatureTypeBuilder 以在 WGS84 地图上构建面向中心的指针投影多边形?
问题描述
我正在尝试使用 Geotools 用 H3 网格定义的瓷砖平铺历史政治领土。我的输入 shapefile 使用 WGS84/EPSG:4326 CRS。H3 六角网格是面向中心的日晷投影,但我假设它们仍然使用 WGS84 CRS。(只是因为这就是 Kevin Sahr 在启发 H3 项目的 DGGS 软件中使用的,据我所知)。
我得到了一些奇怪的结果,我怀疑问题是因为我没有在我的方法中处理指针投影;既不放置六边形也不将生成的多边形保存在 shapefile 输出中。
这是我的方法:
- 摄取区域的 shapefile(多边形和多多边形)
h3.polyfillAddress()
提取边界使用该方法以分辨率 3(或 4,在某些情况下)收集适合该边界的六边形- 使用 Geotools 为该组六边形构建并保存 shapefile
SimpleFeatureTypeBuilder
输入多边形的 geojson 输入位于:https ://pastebin.com/wH1SgCY8
H3 瓦片的 geojson 输出位于:https ://pastebin.com/0Zuc7awv
地图中心附近的形状文件 - 使用 QGIS 查看的本初子午线/赤道 - 似乎是正确的,但离中心越远我得到奇怪的结果。投影显然是一个问题,但我不知道奇怪的 polyfill 结果是由于 H3 的 polyfill 方法的某些限制还是因为在尝试 polyfill 操作之前应该已经处理了输入边界的投影。
我的 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;
}
解决方案
推荐阅读
- php - 添加数组的所有值并将其显示在数组中的问题
- python - Python - 使用 Adobe Illustrator 打开 .DXF 后 GeoPandas 无法工作
- python - 开发用于图像修改的编码器/解码器
- java - 在 GraphiQL 中显示 GraphQL 订阅结果
- vue.js - 正确设置和使用 VUEX 存储突变类型
- wpf - 你能在功能区中重复一个控件块吗?
- android - 如何使用带有浮点数的android camera2 api缩放相机
- google-apps-script - 如何编写自动更新个人过滤器的过滤器范围的 Google 脚本
- android - onTouchListener 总是得到相同的 MotionEvent ACTION_UP
- python - tensorflow 运行时间在 CPU 上稳定,但在 GPU 上上升