MATSIM
PolygonFeatureGenerator.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * PolygonFeatureGenerator.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2007 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.utils.gis.matsim2esri.network;
22 
23 import org.geotools.api.feature.simple.SimpleFeature;
24 import org.geotools.api.referencing.crs.CoordinateReferenceSystem;
25 import org.geotools.feature.simple.SimpleFeatureBuilder;
26 import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
27 import org.locationtech.jts.geom.Coordinate;
28 import org.locationtech.jts.geom.GeometryFactory;
29 import org.locationtech.jts.geom.Polygon;
32 
33 public class PolygonFeatureGenerator implements FeatureGenerator{
34 
35  private static final double PI_HALF = Math.PI / 2.0;
36  private static final double TWO_PI = 2.0 * Math.PI;
37 
39  private final CoordinateReferenceSystem crs;
40  private final GeometryFactory geofac;
41  private SimpleFeatureBuilder builder;
42 
43 
44  public PolygonFeatureGenerator(final WidthCalculator widthCalculator, final CoordinateReferenceSystem crs) {
45  this.widthCalculator = widthCalculator;
46  this.crs = crs;
47  this.geofac = new GeometryFactory();
49  }
50 
51  private void initFeatureType() {
52  SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
53  typeBuilder.setName("link");
54  typeBuilder.setCRS(this.crs);
55  typeBuilder.add("the_geom", Polygon.class);
56  typeBuilder.add("ID", String.class);
57  typeBuilder.add("fromID", String.class);
58  typeBuilder.add("toID", String.class);
59  typeBuilder.add("length", Double.class);
60  typeBuilder.add("freespeed", Double.class);
61  typeBuilder.add("capacity", Double.class);
62  typeBuilder.add("lanes", Double.class);
63  typeBuilder.add("visWidth", Double.class);
64 
65  this.builder = new SimpleFeatureBuilder(typeBuilder.buildFeatureType());
66  }
67 
68  @Override
69  public SimpleFeature getFeature(final Link link) {
70  double width = this.widthCalculator.getWidth(link);
71 
72  Coordinate[] coords = createPolygonCoordsForLink(link, width);
73  Polygon p = this.geofac.createPolygon(this.geofac.createLinearRing(coords), null);
74  Object [] attribs = new Object[9];
75  attribs[0] = p;
76  attribs[1] = link.getId().toString();
77  attribs[2] = link.getFromNode().getId().toString();
78  attribs[3] = link.getToNode().getId().toString();
79  attribs[4] = link.getLength();
80  attribs[5] = link.getFreespeed();
81  attribs[6] = link.getCapacity();
82  attribs[7] = link.getNumberOfLanes();
83  attribs[8] = width;
84 
85  try {
86  return this.builder.buildFeature(null, attribs);
87  } catch (IllegalArgumentException e) {
88  throw new RuntimeException(e);
89  }
90  }
91 
92  public static Coordinate[] createPolygonCoordsForLink(final Link link, double width) {
93  Coordinate from = MGC.coord2Coordinate(link.getFromNode().getCoord());
94  Coordinate to = MGC.coord2Coordinate(link.getToNode().getCoord());
95  double length = from.distance(to);
96 
97  final double dx = -from.x + to.x;
98  final double dy = -from.y + to.y;
99 
100  double theta = 0.0;
101  if (dx > 0) {
102  theta = Math.atan(dy/dx);
103  } else if (dx < 0) {
104  theta = Math.PI + Math.atan(dy/dx);
105  } else { // i.e. DX==0
106  if (dy > 0) {
107  theta = PI_HALF;
108  } else {
109  theta = -PI_HALF;
110  }
111  }
112  if (theta < 0.0) theta += TWO_PI;
113  double sinTheta = Math.sin(theta);
114  double cosTheta = Math.cos(theta);
115  double xfrom2 = from.x + sinTheta * width;
116  double yfrom2 = from.y - cosTheta * width;
117  double xto2 = from.x + cosTheta * length + sinTheta * width;
118  double yto2 = from.y + sinTheta * length - cosTheta * width;
119  Coordinate from2 = new Coordinate(xfrom2,yfrom2);
120  Coordinate to2 = new Coordinate(xto2,yto2);
121 
122  return new Coordinate[] {from, to, to2, from2, from};
123  }
124 
125 }
PolygonFeatureGenerator(final WidthCalculator widthCalculator, final CoordinateReferenceSystem crs)
static Coordinate [] createPolygonCoordsForLink(final Link link, double width)
static Coordinate coord2Coordinate(final Coord coord)
Definition: MGC.java:113