如何使用 Java 正确地将多边形创建到 shapefile 中?
How to correctly create a Polygon into a shapefile with Java?
我正在尝试从坐标列表创建形状文件,它看起来可以工作,但是当我尝试在 shapefile 查看器中查看 shapefile 时,我的形状中似乎没有坐标。此外,如果我随后将我的 shapefile 下载为 geoJSON,它看起来是空的,如下所示:
{"type":"GeometryCollection", "geometries": []}
所以我有这个 Java class,我首先创建一些虚拟数据,然后创建一个多边形 SimpleFeatureType,然后将我的点列表转换为一个多边形,并最终尝试编写它多边形转换为 shapefile。在我尝试在浏览器中查看它之前,我没有收到任何错误,并且一切看起来都很顺利 运行。
这是我的 class 和一些调试打印:
import org.geotools.data.DefaultTransaction;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.SchemaException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Polygon;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;
public class Main {
private static SimpleFeature toFeature(List<PolygonPoint> locations, SimpleFeatureType POLYGON,
GeometryFactory geometryFactory) {
Coordinate[] coords = new Coordinate[locations.size()];
int i = 0;
for (PolygonPoint location : locations) {
Coordinate coord = new Coordinate(location.x, location.y, 0);
coords[i] = (coord);
i++;
}
Polygon polygon = geometryFactory.createPolygon(coords);
System.out.println(polygon.toString());
/**
* Degub print in this point looks like this: POLYGON ((60.15396170672204
* 24.665516804291176, 60.1548304906673 24.67437097771886, 60.156868902093464
* 24.684907435753292, 60.16053593400762 24.681227944085034, 60.16351621152651
* 24.677017850437107, 60.1641222365678 24.670587380672547, 60.163303711361145
* 24.664257803508647, 60.16193970279525 24.6590194867117, 60.158682674758644
* 24.65963863846621, 60.15396170672204 24.665516804291176)) So looks okay so
* far...
*/
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(POLYGON);
featureBuilder.add(polygon);
return featureBuilder.buildFeature(null);
}
static class PolygonPoint {
public double x;
public double y;
public PolygonPoint(double x, double y) {
this.x = x;
this.y = y;
}
}
private static void initData(List<PolygonPoint> locations) {
locations.add(new PolygonPoint(60.1539617067220433, 24.6655168042911761));
locations.add(new PolygonPoint(60.1548304906673010, 24.6743709777188585));
locations.add(new PolygonPoint(60.1568689020934642, 24.6849074357532920));
locations.add(new PolygonPoint(60.1605359340076191, 24.6812279440850340));
locations.add(new PolygonPoint(60.1635162115265132, 24.6770178504371067));
locations.add(new PolygonPoint(60.1641222365677990, 24.6705873806725471));
locations.add(new PolygonPoint(60.1633037113611451, 24.6642578035086473));
locations.add(new PolygonPoint(60.1619397027952516, 24.6590194867116992));
locations.add(new PolygonPoint(60.1586826747586443, 24.6596386384662090));
locations.add(new PolygonPoint(60.1539617067220433, 24.6655168042911761));
}
public static void main(String[] args) throws IOException, SchemaException {
List<PolygonPoint> locations = new ArrayList<>();
initData(locations);
// create simple feature builder for the locations
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("polygonFeature");
builder.setCRS(DefaultGeographicCRS.WGS84);
builder.add(Polygon.TYPENAME_POLYGON, Polygon.class);
SimpleFeatureType POLYGON = builder.buildFeatureType();
DefaultFeatureCollection collection = new DefaultFeatureCollection();
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
SimpleFeature feature = toFeature(locations, POLYGON, geometryFactory);
collection.add(feature);
collection.forEach(name -> System.out.println(name));
/**
* Degub print in this point looks like this:
* SimpleFeatureImpl:polygonFeature=[SimpleFeatureImpl.Attribute:
* Polygon<Polygon id=fid-77f7c041_174f9627c85_-8000>=POLYGON
* ((60.15396170672204 24.665516804291176, 60.1548304906673 24.67437097771886,
* 60.156868902093464 24.684907435753292, 60.16053593400762 24.681227944085034,
* 60.16351621152651 24.677017850437107, 60.1641222365678 24.670587380672547,
* 60.163303711361145 24.664257803508647, 60.16193970279525 24.6590194867117,
* 60.158682674758644 24.65963863846621, 60.15396170672204 24.665516804291176))]
* So looks okay still...
*/
File shapeFile = new File(new File("2020-").getAbsolutePath() + "shapefile.shp");
Map<String, Serializable> params = new HashMap<>();
params.put("url", shapeFile.toURI().toURL());
params.put("create spatial index", Boolean.TRUE);
ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
ShapefileDataStore dataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
dataStore.createSchema(POLYGON);
Transaction transaction = new DefaultTransaction("create");
String typeName = dataStore.getTypeNames()[0];
SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName);
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
featureStore.setTransaction(transaction);
try {
featureStore.addFeatures(collection);
transaction.commit();
} catch (Exception problem) {
transaction.rollback();
} finally {
transaction.close();
}
}
}
}
然后按预期创建了 5 个文件。但是形状不正确,没有显示任何内容。我正在用这个工具测试它们:https://mapshaper.org/ 但可以 google 一些 shapefile 在线查看器。
每当我看到未写入数据的事务时,我都会查看事务处理。你把它做得很好,因为你在出现异常时回滚。但我强烈建议您也制作一些日志消息,指示发生了哪种异常。特别是当你抓住通用的 Exception
.
查看catch
块:
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
featureStore.setTransaction(transaction);
try {
featureStore.addFeatures(collection);
transaction.commit();
} catch (Exception problem) {
problem.printStackTrace(System.err); // print out the stack trace of the exception
transaction.rollback();
} finally {
transaction.close();
}
}
这至少会让您有机会看看哪里出了问题。
感谢 Ian Turton 链接答案,问题已通过替换此解决:
builder.add(Polygon.TYPENAME_POLYGON, Polygon.class);
有了这个:
builder.add("the_geom", Polygon.class);
我正在尝试从坐标列表创建形状文件,它看起来可以工作,但是当我尝试在 shapefile 查看器中查看 shapefile 时,我的形状中似乎没有坐标。此外,如果我随后将我的 shapefile 下载为 geoJSON,它看起来是空的,如下所示:
{"type":"GeometryCollection", "geometries": []}
所以我有这个 Java class,我首先创建一些虚拟数据,然后创建一个多边形 SimpleFeatureType,然后将我的点列表转换为一个多边形,并最终尝试编写它多边形转换为 shapefile。在我尝试在浏览器中查看它之前,我没有收到任何错误,并且一切看起来都很顺利 运行。
这是我的 class 和一些调试打印:
import org.geotools.data.DefaultTransaction;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.SchemaException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Polygon;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;
public class Main {
private static SimpleFeature toFeature(List<PolygonPoint> locations, SimpleFeatureType POLYGON,
GeometryFactory geometryFactory) {
Coordinate[] coords = new Coordinate[locations.size()];
int i = 0;
for (PolygonPoint location : locations) {
Coordinate coord = new Coordinate(location.x, location.y, 0);
coords[i] = (coord);
i++;
}
Polygon polygon = geometryFactory.createPolygon(coords);
System.out.println(polygon.toString());
/**
* Degub print in this point looks like this: POLYGON ((60.15396170672204
* 24.665516804291176, 60.1548304906673 24.67437097771886, 60.156868902093464
* 24.684907435753292, 60.16053593400762 24.681227944085034, 60.16351621152651
* 24.677017850437107, 60.1641222365678 24.670587380672547, 60.163303711361145
* 24.664257803508647, 60.16193970279525 24.6590194867117, 60.158682674758644
* 24.65963863846621, 60.15396170672204 24.665516804291176)) So looks okay so
* far...
*/
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(POLYGON);
featureBuilder.add(polygon);
return featureBuilder.buildFeature(null);
}
static class PolygonPoint {
public double x;
public double y;
public PolygonPoint(double x, double y) {
this.x = x;
this.y = y;
}
}
private static void initData(List<PolygonPoint> locations) {
locations.add(new PolygonPoint(60.1539617067220433, 24.6655168042911761));
locations.add(new PolygonPoint(60.1548304906673010, 24.6743709777188585));
locations.add(new PolygonPoint(60.1568689020934642, 24.6849074357532920));
locations.add(new PolygonPoint(60.1605359340076191, 24.6812279440850340));
locations.add(new PolygonPoint(60.1635162115265132, 24.6770178504371067));
locations.add(new PolygonPoint(60.1641222365677990, 24.6705873806725471));
locations.add(new PolygonPoint(60.1633037113611451, 24.6642578035086473));
locations.add(new PolygonPoint(60.1619397027952516, 24.6590194867116992));
locations.add(new PolygonPoint(60.1586826747586443, 24.6596386384662090));
locations.add(new PolygonPoint(60.1539617067220433, 24.6655168042911761));
}
public static void main(String[] args) throws IOException, SchemaException {
List<PolygonPoint> locations = new ArrayList<>();
initData(locations);
// create simple feature builder for the locations
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("polygonFeature");
builder.setCRS(DefaultGeographicCRS.WGS84);
builder.add(Polygon.TYPENAME_POLYGON, Polygon.class);
SimpleFeatureType POLYGON = builder.buildFeatureType();
DefaultFeatureCollection collection = new DefaultFeatureCollection();
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
SimpleFeature feature = toFeature(locations, POLYGON, geometryFactory);
collection.add(feature);
collection.forEach(name -> System.out.println(name));
/**
* Degub print in this point looks like this:
* SimpleFeatureImpl:polygonFeature=[SimpleFeatureImpl.Attribute:
* Polygon<Polygon id=fid-77f7c041_174f9627c85_-8000>=POLYGON
* ((60.15396170672204 24.665516804291176, 60.1548304906673 24.67437097771886,
* 60.156868902093464 24.684907435753292, 60.16053593400762 24.681227944085034,
* 60.16351621152651 24.677017850437107, 60.1641222365678 24.670587380672547,
* 60.163303711361145 24.664257803508647, 60.16193970279525 24.6590194867117,
* 60.158682674758644 24.65963863846621, 60.15396170672204 24.665516804291176))]
* So looks okay still...
*/
File shapeFile = new File(new File("2020-").getAbsolutePath() + "shapefile.shp");
Map<String, Serializable> params = new HashMap<>();
params.put("url", shapeFile.toURI().toURL());
params.put("create spatial index", Boolean.TRUE);
ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
ShapefileDataStore dataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
dataStore.createSchema(POLYGON);
Transaction transaction = new DefaultTransaction("create");
String typeName = dataStore.getTypeNames()[0];
SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName);
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
featureStore.setTransaction(transaction);
try {
featureStore.addFeatures(collection);
transaction.commit();
} catch (Exception problem) {
transaction.rollback();
} finally {
transaction.close();
}
}
}
}
然后按预期创建了 5 个文件。但是形状不正确,没有显示任何内容。我正在用这个工具测试它们:https://mapshaper.org/ 但可以 google 一些 shapefile 在线查看器。
每当我看到未写入数据的事务时,我都会查看事务处理。你把它做得很好,因为你在出现异常时回滚。但我强烈建议您也制作一些日志消息,指示发生了哪种异常。特别是当你抓住通用的 Exception
.
查看catch
块:
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
featureStore.setTransaction(transaction);
try {
featureStore.addFeatures(collection);
transaction.commit();
} catch (Exception problem) {
problem.printStackTrace(System.err); // print out the stack trace of the exception
transaction.rollback();
} finally {
transaction.close();
}
}
这至少会让您有机会看看哪里出了问题。
感谢 Ian Turton 链接答案,问题已通过替换此解决:
builder.add(Polygon.TYPENAME_POLYGON, Polygon.class);
有了这个:
builder.add("the_geom", Polygon.class);