有没有人能推荐一个Java组件,可以创建一个漂亮的世界地图图片,并突出显示某些国家(根据一些统计数据)。类似于这张图片:
希望有类似于Google Geo Charts(但适用于Java)的东西: https://developers.google.com/chart/interactive/docs/gallery/geochart,但在服务器端运行,无需互联网连接。理想情况下,我想给一些国家附加权重,以比例突出它们。
可以是开源或商业软件(只要不是价格荒谬的东西)。
有没有人能推荐一个Java组件,可以创建一个漂亮的世界地图图片,并突出显示某些国家(根据一些统计数据)。类似于这张图片:
希望有类似于Google Geo Charts(但适用于Java)的东西: https://developers.google.com/chart/interactive/docs/gallery/geochart,但在服务器端运行,无需互联网连接。理想情况下,我想给一些国家附加权重,以比例突出它们。
可以是开源或商业软件(只要不是价格荒谬的东西)。
我找不到一个Java库来完成你所需要的功能,因此我研究了如何修改SVG样式并将其转换为图像。对于这个任务,我首先想到的是Apache Batik。
我选择使用wikimedia上提供的开源SVG地图(类似于Gregor Opheys的答案),因为这样可以避免版权问题,而且已经准备好了可供国家进行简单CSS修改的模板。(请参阅SVG注释以获取说明)。但有一个小问题,一些在wikimedia上的图像是由Python脚本生成的,这也将CSS样式放入了元素中。如果您想使用这些SVG文件之一,您需要处理它。
令我高兴的是,在Batik维基上有一个非常完美的示例,只需要稍微调整一下就行了。我能够通过进行一些小的语法更改(他们的输出文件名为.jpg,但实际上使用的是PNG转码器)和从项目资源中加载SVG而生成修改后的图像(PNG)。以下是示例代码及我的小更改:
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();
}
}
}
SVGStyleElement
,在此处,您可以看到美国变成了绿色。对于任何其他国家,您只需使用它们的2个字母缩写并选择您想要填充的颜色即可。当然,由于它是CSS,您还可以做诸如更改边框颜色或使用背景图像而不是颜色等事情,因此您有很大的灵活性。<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>
java.util.Map
。
你的函数将接受一组国家名称,并基本上返回地图的SVG字符串。其中,路径的id与集合中的路径匹配时,您将添加一个填充属性和所需的颜色...
下面是代码。您需要下载此文件并将其保存为同一文件夹中的world.svg
。然后将要突出显示的国家作为参数传递给它。程序将写入一个名为out.svg
的文件,您可以在浏览器中打开它(我使用的是Firefox)。希望它能解决问题。我只尝试从eclipse运行它...package com.examples.firstbundle;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
public class SVGMap {
private static String prefix = "";
private static String postfix = "";
private static Map<String, String> worldMap = new TreeMap<String, String>();
private final static String pathFormat = "<path id=\"{0}\" d=\"{1}\" fill=\"{2}\" />";
static {
try {
List<String> lines = Files.readAllLines(FileSystems.getDefault().getPath("world.svg"), StandardCharsets.UTF_8);
boolean pathstarted = false;
for(String line : lines) {
if(isPath(line)) {
pathstarted = true;
worldMap.put(getCountry(line), getPath(line));
} else {
if(!pathstarted) {
prefix += line;
}
else {
postfix += line;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
Set<String> countries = new TreeSet<String>();
for(String country : args) {
countries.add(country);
}
FileOutputStream fileOutputStream = new FileOutputStream("out.svg");
OutputStreamWriter out = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8);
out.append(prefix);
for(String country : worldMap.keySet()) {
out.append(MessageFormat.format(pathFormat, country, worldMap.get(country), countries.contains(country) ? "tomato" : "grey"));
}
out.append(postfix);
out.flush();
out.close();
}
private static String getPath(String line) {
String part = line.split("=")[2];
String path = part.split("\"")[1];
return path;
}
private static String getCountry(String line) {
String part = line.split("=")[1];
String country = part.split("\"")[1];
return country;
}
private static boolean isPath(String line) {
return line.startsWith("<path");
}
}
你可以使用 GWT 应用来实现。GWT (Google Web ToolKit) 是一个基于 Java 的应用程序制作平台。它提供了与 Google Charts JavaScript API 中相同类型的可视化 API,但是使用的是 Java 代码。请查看此链接以获取基于 Java 的图表 API 和地理图表的实时示例 http://gwt-charts.appspot.com/#geochart。希望这有所帮助 :)
我认为对你更好的选择是:
gvSIG 以其用户友好的界面而闻名,能够访问最常见的矢量和栅格格式。它具有广泛的工具,用于处理类似地理信息的数据(查询工具、布局创建、地理处理、网络等)。
来源:gvSIG 维基百科