I am making a map with unfolding with processing.core.PApplet. I'm using pure Java instead of Processing (Java 8).
My goal is to save the map as an image on my hard drive, but when I try to save it as a PNG, it is a black image. Same blank result happens when trying to save it as a TIF or JPG.
The map itself has no event dispatcher. You cannot interact with it, no clicking, zooming nor scrolling. It should have no problem saving as an image.
My Main code is quite simple:
import processing.core.PApplet;
public class Main {
public static void main(String args[]) {
PApplet sketch = new ChoroplethMap();
sketch.init();
sketch.save("test.jpg");
}
}
I've also tried the saveFrame()
method as well to no avail. From other forums, it seems like these methods have no issues in Processing but I've found no information on them in pure Java 8.
I've also tried using BufferedImages and streams but it yields the same result: a black image with no map.
Here's my map code, it is pretty much copied from the unfolding library Choropleth map example:
import java.util.HashMap;
import java.util.List;
import processing.core.PApplet;
import de.fhpotsdam.unfolding.UnfoldingMap;
import de.fhpotsdam.unfolding.data.Feature;
import de.fhpotsdam.unfolding.data.GeoJSONReader;
import de.fhpotsdam.unfolding.examples.SimpleMapApp;
import de.fhpotsdam.unfolding.examples.interaction.snapshot.MapSnapshot;
import de.fhpotsdam.unfolding.marker.Marker;
import de.fhpotsdam.unfolding.utils.MapUtils;
/**
* Visualizes population density of the world as a choropleth map. Countries are shaded in proportion to the population
* density.
*
* It loads the country shapes from a GeoJSON file via a data reader, and loads the population density values from
* another CSV file (provided by the World Bank). The data value is encoded to transparency via a simplistic linear
* mapping.
*/
public class ChoroplethMap extends PApplet {
UnfoldingMap map;
HashMap<String, DataEntry> dataEntriesMap;
List<Marker> countryMarkers;
public void setup() {
size(800, 600, OPENGL);
smooth();
map = new UnfoldingMap(this, 50, 50, 700, 500);
map.zoomToLevel(2);
map.setBackgroundColor(240);
//MapUtils.createDefaultEventDispatcher(this, map);
// Load country polygons and adds them as markers
List<Feature> countries = GeoJSONReader.loadData(this, "data/countries.geo.json");
countryMarkers = MapUtils.createSimpleMarkers(countries);
map.addMarkers(countryMarkers);
// Load population data
dataEntriesMap = loadPopulationDensityFromCSV("data/countries-population-density.csv");
println("Loaded " + dataEntriesMap.size() + " data entries");
// Country markers are shaded according to its population density (only once)
shadeCountries();
}
public void draw() {
background(255);
// Draw map tiles and country markers
map.draw();
}
public void shadeCountries() {
for (Marker marker : countryMarkers) {
// Find data for country of the current marker
String countryId = marker.getId();
DataEntry dataEntry = dataEntriesMap.get(countryId);
if (dataEntry != null && dataEntry.value != null) {
// Encode value as brightness (values range: 0-1000)
float transparency = map(dataEntry.value, 0, 700, 10, 255);
marker.setColor(color(255, 0, 0, transparency));
} else {
// No value available
marker.setColor(color(100, 120));
}
}
}
public HashMap<String, DataEntry> loadPopulationDensityFromCSV(String fileName) {
HashMap<String, DataEntry> dataEntriesMap = new HashMap<String, DataEntry>();
String[] rows = loadStrings(fileName);
for (String row : rows) {
// Reads country name and population density value from CSV row
String[] columns = row.split(";");
if (columns.length >= 3) {
DataEntry dataEntry = new DataEntry();
dataEntry.countryName = columns[0];
dataEntry.id = columns[1];
dataEntry.value = Float.parseFloat(columns[2]);
dataEntriesMap.put(dataEntry.id, dataEntry);
}
}
return dataEntriesMap;
}
class DataEntry {
String countryName;
String id;
Integer year;
Float value;
}
}
I feel like I'm not initializing the PApplet in my main class the right way. Is there anything else I need to do besides calling the init()
method?
I'm open to over suggestions besides trying to fix save()
or saveFrame()
, something like using BufferedImages or streams to write to a file.
Thanks, and have a nice day.