Thursday, 24 March 2016

java - How to draw polygons on an existing map?


If you want a map with some circles, squares, etc. representing cities or something else you can use the following code.


Note that you can change the map and the coordinates with yours, and you'll get your own map in a java application!


import java.awt.Color;
import java.net.URL;
import org.geotools.data.DataUtilities;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;

import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureCollections;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.map.FeatureLayer;
import org.geotools.map.MapContent;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.Graphic;

import org.geotools.styling.Mark;
import org.geotools.styling.PointSymbolizer;
import org.geotools.styling.PolygonSymbolizer;
import org.geotools.styling.Rule;
import org.geotools.styling.Style;
import org.geotools.styling.StyleBuilder;
import org.geotools.styling.StyleFactory;
import org.geotools.swing.JMapFrame;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.filter.FilterFactory;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;

public class MyGIS{
public static void main(String[] args) {
try {
usingFeatureCaching();
} catch (Exception e) {

// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static void usingFeatureCaching() throws Exception {

//Shape-file's path
URL url = new URL("file://C:/PE/Italia/reg2011_g.shp");
ShapefileDataStore shapefile = new ShapefileDataStore(url);


// Creates a map and adds the shapefile
MapContent map = new MapContent();

//Set's windows title
map.setTitle("Italy");

//Creates the map style
StyleBuilder styleBuilder = new StyleBuilder();
PolygonSymbolizer restrictedSymb = styleBuilder.createPolygonSymbolizer(Color.LIGHT_GRAY, Color.BLACK, 0);


//Sets opacity
restrictedSymb.getFill().setOpacity(styleBuilder.literalExpression(0.5));
org.geotools.styling.Style myStyle = styleBuilder.createStyle(restrictedSymb);

//Adds another layer to the map
FeatureLayer layer = new FeatureLayer(shapefile.getFeatureSource(), myStyle);
map.addLayer(layer);

//-------------------------- BUILDS THE CIRCLE ON THE MAP ------------------------------------------//


StyleFactory sf = CommonFactoryFinder.getStyleFactory(null);
FilterFactory ff = CommonFactoryFinder.getFilterFactory2();

SimpleFeatureSource fs = shapefile.getFeatureSource();

SimpleFeatureType pointtype = DataUtilities.createType("Location", "the_geom:Point," + "name:String");

SimpleFeatureBuilder sfb = new SimpleFeatureBuilder(pointtype);


double longitude = 537319.7867d;
double latitude = 5062350.2792d;

GeometryFactory geometryFactory= JTSFactoryFinder.getGeometryFactory(null);
com.vividsolutions.jts.geom.Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
sfb.add(point);

SimpleFeatureCollection col = FeatureCollections.newCollection();
SimpleFeature feature1 = sfb.buildFeature(null);
col.add(feature1);



org.geotools.styling.Stroke stroke2 = sf.createStroke(
ff.literal(new Color(0xC8, 0x46, 0x63)),
//circle thickness
ff.literal(1)
);

org.geotools.styling.Fill fill2 = sf.createFill(
ff.literal(new Color(0xff, 0xC8, 0x61)));


map.setTitle("Italia");


//Type of symbol
Mark mark = sf.getCircleMark();

mark.setFill(fill2);
mark.setStroke(stroke2);


Graphic graphic = sf.createDefaultGraphic();
graphic.graphicalSymbols().clear();
graphic.graphicalSymbols().add(mark);

//circle dimension on the map
graphic.setSize(ff.literal(5));

GeometryDescriptor geomDesc = fs.getSchema().getGeometryDescriptor();
String geometryAttributeName = geomDesc.getLocalName();
PointSymbolizer sym2 = sf.createPointSymbolizer(graphic, geometryAttributeName);


Rule rule2 = sf.createRule();
rule2.symbolizers().add(sym2);
Rule rules2[] = {rule2};
FeatureTypeStyle fts2 = sf.createFeatureTypeStyle(rules2);
Style style2 = sf.createStyle();
style2.featureTypeStyles().add(fts2);

map.addLayer(new FeatureLayer(col, style2));



StreamingRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);

//Shows the map
JMapFrame.showMap(map);
}
}

This is the result of the code:



The code's result


PS: Here you can find the complete project, enjoy!



Answer



I've created a while ago a method to draw points on a layer from geotagged flickr pictures. It shows basically how to create a FeatureLayer with custom points


public Layer getFlickrLayer(){

SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();

b.setName( "pictures" );
b.setCRS( DefaultGeographicCRS.WGS84 );

//picture location
b.add( "geom", Point.class );
//picture url
b.add( "url", String.class );

final SimpleFeatureType TYPE = b.buildFeatureType();

SimpleFeatureCollection collection = FeatureCollections.newCollection("internal");
WKTReader2 wkt = new WKTReader2();


for(Photo currentPhoto : this.photoList){

float lat = currentPhoto.getGeoData().getLatitude();
float lng = currentPhoto.getGeoData().getLongitude();

try {
collection.add( SimpleFeatureBuilder.build( TYPE, new Object[]{ wkt.read("POINT("+lng+" "+lat+")"), "<<"+currentPhoto.getSmallUrl()+">>"}, null) );
} catch (ParseException e) {

e.printStackTrace();

}
}
Style style = SLD.createPointStyle("Star", Color.BLUE, Color.BLUE, 0.3f, 15);

Layer flickrLayer = new FeatureLayer(collection, style);

flickrLayer.setTitle("flickr layer");

return flickrLayer;


}

As you can see the SimpleFeatureBuilder can be used to create points. Just use your own lat and lng values and remove the picture url and you create a layer with your custom points. I have also created a style for the points. You can simply add this layer to your existing map.


In case you do not need a more complex feature points can be created without the well known text method.


GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();

Coordinate coordinates = new Coordinate(lat, lng);
Point point = geometryFactory.createPoint(coordinates);

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...