View Javadoc
1   /**
2    * 
3    */
4   package org.opentrafficsim.water.demand;
5   
6   import org.geotools.geometry.jts.JTSFactoryFinder;
7   import org.jaitools.jts.CoordinateSequence2D;
8   import org.opentrafficsim.water.AbstractNamed;
9   import org.opentrafficsim.water.RepeatableRandomStream;
10  
11  import com.vividsolutions.jts.geom.Coordinate;
12  import com.vividsolutions.jts.geom.Envelope;
13  import com.vividsolutions.jts.geom.GeometryFactory;
14  import com.vividsolutions.jts.geom.MultiPolygon;
15  import com.vividsolutions.jts.geom.Point;
16  
17  import nl.tudelft.simulation.jstats.streams.StreamInterface;
18  
19  /**
20   * A region that generates demand. Examples are municipalities or (in Europe), NUTS regions.
21   * <p>
22   * Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
23   * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
24   * </p>
25   * <p>
26   * Based on software from the IDVV project, which is Copyright (c) 2013 Rijkswaterstaat - Dienst Water, Verkeer en Leefomgeving
27   * and licensed without restrictions to Delft University of Technology, including the right to sub-license sources and derived
28   * products to third parties.
29   * </p>
30   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
31   * initial version Nov 6, 2016 <br>
32   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
33   */
34  public class Region extends AbstractNamed implements Comparable<Region>
35  {
36      /** */
37      private static final long serialVersionUID = 1L;
38  
39      /** the region to whic this region belongs, e.g. Municipality - Province - Country. */
40      private Region superRegion;
41  
42      /** the number of inhabitants in the region. */
43      private double inhabitants;
44  
45      /** the number of jobs in the region. */
46      private double jobs;
47  
48      /** the center of the region. */
49      private Coordinate center;
50  
51      /** the shape of this region. */
52      private MultiPolygon area;
53  
54      /** export ton/teu factor. */
55      private double exportTonTEU;
56  
57      /** import ton/teu factor. */
58      private double importTonTEU;
59  
60      /** export empty factor. */
61      private double exportEmptyFactor;
62  
63      /** import empty factor. */
64      private double importEmptyFactor;
65  
66      /** current Import TEU per year. */
67      private double currentImportTEUperYear = 0;
68  
69      /** current Export TEU per year. */
70      private double currentExportTEUperYear = 0;
71  
72      /** repeatable stream. */
73      private static StreamInterface randomStream = null;
74  
75      /**
76       * @param name the name of the region
77       * @param superRegion the region of which this region is part; can be null
78       * @param center the coordinate that denotes the center of the region
79       */
80      public Region(final String name, final Region superRegion, final Coordinate center)
81      {
82          super(name);
83          this.superRegion = superRegion;
84          this.center = center;
85  
86          randomStream = RepeatableRandomStream.create(this.getName());
87      }
88  
89      /**
90       * @return the superRegion
91       */
92      public final Region getSuperRegion()
93      {
94          return this.superRegion;
95      }
96  
97      /**
98       * @param jobs the jobs to set
99       */
100     public final void setJobs(final double jobs)
101     {
102         this.jobs = jobs;
103     }
104 
105     /**
106      * @return the jobs
107      */
108     public final double getJobs()
109     {
110         return (this.jobs > 0) ? this.jobs : 1;
111     }
112 
113     /**
114      * @return the center
115      */
116     public final Coordinate getCenter()
117     {
118         return this.center;
119     }
120 
121     /**
122      * @return the inhabitants
123      */
124     public final double getInhabitants()
125     {
126         return this.inhabitants;
127     }
128 
129     /**
130      * @param inhabitants set inhabitants
131      */
132     protected final void setInhabitants(final double inhabitants)
133     {
134         this.inhabitants = inhabitants;
135     }
136 
137     /**
138      * @return the exportTonTEU
139      */
140     public final double getExportTonTEU()
141     {
142         return this.exportTonTEU;
143     }
144 
145     /**
146      * @param exportTonTEU the exportTonTEU to set
147      */
148     public final void setExportTonTEU(final double exportTonTEU)
149     {
150         this.exportTonTEU = exportTonTEU;
151     }
152 
153     /**
154      * @return the importTonTEU
155      */
156     public final double getImportTonTEU()
157     {
158         return this.importTonTEU;
159     }
160 
161     /**
162      * @param importTonTEU the importTonTEU to set
163      */
164     public final void setImportTonTEU(final double importTonTEU)
165     {
166         this.importTonTEU = importTonTEU;
167     }
168 
169     /**
170      * @return the exportEmptyFactor
171      */
172     public final double getExportEmptyFactor()
173     {
174         return this.exportEmptyFactor;
175     }
176 
177     /**
178      * @param exportEmptyFactor the exportEmptyFactor to set
179      */
180     public final void setExportEmptyFactor(final double exportEmptyFactor)
181     {
182         this.exportEmptyFactor = exportEmptyFactor;
183     }
184 
185     /**
186      * @return the importEmptyFactor
187      */
188     public final double getImportEmptyFactor()
189     {
190         return this.importEmptyFactor;
191     }
192 
193     /**
194      * @param importEmptyFactor the importEmptyFactor to set
195      */
196     public final void setImportEmptyFactor(final double importEmptyFactor)
197     {
198         this.importEmptyFactor = importEmptyFactor;
199     }
200 
201     /**
202      * @return the currentExportTEUperYear
203      */
204     public final double getCurrentExportTEUperYear()
205     {
206         return this.currentExportTEUperYear;
207     }
208 
209     /**
210      * @param newExportTEUPerYear update currentExportTEUperYear
211      */
212     public final void setCurrentExportTEUperYear(final double newExportTEUPerYear)
213     {
214         this.currentExportTEUperYear = newExportTEUPerYear;
215     }
216 
217     /**
218      * @param newExportTEUPerYear add to currentExportTEUperYear
219      */
220     public final void addCurrentExportTEUperYear(final double newExportTEUPerYear)
221     {
222         this.currentExportTEUperYear += newExportTEUPerYear;
223     }
224 
225     /**
226      * @return the currentExportTEUperYear
227      */
228     public final double getCurrentImportTEUperYear()
229     {
230         return this.currentImportTEUperYear;
231     }
232 
233     /**
234      * @param newImportTEUPerYear update currentExportTEUperYear
235      */
236     public final void setCurrentImportTEUperYear(final double newImportTEUPerYear)
237     {
238         this.currentImportTEUperYear = newImportTEUPerYear;
239     }
240 
241     /**
242      * @param newImportTEUPerYear add to currentExportTEUperYear
243      */
244     public final void addCurrentImportTEUperYear(final double newImportTEUPerYear)
245     {
246         this.currentImportTEUperYear += newImportTEUPerYear;
247     }
248 
249     /**
250      * @return the area
251      */
252     public final MultiPolygon getArea()
253     {
254         return this.area;
255     }
256 
257     /**
258      * @param area the area to set
259      */
260     public final void setArea(final MultiPolygon area)
261     {
262         this.area = area;
263     }
264 
265     /**
266      * @return random point within a region
267      */
268     public final Coordinate getNextLocationInArea()
269     {
270         Envelope bounds = this.area.getEnvelopeInternal();
271 
272         GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
273 
274         Point p = new Point(new CoordinateSequence2D(0, 0), geometryFactory);
275         while (!isInArea(p))
276         {
277             double latitude = bounds.getMinX() + (randomStream.nextDouble() * ((bounds.getMaxX() - bounds.getMinX())));
278             double longitude = bounds.getMinY() + (randomStream.nextDouble() * ((bounds.getMaxY() - bounds.getMinY())));
279 
280             p = new Point(new CoordinateSequence2D(latitude, longitude), geometryFactory);
281         }
282 
283         return p.getCoordinate();
284     }
285 
286     /**
287      * @param p point
288      * @return whether point is within region bounds
289      */
290     public final boolean isInArea(final Point p)
291     {
292         return this.area.contains(p);
293     }
294 
295     /** {@inheritDoc} */
296     @Override
297     public final int compareTo(final Region other)
298     {
299         return this.getName().compareTo(other.getName());
300     }
301 
302     /** {@inheritDoc} */
303     @Override
304     @SuppressWarnings("checkstyle:designforextension")
305     public String toString()
306     {
307         return "Region " + this.getName();
308     }
309 
310 }