使用带有范围查找的 JTS 对多边形进行矢量化
vectorize polygon using JTS with range lookup
我尝试使用 java 对图像进行矢量化,即带有 JAI 的 geotools。
代码最少,在 intelliJ 中运行良好
InputStream stringAsStream = new ByteArrayInputStream(inputAsciiGrid.getBytes(StandardCharsets.UTF_8));
SimpleFeatureIterator vectorizedFeatures = extractor.execute(input, 0, true, null,
null, classificationRanges, null).features();
我的问题是通过 maven 执行此操作时,如:
mvn clean package && \
java -jar target/quickstart-1.0.jar
它失败了,除了
RangeLookup: No OperationDescriptor is registered in the current operation registry under this name
示例代码可以在 https://github.com/geoHeil/jts-vectorize
找到
请注意,jar 包含 class,但不包含 META-INF/registry.jai
文件中的 OperationDescriptors
。
jar -tf target/quickstart-1.0.jar| grep RangeLookupProcess
org/geotools/process/raster/RangeLookupProcess.class
编辑
我试着关注
并添加
<dependency>
<groupId>it.geosolutions.jaiext.utilities</groupId>
<artifactId>jt-utilities</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>it.geosolutions.jaiext.iterators</groupId>
<artifactId>jt-iterators</artifactId>
<version>1.1.8</version>
</dependency>
这会将异常更改为:
Exception in thread "main" java.lang.NoClassDefFoundError: it/geosolutions/jaiext/utilities/ImageLayout2
at FooJava.getAsciiGridFromstring(FooJava.java:49)
at FooJava.main(FooJava.java:35)
Caused by: java.lang.ClassNotFoundException: it.geosolutions.jaiext.utilities.ImageLayout2
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 2 more
make: *** [run-java] Error 1
即使 class 再次出现:
geoheil@geoheilsMacBook ~/Downloads/vectorize/jts-vectorize [20:36:45]
> $ jar -tf target/quickstart-1.0.jar| grep ImageLayout2 [±master ●●]
org/jaitools/imageutils/ImageLayout2.class
这似乎是版本不匹配。
还原和添加 (https://github.com/geotools/geotools/blob/18.4/pom.xml#L97) 中也列出的版本时:
<properties>
<geotools.version>18.4</geotools.version>
<jaiext.version>1.0.16</jaiext.version>
</properties>
<dependencies>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-arcgrid</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-process-raster</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>it.geosolutions.jaiext.utilities</groupId>
<artifactId>jt-utilities</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>it.geosolutions.jaiext.rlookup</groupId>
<artifactId>jt-rlookup</artifactId>
<version>${jaiext.version}</version>
</dependency>
</dependencies>
错误又是第一个。
编辑 2
手动注册缺少的操作描述符:
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/javax.media.jai.registryFile.jai</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/registryFile.jaiext</resource>
</transformer>
并添加两个文件(见上面的名称),内容为:
# --- JAI ext manual re-registration ---
descriptor it.geosolutions.jaiext.rlookup.RangeLookupDescriptor
给我一个新的异常:
java.lang.RuntimeException: - Unable to render RenderedOp for this operation.
at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:827)
at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
at javax.media.jai.RenderedOp.getPropertyNames(RenderedOp.java:1791)
at javax.media.jai.PropertyEnvironment.mapDefaults(PropertyEnvironment.java:270)
at javax.media.jai.PropertyEnvironment.getPropertyNames(PropertyEnvironment.java:125)
at javax.media.jai.WritablePropertySourceImpl.addProperties(WritablePropertySourceImpl.java:298)
at javax.media.jai.RenderedOp.createPropertySource(RenderedOp.java:1817)
at javax.media.jai.RenderedOp.getPropertyNames(RenderedOp.java:1851)
at javax.media.jai.PropertySourceImpl.<init>(PropertySourceImpl.java:143)
at org.geotools.coverage.AbstractCoverage.<init>(AbstractCoverage.java:139)
at org.geotools.coverage.grid.AbstractGridCoverage.<init>(AbstractGridCoverage.java:102)
at org.geotools.coverage.grid.GridCoverage2D.<init>(GridCoverage2D.java:186)
at org.geotools.coverage.grid.GridCoverageFactory.create(GridCoverageFactory.java:589)
at org.geotools.process.raster.RangeLookupProcess.execute(RangeLookupProcess.java:208)
at org.geotools.process.raster.RangeLookupProcess.execute(RangeLookupProcess.java:234)
at org.geotools.process.raster.PolygonExtractionProcess.execute(PolygonExtractionProcess.java:167)
at FooJava.getWktForDbRangeFromRaster(FooJava.java:57)
at FooJava.main(FooJava.java:36)
但是,这并不一定算是进步,即现在连IntelliJ都无法启动了。它失败了:ExceptionInInitializerError
由于空指针异常
我认为描述符的配置是从 registryFile.jai
文件中读取的。(*)
创建具有依赖项的 jar 时,registryFile.jai 文件将被最后一个 jar 的内容覆盖。
将 registryFile.jai 内容与添加到阴影插件的以下配置合并可纠正此问题。 (这已添加到您提供的 github 来源)
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/registryFile.jai</resource>
</transformer>
(无需在项目 resources/META-INF 文件夹中创建 registryFile.jai。)
(*) 我尝试将 configuration 添加到不同的命名文件,但没有找到描述符。
即使尝试 OperationRegistry.updateFromStream(is);命令无效。
我尝试使用 java 对图像进行矢量化,即带有 JAI 的 geotools。
代码最少,在 intelliJ 中运行良好
InputStream stringAsStream = new ByteArrayInputStream(inputAsciiGrid.getBytes(StandardCharsets.UTF_8));
SimpleFeatureIterator vectorizedFeatures = extractor.execute(input, 0, true, null,
null, classificationRanges, null).features();
我的问题是通过 maven 执行此操作时,如:
mvn clean package && \
java -jar target/quickstart-1.0.jar
它失败了,除了
RangeLookup: No OperationDescriptor is registered in the current operation registry under this name
示例代码可以在 https://github.com/geoHeil/jts-vectorize
找到请注意,jar 包含 class,但不包含 META-INF/registry.jai
文件中的 OperationDescriptors
。
jar -tf target/quickstart-1.0.jar| grep RangeLookupProcess
org/geotools/process/raster/RangeLookupProcess.class
编辑
我试着关注
<dependency>
<groupId>it.geosolutions.jaiext.utilities</groupId>
<artifactId>jt-utilities</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>it.geosolutions.jaiext.iterators</groupId>
<artifactId>jt-iterators</artifactId>
<version>1.1.8</version>
</dependency>
这会将异常更改为:
Exception in thread "main" java.lang.NoClassDefFoundError: it/geosolutions/jaiext/utilities/ImageLayout2
at FooJava.getAsciiGridFromstring(FooJava.java:49)
at FooJava.main(FooJava.java:35)
Caused by: java.lang.ClassNotFoundException: it.geosolutions.jaiext.utilities.ImageLayout2
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 2 more
make: *** [run-java] Error 1
即使 class 再次出现:
geoheil@geoheilsMacBook ~/Downloads/vectorize/jts-vectorize [20:36:45]
> $ jar -tf target/quickstart-1.0.jar| grep ImageLayout2 [±master ●●]
org/jaitools/imageutils/ImageLayout2.class
这似乎是版本不匹配。 还原和添加 (https://github.com/geotools/geotools/blob/18.4/pom.xml#L97) 中也列出的版本时:
<properties>
<geotools.version>18.4</geotools.version>
<jaiext.version>1.0.16</jaiext.version>
</properties>
<dependencies>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-arcgrid</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-process-raster</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>it.geosolutions.jaiext.utilities</groupId>
<artifactId>jt-utilities</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>it.geosolutions.jaiext.rlookup</groupId>
<artifactId>jt-rlookup</artifactId>
<version>${jaiext.version}</version>
</dependency>
</dependencies>
错误又是第一个。
编辑 2
手动注册缺少的操作描述符:
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/javax.media.jai.registryFile.jai</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/registryFile.jaiext</resource>
</transformer>
并添加两个文件(见上面的名称),内容为:
# --- JAI ext manual re-registration ---
descriptor it.geosolutions.jaiext.rlookup.RangeLookupDescriptor
给我一个新的异常:
java.lang.RuntimeException: - Unable to render RenderedOp for this operation.
at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:827)
at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
at javax.media.jai.RenderedOp.getPropertyNames(RenderedOp.java:1791)
at javax.media.jai.PropertyEnvironment.mapDefaults(PropertyEnvironment.java:270)
at javax.media.jai.PropertyEnvironment.getPropertyNames(PropertyEnvironment.java:125)
at javax.media.jai.WritablePropertySourceImpl.addProperties(WritablePropertySourceImpl.java:298)
at javax.media.jai.RenderedOp.createPropertySource(RenderedOp.java:1817)
at javax.media.jai.RenderedOp.getPropertyNames(RenderedOp.java:1851)
at javax.media.jai.PropertySourceImpl.<init>(PropertySourceImpl.java:143)
at org.geotools.coverage.AbstractCoverage.<init>(AbstractCoverage.java:139)
at org.geotools.coverage.grid.AbstractGridCoverage.<init>(AbstractGridCoverage.java:102)
at org.geotools.coverage.grid.GridCoverage2D.<init>(GridCoverage2D.java:186)
at org.geotools.coverage.grid.GridCoverageFactory.create(GridCoverageFactory.java:589)
at org.geotools.process.raster.RangeLookupProcess.execute(RangeLookupProcess.java:208)
at org.geotools.process.raster.RangeLookupProcess.execute(RangeLookupProcess.java:234)
at org.geotools.process.raster.PolygonExtractionProcess.execute(PolygonExtractionProcess.java:167)
at FooJava.getWktForDbRangeFromRaster(FooJava.java:57)
at FooJava.main(FooJava.java:36)
但是,这并不一定算是进步,即现在连IntelliJ都无法启动了。它失败了:ExceptionInInitializerError
由于空指针异常
我认为描述符的配置是从 registryFile.jai
文件中读取的。(*)
创建具有依赖项的 jar 时,registryFile.jai 文件将被最后一个 jar 的内容覆盖。 将 registryFile.jai 内容与添加到阴影插件的以下配置合并可纠正此问题。 (这已添加到您提供的 github 来源)
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/registryFile.jai</resource>
</transformer>
(无需在项目 resources/META-INF 文件夹中创建 registryFile.jai。)
(*) 我尝试将 configuration 添加到不同的命名文件,但没有找到描述符。 即使尝试 OperationRegistry.updateFromStream(is);命令无效。