You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GeoTools连接NASA WMTS服务时触发NumberFormatException问题

问题:GeoTools解析NASA WMTS服务Capabilities文档时触发NumberFormatException

我正在学习使用GeoTools库通过WMTS协议加载瓦片,已严格按照官方文档配置环境,尝试了32.1、31.5、31.0多个版本,连接文档指定的NASA WMTS服务时出现异常。该服务返回的XML能力文档中,LegendURL的width值为178.0(异常栈中显示为378.0),GeoTools的解析器因该带小数的数值触发NumberFormatException。想知道这是GeoTools的配置问题,还是NASA WMTS服务不符合标准?官方文档是否已过时?

异常信息如下:

[2025-01-15 11:42:44] [INFOS  ] java.lang.RuntimeException: Parsing failed for width: java.lang.NumberFormatException: For input string: "378.0"
    at org.geotools.xsd.impl.ParseExecutor.visit(ParseExecutor.java:153)
    at org.geotools.xsd.impl.BindingWalker$BindingExecutionChain.execute(BindingWalker.java:218)
    at org.geotools.xsd.impl.BindingWalker.walk(BindingWalker.java:184)
    at org.geotools.xsd.impl.BindingWalker.walk(BindingWalker.java:188)
    at org.geotools.xsd.impl.ElementHandlerImpl.startElement(ElementHandlerImpl.java:180)
    at org.geotools.xsd.impl.ParserHandler.startElement(ParserHandler.java:378)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:518)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:183)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:353)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2726)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:114)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1224)
    at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637)
    at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:326)
    at org.geotools.xsd.Parser.parse(Parser.java:183)
    at org.geotools.xsd.Parser.parse(Parser.java:125)
    at org.geotools.ows.wmts.response.WMTSGetCapabilitiesResponse.<init>(WMTSGetCapabilitiesResponse.java:84)
    at org.geotools.ows.wmts.WMTSSpecification$GetCapsRequest.createResponse(WMTSSpecification.java:381)
    at org.geotools.ows.wmts.WMTSSpecification$GetCapsRequest.createResponse(WMTSSpecification.java:353)
    at org.geotools.data.ows.AbstractOpenWebService.internalIssueRequest(AbstractOpenWebService.java:465)
    at org.geotools.data.ows.AbstractOpenWebService.issueRequest(AbstractOpenWebService.java:493)
    at org.geotools.data.ows.AbstractOpenWebService.negotiateVersion(AbstractOpenWebService.java:287)
    at org.geotools.data.ows.AbstractOpenWebService.<init>(AbstractOpenWebService.java:124)
    at org.geotools.data.ows.AbstractOpenWebService.<init>(AbstractOpenWebService.java:97)
    at org.geotools.data.ows.AbstractOpenWebService.<init>(AbstractOpenWebService.java:88)
    at org.geotools.data.ows.AbstractOpenWebService.<init>(AbstractOpenWebService.java:77)
    at org.geotools.ows.wmts.WebMapTileServer.<init>(WebMapTileServer.java:150)
    at fr.projetlineaire.phasemanager.maps.WMTSTest$WMTSHelper.<init>(WMTSTest.java:65)
    at fr.projetlineaire.phasemanager.maps.WMTSTest$WMTSHelper.of(WMTSTest.java:128)
    at fr.projetlineaire.phasemanager.maps.WMTSTest.launch(WMTSTest.java:28)
    at fr.projetlineaire.phasemanager.main.MainApp.start(MainApp.java:103)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:185)
    at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.lang.NumberFormatException: For input string: "378.0"
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
    at java.base/java.lang.Integer.parseInt(Integer.java:662)
    at java.base/java.math.BigInteger.<init>(BigInteger.java:541)
    at java.base/java.math.BigInteger.<init>(BigInteger.java:679)
    at org.geotools.xs.bindings.XSIntegerBinding.parse(XSIntegerBinding.java:96)
    at org.geotools.xsd.impl.ParseExecutor.visit(ParseExecutor.java:142)
    ... 44 more

问题原因分析

  • 服务端不符合WMTS规范:OGC WMTS标准明确要求LegendURL的width、height属性为非负整数类型,NASA GIBS服务返回的378.0是带小数的数值,属于服务实现不规范。
  • GeoTools解析逻辑严格:GeoTools的XSIntegerBinding类直接将输入字符串转换为BigInteger,不兼容带小数的整数格式,这是严格遵循规范的设计,并非配置错误。
  • 官方文档未过时:文档指定的服务出现了非规范输出,文档本身内容没有问题。

解决方案

临时修复(绕过解析错误)

  1. 自定义XSD绑定兼容小数格式
    编写自定义绑定类,处理带小数的整数字符串,替换GeoTools默认的XSIntegerBinding:

    public class LenientXSIntegerBinding extends XSIntegerBinding {
        @Override
        public Object parse(InstanceComponent instance, Object value) throws Exception {
            if (value instanceof String str) {
                // 去除小数部分,保留整数位
                if (str.contains(".")) {
                    str = str.split("\\.")[0];
                }
                return super.parse(instance, str);
            }
            return super.parse(instance, value);
        }
    }
    

    在创建WMTS解析器时注册该自定义绑定,覆盖默认实现。

  2. 本地修改Capabilities文档
    手动下载NASA WMTS的Capabilities XML文件,将所有带小数的width、height值改为整数(如378.0改为378),然后让GeoTools加载本地修改后的文档。

长期解决方案

  • 向GeoTools项目提交issue,建议优化整数解析逻辑,兼容带小数的数值(自动取整),提升对非严格规范服务的兼容性。
  • 通过NASA EarthData官方渠道反馈GIBS WMTS服务的规范兼容问题,请求修复输出格式。

内容的提问来源于stack exchange,提问作者Guyard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:24:53