赞
踩
前台是openlayer vue 项目,后台是spring boot 。需求是前台页面通过设置空间范围,然后对范围内的影像,进行分类输出。中间踩过一些坑,将新路历程记录下来,一来是回顾记录下来,二来,也希望给其他人一些参考。
- //获取geojson数据
- new GeoJSON().writeFeatures(layer.getSource().getFeatures())
{"geoJSON":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[122.75304112963302,42.499201220100524],[122.8043874485347,42.499201220100524],[122.8043874485347,42.52820855610342],[122.75304112963302,42.52820855610342],[122.75304112963302,42.499201220100524]]]},"properties":null}]}}
public void imageCutByShp() throws Exception { gdal.AllRegister()//注册驱动,否则下边执行报错 Dataset source = gdal.Open("E:\\a.tif"); //tif文件路径 Vector vector = new Vector(); vector.add("-cutline"); vector.add("E:\\cut.shp");//shp文件路径 //或者是geojson字符串都可以 //String jsonObject = JSONObject.toJSONString(geoJSON); // vector.add(jsonObject); //geojson的字符串 vector.add("-crop_to_cutline"); WarpOptions warpAppOptions = new WarpOptions(vector); Dataset[] datasets = new Dataset[]{source}; Dataset output = gdal.Warp("E:\\output.tif", datasets, warpAppOptions); //第一个参数是生成结果路径和文件名 }
(小编是集成用其他小伙伴利用python深度学习完成的工具,对应的exe,实现分类)
try { String output = "E:\\a.shp"; Dataset dataset = gdal.Open(output); Band band = dataset.GetRasterBand(1); SpatialReference prj = new SpatialReference(); if (!dataset.GetProjectionRef().isEmpty()) { prj.ImportFromWkt(dataset.GetProjectionRef()); } Driver driver = gdal.GetDriverByName("ESRI Shapefile"); Dataset dsOut = driver.Create(output, dataset.getRasterXSize(), dataset.getRasterYSize(), 1, gdalconst.GDT_Byte); Layer layer = dsOut.CreateLayer("layer", prj); FieldDefn field = new FieldDefn("value", ogr.OFTReal); //第二个参数是字段类型,ogr.OFTInteger和ogr.OFTReal都是属性字段的数据类型,但它们的区别在于存储的数据类型不同。ogr.OFTInteger表示整数类型,而ogr.OFTReal表示浮点数类型。如果您需要存储整数类型的属性值,可以使用ogr.OFTInteger,如果需要存储浮点数类型的属性值,可以使用ogr.OFTReal。在创建属性字段时,需要根据实际情况选择合适的数据类型。 layer.CreateField(field); //矢量化 gdal.Polygonize(band, null, layer, 0); Feature feature = layer.GetNextFeature(); while (null != feature) { int value = feature.GetFieldAsInteger("value"); if (value == 0) { layer.DeleteFeature(feature.GetFID()); } feature = layer.GetNextFeature(); } layer.SyncToDisk(); File[] files = new File[5]; files[0] = new File(output); files[1] = new File(output.replace(".shp", ".dbf")); files[2] = new File(output.replace(".shp", ".prj")); files[3] = new File(output.replace(".shp", ".shx")); dataset.delete(); dsOut.delete(); } catch (Exception exception) { log.error("影像转shp失败:" + exception.toString()); }
以上是tif转shp,小编也试过tif直接转geojson,将驱动改成GeoJSON的,Driver driver = gdal.GetDriverByName("GeoJSON");File[] files = new File[1];files[0] = new File(output);也能转成功,但是layer.GetNextFeature()一直是null,得到的数据里也没有将栅格像素值转到geojson属性里。
由于前台openlayer显示的坐标系统是4326的,分析的影像坐标系统是cgcs2000的,前台页面通过openlayer转坐标系统,图形偏的好远,不成功,所以在后台利用geotools中的JTS进行坐标转换
public SimpleFeatureCollection readShp() throws Exception { SimpleFeatureCollection simpleFeatureCollection = null; ShapefileDataStore shpDataStore = null; try { String input = "E:\\a.shp'"; File file = new File(input); shpDataStore = new ShapefileDataStore(file.toURL()); //设置字符编码 Charset charset = "GBK" shpDataStore.setCharset(charset); String typeName = shpDataStore.getTypeNames()[0]; SimpleFeatureSource featureSource = null; featureSource = shpDataStore.getFeatureSource(typeName); simpleFeatureCollection = featureSource.getFeatures(); } catch (Exception exception) { log.error("读取shp失败:" + exception.toString()); throw new Exception ("读取shp失败:" + exception.toString()); } return simpleFeatureCollection; }
- /**
- * @param simpleFeatureCollection 要素集
- * @param currentCRS 当前的坐标系统
- * @param targetCRS 转换的坐标系统
- */
- public SimpleFeatureCollection project(SimpleFeatureCollection simpleFeatureCollection, CoordinateReferenceSystem currentCRS, CoordinateReferenceSystem targetCRS) throws MismatchedDimensionException, TransformException, FactoryException, TemplateException {
- // 当前要素集空间参考
- if (null == simpleFeatureCollection || simpleFeatureCollection.size() == 0) {
- return simpleFeatureCollection;
- }
- if (null == targetCRS) {
- throw new Exception("坐标转换错误:targetCRS 空了");
- }
- if(currentCRS==null){
- currentCRS = CRS.decode(CRS.lookupIdentifier(simpleFeatureCollection.getSchema().getCoordinateReferenceSystem(), false), true);
- }
-
- MathTransform transform = null;
- if (!currentCRS.equals(targetCRS)) {
- // 判断是否可直接转换
- if (CRS.isCompatible(currentCRS, targetCRS, true)) {
- // 如果可直接转换 转换完成再叠加
- transform = CRS.findMathTransform(currentCRS, targetCRS, true);
- } else {
- // 否则抛出异常 坐标系不能直接转换。
- throw new Exception("坐标转换错误");
- }
- }
- // transform 不为空说明需要转换坐标
- SimpleFeatureType resultFeatureType = null;
- if (transform != null) {
-
- resultFeatureType = SimpleFeatureTypeBuilder.retype(simpleFeatureCollection.getSchema(), targetCRS);
-
- SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(resultFeatureType);
-
- try (SimpleFeatureIterator iterator1 = simpleFeatureCollection.features()) {
- List<SimpleFeature> resultFeatures = new ArrayList<>();
- while (iterator1.hasNext()) {
- SimpleFeature feature = iterator1.next();
- Geometry geometry = (Geometry) feature.getDefaultGeometry();
- Geometry newGeometry = JTS.transform(geometry, transform);
- featureBuilder.add(newGeometry);
- if (feature.getAttributes().size() > 1) {
- featureBuilder.addAll(feature.getAttributes().subList(1, feature.getAttributes().size()));
- }
-
- SimpleFeature newFeature = featureBuilder.buildFeature(null);
- resultFeatures.add(newFeature);
- }
- simpleFeatureCollection = new ListFeatureCollection(resultFeatureType, resultFeatures);
- }
- }
- return simpleFeatureCollection;
- }

使用featureBuilder.add()方式添加,一定要注意一定按照SimpleFeatureType给的字段顺序进行赋值!!!
- public String featureCollection2GeoJsonStr(SimpleFeatureCollection featureCollection) throws IOException {
- FeatureJSON featureJSON = new FeatureJSON(new GeometryJSON(15));// 避免精度丢失
- FeatureCollection features = (FeatureCollection) featureCollection;
- return featureJSON.toString(features);
- }
- //显示geojson数据
- resultLayer.getSource().addFeatures(new GeoJSON().readFeatures(geojson))
这里需要注意的是由于SimpleFeatureCollection 是 org.geotools.data.simple命名空间下的,featureJSON.toString()方法需要传入的参数FeatureCollection是org.geotools.feature命名空间下的,所以将org.geotools.data.simple.SimpleFeatureCollection 转成org.geotools.feature.FeatureCollection 。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。