MATSIM
ActivityFacilitiesImpl.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * Facilities.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.facilities;
22 
23 import org.apache.logging.log4j.LogManager;
24 import org.apache.logging.log4j.Logger;
25 import org.matsim.api.core.v01.Coord;
26 import org.matsim.api.core.v01.Id;
27 import org.matsim.api.core.v01.IdMap;
33 
34 import java.util.Collection;
35 import java.util.Iterator;
36 import java.util.Map;
37 import java.util.Map.Entry;
38 import java.util.TreeMap;
39 
45 
47  // member variables
49 
50  private long nextMsg = 1;
51 
52  private static final Logger log = LogManager.getLogger(ActivityFacilitiesImpl.class);
54  private final Attributes attributes = new AttributesImpl();
55 
56  private final IdMap<ActivityFacility, ActivityFacility> facilities = new IdMap<>(ActivityFacility.class); // FIXME potential iteration order change
57 
58  private String name;
59 
61 
63  // constructor
65 
66  @Deprecated // use creational method in FacilitiesUtils instead. kai, feb'14
67  public ActivityFacilitiesImpl(final String name) {
68  this.name = name;
69  this.factory = new ActivityFacilitiesFactoryImpl();
70  }
71 
72  @Deprecated // use creational method in FacilitiesUtils instead. kai, feb'14
74  this(null);
75  }
76 
78  // create methods
80 
82  return createAndAddFacility(id, center, null);
83  }
84 
85  public final ActivityFacilityImpl createAndAddFacility(final Id<ActivityFacility> id, final Coord center, final Id<Link> linkId) {
86  if (this.facilities.containsKey(id)) {
87  throw new IllegalArgumentException("Facility with id=" + id + " already exists.");
88  }
89  ActivityFacilityImpl f = new ActivityFacilityImpl(id, center, linkId);
90  this.facilities.put(f.getId(),f);
91 
92  // show counter
93  if (this.facilities.size() % this.nextMsg == 0) {
94  this.nextMsg *= 2;
95  log.info(" facility # " + this.facilities.size() );
96  }
97 
98  return f;
99  }
100 
101  @Override
103  return this.factory;
104  }
105 
106  @Override
107  public final Map<Id<ActivityFacility>, ? extends ActivityFacility> getFacilities() {
108  return this.facilities;
109  }
110 
111  @Override
112  public final TreeMap<Id<ActivityFacility>, ActivityFacility> getFacilitiesForActivityType(final String act_type) {
113  TreeMap<Id<ActivityFacility>, ActivityFacility> facs = new TreeMap<>();
114  Iterator<ActivityFacility> iter = this.facilities.values().iterator();
115  while (iter.hasNext()){
116  ActivityFacility f = iter.next();
117  Map<String, ? extends ActivityOption> a = f.getActivityOptions();
118  if(a.containsKey(act_type)){
119  facs.put(f.getId(),f);
120  }
121  }
122  return facs;
123  }
124 
125  @Override
126  public String getName() {
127  return this.name;
128  }
129 
130  @Override
131  public void setName(String name) {
132  this.name = name;
133  }
134 
135  @Override
136  public final void addActivityFacility(ActivityFacility facility) {
137  // validation
138  if (this.facilities.containsKey(facility.getId())) {
139  throw new IllegalArgumentException("Facility with id=" + facility.getId() + " already exists.");
140  }
141 
142  this.facilities.put(facility.getId(),facility);
143  }
144 
145  @Override
148  }
149 
150  @Override
151  public String toString() {
152  StringBuilder stb = new StringBuilder(200);
153  stb.append(super.toString());
154  stb.append("\n");
155  stb.append("[number of facilities=");
156  stb.append(this.facilities.size());
157  stb.append("]\n");
158  for ( Entry<Id<ActivityFacility>,? extends ActivityFacility> entry : this.facilities.entrySet() ) {
159  final ActivityFacility fac = entry.getValue();
160  stb.append("[key=");
161  stb.append(entry.getKey().toString());
162  stb.append("; value=");
163  stb.append(fac.toString());
164  stb.append("]\n");
165  }
166 
167  return stb.toString();
168  }
169 
170  synchronized private void buildQuadTree() {
171  /* the method must be synchronized to ensure we only build one quadTree
172  * in case that multiple threads call a method that requires the quadTree.
173  */
174  if (this.facilitiesQuadTree != null) {
175  return;
176  }
177  double startTime = System.currentTimeMillis();
178  double minx = Double.POSITIVE_INFINITY;
179  double miny = Double.POSITIVE_INFINITY;
180  double maxx = Double.NEGATIVE_INFINITY;
181  double maxy = Double.NEGATIVE_INFINITY;
182  for ( ActivityFacility n : this.facilities.values()) {
183  if (n.getCoord().getX() < minx) { minx = n.getCoord().getX(); }
184  if (n.getCoord().getY() < miny) { miny = n.getCoord().getY(); }
185  if (n.getCoord().getX() > maxx) { maxx = n.getCoord().getX(); }
186  if (n.getCoord().getY() > maxy) { maxy = n.getCoord().getY(); }
187  }
188  minx -= 1.0;
189  miny -= 1.0;
190  maxx += 1.0;
191  maxy += 1.0;
192  // yy the above four lines are problematic if the coordinate values are much smaller than one. kai, oct'15
193 
194  log.info("building QuadTree for nodes: xrange(" + minx + "," + maxx + "); yrange(" + miny + "," + maxy + ")");
195  QuadTree<ActivityFacility> quadTree = new QuadTree<>(minx, miny, maxx, maxy);
196  for (ActivityFacility n : this.facilities.values()) {
197  quadTree.put(n.getCoord().getX(), n.getCoord().getY(), n);
198  }
199  /* assign the quadTree at the very end, when it is complete.
200  * otherwise, other threads may already start working on an incomplete quadtree
201  */
202  this.facilitiesQuadTree = quadTree;
203  log.info("Building QuadTree took " + ((System.currentTimeMillis() - startTime) / 1000.0) + " seconds.");
204  }
205 
206 
213  @Override public ActivityFacility getNearestFacility(final Coord coord) {
214  if (this.facilitiesQuadTree == null) { buildQuadTree(); }
215  return this.facilitiesQuadTree.getClosest(coord.getX(), coord.getY());
216  }
217 
225  @Override public Collection<ActivityFacility> getNearestFacilities(final Coord coord, final double distance) {
226  if (this.facilitiesQuadTree == null) { buildQuadTree(); }
227  return this.facilitiesQuadTree.getDisk(coord.getX(), coord.getY(), distance);
228  }
229 
230 
231  @Override
233  return attributes;
234  }
235 }
final void addActivityFacility(ActivityFacility facility)
Collection< ActivityFacility > getNearestFacilities(final Coord coord, final double distance)
Set< Map.Entry< Id< T >, V > > entrySet()
Definition: IdMap.java:209
final ActivityFacilityImpl createAndAddFacility(final Id< ActivityFacility > id, final Coord center, final Id< Link > linkId)
boolean containsKey(Object key)
Definition: IdMap.java:44
Collection< V > values()
Definition: IdMap.java:204
final TreeMap< Id< ActivityFacility >, ActivityFacility > getFacilitiesForActivityType(final String act_type)
ActivityFacility getNearestFacility(final Coord coord)
boolean put(final double x, final double y, final T value)
Definition: QuadTree.java:86
final ActivityFacilityImpl createAndAddFacility(final Id< ActivityFacility > id, final Coord center)
T getClosest(final double x, final double y)
Definition: QuadTree.java:130
final IdMap< ActivityFacility, ActivityFacility > facilities
Collection< T > getDisk(final double x, final double y, final double distance)
Definition: QuadTree.java:142
Map< String, ActivityOption > getActivityOptions()
V put(Id< T > key, V value)
Definition: IdMap.java:141
final Map< Id< ActivityFacility >, ? extends ActivityFacility > getFacilities()