George George - 3 years ago 79
Java Question

Show direction of linestring on map - auto zoom on map

I have this code, which plots on a map a linestring which is the track of 2 coordinate points that the user supplies.

public class Quickstart {

public static void main(String[] args) throws Exception {
// display a data store file chooser dialog for shapefiles
File file = JFileDataStoreChooser.showOpenFile("shp", null);
if (file == null) {

FileDataStore store = FileDataStoreFinder.getDataStore(file);
SimpleFeatureSource featureSource = store.getFeatureSource();

GeometryFactory gf = JTSFactoryFinder.getGeometryFactory();

double latitude, longitude, latitudeDest, longitudeDest;
Scanner reader = new Scanner(;
System.out.println("Enter reference longitude and latitude:\n");
longitude = reader.nextDouble();
latitude = reader.nextDouble();
System.out.println("Enter destination longitude and latitude:\n");
longitudeDest = reader.nextDouble();
latitudeDest = reader.nextDouble();

final String EPSG4326 = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\"," +
"\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\", " +
CoordinateReferenceSystem crs = CRS.parseWKT(EPSG4326);

Point start = gf.createPoint(new Coordinate(longitude, latitude));
Point end = gf.createPoint(new Coordinate(longitudeDest, latitudeDest));

GeodeticCalculator gc = new GeodeticCalculator(crs);
gc.setStartingPosition(JTS.toDirectPosition(start.getCoordinate(), crs));
gc.setDestinationPosition(JTS.toDirectPosition(end.getCoordinate(), crs));

// Calculate distance between points
double distance = gc.getOrthodromicDistance();

int totalmeters = (int) distance;
int km = totalmeters / 1000;
int meters = totalmeters - (km * 1000);
float remaining_cm = (float) (distance - totalmeters) * 10000;
remaining_cm = Math.round(remaining_cm);
float cm = remaining_cm / 100;

System.out.println("Distance = " + km + "km " + meters + "m " + cm + "cm");

Coordinate[] coordinates = {start.getCoordinate(), end.getCoordinate()};
LineString line = gf.createLineString(coordinates);

SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
//builder.add("start", Point.class);
//builder.add("end", Point.class);
builder.add("line", LineString.class);
// build the type
final SimpleFeatureType TYPE = builder.buildFeatureType();

SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);

SimpleFeature feature = featureBuilder.buildFeature(null);
DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("internal", TYPE);

// Create style for the line
//Style style = SLD.createSimpleStyle(TYPE,;
Style style = SLD.createLineStyle(, 2.0f);
Layer layer = new FeatureLayer(featureCollection, style);

// Create style for the file
Style shpStyle = SLD.createSimpleStyle(TYPE,;
Layer shpLayer = new FeatureLayer(featureSource, shpStyle);

// Create a map content and add our shapefile to it
MapContent map = new MapContent();

// Now display the map


I have 2 questions:

1) How can I show the direction of the line?From start point to end?

2) When you run the program and see the map , you must manually search for the linestring(red line) and then zoom to map in order to find it.Is there a way to automatically zoom to the line (the coordinates) when the map appears?

Answer Source

For the style you need something like the SLD described here, in code that becomes:

    // Create style for the line
    // Style style = SLD.createSimpleStyle(TYPE,;
    org.geotools.styling.Style style = SLD.createLineStyle(, 2.0f);
    StyleBuilder sb = new StyleBuilder();
    FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
    PointSymbolizer point = sb.createPointSymbolizer();
    Mark mark = sb.createMark("shape://oarrow");

    Graphic graphic = sb.createGraphic(null, mark, null);


    Rule rule = sb.createRule(point);
    style.getFeatureTypeStyles()[0].addRule(rule );
    Layer layer = new FeatureLayer(featureCollection, style);

Zooming into the line is just a case of setting the map viewport to the bounds of the line:

    MapViewport viewport = new MapViewport(featureCollection.getBounds());
    map.setViewport(viewport );

If you want you might want to grow those bounds by a little (10%?) so that you can see the surroundings too.

enter image description here


To avoid the deprecated methods in StyleBuilder you can use:


Expanding the bounding box is just a case of adding some distance to the envelope:

    ReferencedEnvelope bounds = featureCollection.getBounds();
    double delta = bounds.getWidth()/20.0; //5% on each side
    bounds.expandBy(delta );
    MapViewport viewport = new MapViewport(bounds);
    map.setViewport(viewport );
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download