I want to transform a geojson in a .png image. Do you have any lib/tool/tip to accomplish this task in Java? I googled a lot but no luck.
-
1As a one off, or as part of a service?– nmtokenCommented Jun 29, 2017 at 17:39
-
3gdal_rasterize will create a .png from almost any Vector format, including geojson. This isn't Java based.– klewisCommented Jun 29, 2017 at 19:09
-
@nmtoken as a maven dependency would be perfect.– FrancescoCommented Jun 29, 2017 at 19:42
-
@klewis I will check for gdal I don't know it.– FrancescoCommented Jun 29, 2017 at 19:42
-
geotools has everything you need– Ian TurtonCommented Jun 29, 2017 at 19:46
|
Show 1 more comment
2 Answers
If you chose GeoTools it is a fairly simple process, fetch your geojson from somewhere:
URL states = new URL("http://geojson.xyz/naturalearth-3.3.0/ne_110m_admin_1_states_provinces.geojson");
FeatureJSON featureJSON = new FeatureJSON();
FeatureCollection features = featureJSON.readFeatureCollection(states.openStream());
Then add them to a map with a style:
MapContent mapContent = new MapContent();
mapContent.setTitle("Quickstart");
Style style = SLD.createSimpleStyle(features.getSchema());
Layer layer = new FeatureLayer(features, style);
mapContent.addLayer(layer);
Finally create an image and render the map:
File outputFile = new File("states.png");
ImageOutputStream outputImageFile = null;
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(outputFile);
outputImageFile = ImageIO.createImageOutputStream(fileOutputStream);
int w = 1000;
ReferencedEnvelope bounds = features.getBounds();
int h = (int) (w * (bounds.getHeight() / bounds.getWidth()));
BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bufferedImage.createGraphics();
mapContent.getViewport().setMatchingAspectRatio(true);
mapContent.getViewport().setScreenArea(new Rectangle(Math.round(w), Math.round(h)));
mapContent.getViewport().setBounds(bounds);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle outputArea = new Rectangle(w, h);
GTRenderer renderer = new StreamingRenderer();
LabelCacheImpl labelCache = new LabelCacheImpl();
Map<Object, Object> hints = renderer.getRendererHints();
if (hints == null) {
hints = new HashMap<>();
}
hints.put(StreamingRenderer.LABEL_CACHE_KEY, labelCache);
renderer.setRendererHints(hints);
renderer.setMapContent(mapContent);
renderer.paint(g2d, outputArea, bounds);
ImageIO.write(bufferedImage, "png", outputImageFile);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (outputImageFile != null) {
outputImageFile.flush();
outputImageFile.close();
fileOutputStream.flush();
fileOutputStream.close();
}
} catch (IOException e) {// don't care now
}
}
}
-
Hi, thanks for your solution. It works pretty well! How would you define the scale of the geojson file please?– hzitounCommented May 13, 2020 at 15:30
-
1GeoJSON is a vector format - it doesn't have a scale. To scale the map you can change the
w
variable which is the width of the map. Commented May 13, 2020 at 16:25 -
could you please tell me if there is a way to get the GPS coordinates of a pixel in the outputted image? I want to georeference a sub-image in the big image and get the GPS coordinates. Many thanks in advance.– hzitounCommented Apr 7, 2021 at 8:43
-
any help please? I just want to not loose the GPS coordinates when I generate the image. Is there a way to get a list of matches (x, y) in image <=> (lat, long) in geojson?– hzitounCommented Jun 3, 2021 at 17:27
-
Hi Ian. What about the deprecation messages from FeatureJSON and readFeatureCollection() ? How can I update that?– Magno CCommented Aug 22 at 0:21
I read points from a shapefile and burn in a png, also with a color classification. The recipe is in python, you need in java but the structure is the same, only must to learn the image java api:
https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html
import sys
from osgeo import gdal, ogr
from PIL import Image, ImageDraw
# Filename of input OGR file
vector_fn = 'points.shp'
# Open the data source and read in the extent
datasource = ogr.Open(vector_fn)
if datasource is None:
print ('Could not open file')
sys.exit(1)
vector_layer = datasource.GetLayer()
mapXmin, mapXmax, mapYmin, mapYmax = vector_layer.GetExtent()
# http://gdal.org/python/osgeo.ogr.Layer-class.html#GetExtent
print ("mapXmin:",mapXmin)
print ("mapXmax:",mapXmax)
print ("mapYmin:",mapYmin)
print ("mapYmax:",mapYmax)
print(mapXmin,mapYmin,mapXmax,mapYmax)
print ("W:",mapXmax-mapXmin)
print ("H:",mapYmax-mapYmin)
# Define pixel_size
pixel_size = 0.5 # meters are one pixel
# Create the target data source
target_Width = int(abs(mapXmax - mapXmin) / pixel_size)
target_Height = int(abs(mapYmax - mapYmin) / pixel_size)
print ("target_Width:",target_Width)
print ("target_Height:",target_Height)
image = Image.new('RGBA', (target_Width, target_Height))
draw = ImageDraw.Draw(image)
r=6 #radio
# Loop through the features in the layer
feature = vector_layer.GetNextFeature()
while feature:
# get the x,y coordinates for the point
geom = feature.GetGeometryRef()
xx = geom.GetX();yy = geom.GetY()
x= int((xx-mapXmin) / pixel_size)
y= int((mapYmax-yy) / pixel_size)
value = feature.GetFieldAsDouble('valuation')
color = (18,173,42) #dark green
if(value < 2500): color = (255,0,0) #red
elif(value < 3000): color = (255,255,0) #yellow
draw.ellipse((x-r, y-r, x+r, y+r), fill = color, outline =None)
#draw.point((x, y), 'red')
# destroy the feature and get a new one
feature.Destroy()
feature = vector_layer.GetNextFeature()
# close the data source and text file
datasource.Destroy()
image = image.resize((int(target_Width*0.5), int(target_Height*0.5)), Image.ANTIALIAS)
image.save('circles.png')