java的地理图表

Atl*_*liB 7 java maps graph geo

任何人都可以推荐一个Java组件,它可以让您创建一个漂亮的世界地图图像,突出显示某些国家/地区(基于一些统计数据).与此图像类似的东西:

突出显示国家的世界地图

类似于谷歌地理图表(但对于Java):https://developers.google.com/chart/interactive/docs/gallery/geochart 但在服务器端运行,没有互联网连接.理想情况下,我想重视一些国家,这些国家会按比例突出它们.

无论是开源还是商业(只要不是价格荒谬的东西).

Ste*_*ert 5

我找不到一个java库来做你想要的,所以我研究了一个SVG并修改它的样式,并将其转换为图像。对于这项任务,我首先想到的是:Apache Batik。

我选择使用维基媒体上提供的开源 svg 地图(类似于 Gregor Opheys 的答案),因为它不是这样做的,所以你不关心许可,它也已经准备好按国家/地区进行简单的 CSS 修改。(有关说明,请参阅 SVG 注释)。有一个问题,维基媒体上的一些图像是由python 脚本生成的,它将 CSS 样式也放在元素中。如果您想使用这些 SVG 文件之一,您必须处理它。

令我高兴的是,蜡染维基上几乎有一个完美的例子,只需要进行一些调整。我能够通过一个小的语法更改(他们的输出文件名为 .jpg 但它使用 png 转码器)和一个小的更改来生成一个修改后的图像 (png),以从项目资源而不是磁盘加载 svg。下面是我的小改动的示例代码:

public class MapMaker {

    private final static String MAP_FLAT = "BlankMap-World6-Equirectangular.svg";
    private final static String MAP_ROUND = "WorldMap.svg";

    public static void main(String... args) {

        try {
            // make a Document with the base map 
            String parser = XMLResourceDescriptor.getXMLParserClassName();
            SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
            Document doc = f.createDocument("http://example.com/stuff",
                    MapMaker.class.getClassLoader().getResourceAsStream(MAP_ROUND));

            // prepare to modify and transcode the document
            SVGDocument sdoc = (SVGDocument) doc;
            Element svgRoot = sdoc.getDocumentElement();
            PNGTranscoder t = new PNGTranscoder();
            TranscoderInput input = new TranscoderInput(doc);

            // find the existing stylesheet in the document
            NodeList stylesList = doc.getElementsByTagName("style");
            Node styleNode = stylesList.item(0);

            // append another stylesheet after the existing one
            SVGStyleElement style = (SVGStyleElement) doc.createElementNS(SVG_NAMESPACE_URI, "style");
            style.setAttributeNS(null, "type", "text/css");
            style.appendChild(doc.createCDATASection(".us {fill: blue;}"));
            styleNode.getParentNode().appendChild(style);

            // transcode the map
            OutputStream ostream = new FileOutputStream("outblue.jpg");
            TranscoderOutput output = new TranscoderOutput(ostream);
            t.transcode(input, output);
            ostream.close();

            // replace the appended stylesheet with another
            SVGStyleElement oldStyle = style;
            style = (SVGStyleElement) doc.createElementNS(SVG_NAMESPACE_URI, "style");
            style.setAttributeNS(null, "type", "text/css");
            style.appendChild(doc.createCDATASection(".us {fill: green;}"));
            styleNode.getParentNode().replaceChild(style, oldStyle);

            // transcode the revised map
            File outFile = new File(System.getProperty("java.io.tmpdir"), "outgreen.png");
            ostream = new FileOutputStream(outFile);
            output = new TranscoderOutput(ostream);
            t.transcode(input, output);
            ostream.close();
            System.out.println("Out File: " + outFile);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如我提到的,它的工作方式是在将其转换为您需要的光栅图像之前将 CSS 添加到 SVG。秘诀是SVGStyleElement,在这里你可以看到美国变绿了。对于任何其他国家/地区,您只需使用他们的 2 个字母的有向图并选择您想要填充的颜色。当然,因为它是 CSS,你也可以做一些事情,比如改变边框颜色或使用背景图像而不是颜色,所以你有很大的灵活性。

我确实不得不稍微处理一下依赖项,所以为了让你克服这个障碍,我将包括我的 maven 依赖项:

<dependencies>
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-parser</artifactId>
        <version>1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-css</artifactId>
        <version>1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-svg-dom</artifactId>
        <version>1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-transcoder</artifactId>
        <version>1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-rasterizer</artifactId>
        <version>1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-codec</artifactId>
        <version>1.7</version>
    </dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)

如果您使用不同的构建管理器,请告诉我,我可以转储传递依赖树。