векторизовать многоугольник с помощью JTS с поиском по диапазону

Я пытаюсь векторизовать изображение, используя java, то есть геоинструменты с JAI.

Код минимален и прекрасно работает в 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 содержит класс, но не OperationDescriptors в файлах META-INF/registry.jai.

jar -tf target/quickstart-1.0.jar| grep RangeLookupProcess                                                            
org/geotools/process/raster/RangeLookupProcess.class

редактировать

Я попытался выполнить java.lang.ClassNotFoundException: it.geosolutions.jaiext. range.Range и добавил

<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

хотя снова класс есть:

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$1.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 из-за исключения нулевого указателя


person Georg Heiler    schedule 16.10.2018    source источник
comment
можете ли вы открыть толстую банку с помощью распаковки (или аналогичной) и посмотреть, что находится в папке служб и что содержат эти файлы   -  person Ian Turton    schedule 17.10.2018
comment
Привет @IanTurton, см. github.com/geoHeil/jts -vectorize/tree/master/ для содержимого   -  person Georg Heiler    schedule 17.10.2018
comment
Код, которым вы поделились на github, работает на Intelij? (на моей машине не работает)   -  person miskender    schedule 21.10.2018
comment
Он терпит неудачу с некоторыми исключениями ввода-вывода, но исходная проблема, о которой я сообщил здесь, в SF, не видна, то есть реестр операций JAI зарегистрирован неправильно.   -  person Georg Heiler    schedule 21.10.2018


Ответы (1)


Я думаю, что конфигурация дескрипторов читается из registryFile.jai файла. (*)

Когда создается jar с зависимостями, файл registerFile.jai перезаписывается содержимым последнего jar. Объединение содержимого реестраFile.jai со следующей конфигурацией, добавленной в плагин затенения, устраняет эту проблему. (это добавлено в предоставленный вами источник github)

<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
   <resource>META-INF/registryFile.jai</resource>
</transformer>

(Нет необходимости создавать файл реестра.jai в папке ресурсов вашего проекта/META-INF.)

(*) Я попытался добавить configuration к файлу с другим именем, и он не нашел дескриптор. Даже при попытке OperationRegistry.updateFromStream(is); команда не сработала.

person miskender    schedule 22.10.2018