任何人都可以推薦一個Java組件,它可以讓你創建一個漂亮的世界地圖圖像,突出顯示某些國家(基於某些統計數據)。類似的東西這個形象:java的地理圖表
一些類似於谷歌地球圖(但爲Java):https://developers.google.com/chart/interactive/docs/gallery/geochart 但運行在服務器端,沒有連接到互聯網。理想情況下,我想重視幾個可以按比例突出顯示的國家。
無論是開源或商業(只要它不是可笑的價格)。
任何人都可以推薦一個Java組件,它可以讓你創建一個漂亮的世界地圖圖像,突出顯示某些國家(基於某些統計數據)。類似的東西這個形象:java的地理圖表
一些類似於谷歌地球圖(但爲Java):https://developers.google.com/chart/interactive/docs/gallery/geochart 但運行在服務器端,沒有連接到互聯網。理想情況下,我想重視幾個可以按比例突出顯示的國家。
無論是開源或商業(只要它不是可笑的價格)。
我無法找到一個Java庫,用來做什麼你要找的人,所以我看着服用SVG和修改其風格,並將其轉換爲圖像。我首先想到的是這個任務:Apache Batik。
我選擇使用wikimedia上的開源svg地圖(類似於Gregor Opheys的答案),因爲它不會讓你感到不關心授權,它也已經爲簡單的CSS修改做好了準備。國家。 (請參閱SVG註釋以獲取指示信息)。有一個問題,維基媒體上的一些圖像是由a python script生成的,它將CSS樣式也放入元素中。如果你想使用這些SVG文件之一,你必須爲此處理。
令我驚喜的是,有almost a perfect example on the batik wiki,只需要一些調整。我能夠通過一個小的語法修改(他們的outfile文件被命名爲.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();
}
}
}
正如我提到的,這種工作方式是將其轉換成你需要的光柵圖像之前添加CSS到SVG。祕密醬是SVGStyleElement
,在這裏你可以看到美國變綠了。對於任何其他國家,您只需使用雙字母有向圖,然後選擇您想要填充的顏色。當然,因爲它是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>
如果你使用一個不同的構建經理,讓我知道,我可以轉儲傳遞依賴樹。
那麼,你可以做一個GWT應用程序。 GWT(Google Web ToolKit)是一個基於Java的平臺應用程序。它提供了與您在Google Charts JavaScript API中看到的相同類型的可視化API,但是在java代碼中。查看此鏈接以獲得基於Java的Chart API和Java代碼http://gwt-charts.appspot.com/#geochart中的地理圖的實例。希望這有助於:)
非常接近,但似乎對Google服務器有依賴性,因此無法離線運行: https://developers.google.com/chart/interactive/faq?csw= 1#離線 – AtliB 2014-10-30 21:48:10
我想對你更好:
gvSIG是對於具有友好的用戶界面,能夠 訪問最常用的格式,矢量和柵格的人知道。它 提供各種各樣的工具與地理類 信息(查詢工具,佈局創作,地理處理,網絡, 等)
源工作:gvSIG Wikipedia
它似乎沒有API ...似乎是一個桌面應用程序。我需要一個可以創建圖片格式的地圖並將其包含在報告中的組件。 – AtliB 2014-11-06 13:14:14
沒有使用它,不知道它是否適合您的需求,但你可以看看Nasa WorldWind。它具有SDK,看起來好像有一個離線模式可用。
檢查:
作爲開始,你可以輕鬆將一個組件或者說像自己的函數使用SVG世界地圖 (例如this)。 將國名的java.util.Map
保留爲SVG源中給出的路徑元素。 您的函數將採用一組國家名稱,並基本上以字符串形式返回地圖的svg。如果路徑的ID與組中的一個相匹配,您可以使用所需的顏色添加填充屬性...
這是代碼。您需要下載this並將其作爲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");
}
}
你可以使用d3js和Javas ScriptEngine。 – user 2014-11-10 18:01:49
你正在尋找什麼樣的輸出格式?你是否期望它是靜態的(即一個光柵圖像),還是需要動態/需要的能力,像鼠標懸停等腳本的東西? – 2014-11-11 02:10:28
@SteveSiebert只是一個靜態的,包含在.pdf報告中,將被打印出來。所以大多數圖像格式應該足夠了 – AtliB 2014-11-11 11:46:42