source: josm/trunk/src/org/openstreetmap/josm/tools/RightAndLefthandTraffic.java@ 7206

Last change on this file since 7206 was 7193, checked in by bastiK, 10 years ago

added right- and left-hand traffic database
(new mapcss pseudo-class-condition :righthandtraffic)

Data file (data/left-right-hand-traffic.osm) license: CC0.
Loosely based on boundary lines data from naturalearthdata.com.
Traffic law info from wikipedia.
Boundaries generalized, especially in areas where there seem to be no roads.
Should be mostly correct, but some remote islands and atolls may be assigned wrongly.
Alway check before you start driving. :)

Added fast lookup index similar to QuadBuckets.

  • Property svn:eol-style set to native
File size: 2.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools;
3
4import java.awt.geom.Area;
5import java.io.IOException;
6import java.io.InputStream;
7import java.util.ArrayList;
8import java.util.Collection;
9import org.openstreetmap.josm.data.coor.LatLon;
10import org.openstreetmap.josm.data.osm.BBox;
11import org.openstreetmap.josm.data.osm.DataSet;
12import org.openstreetmap.josm.data.osm.Way;
13import org.openstreetmap.josm.io.IllegalDataException;
14import org.openstreetmap.josm.io.MirroredInputStream;
15import org.openstreetmap.josm.io.OsmReader;
16import org.openstreetmap.josm.tools.GeoPropertyIndex.GeoProperty;
17import org.openstreetmap.josm.tools.Geometry.PolygonIntersection;
18
19/**
20 * Look up, if there is right- or left-hand traffic at a certain place.
21 */
22public class RightAndLefthandTraffic {
23
24 private static class RLTrafficGeoProperty implements GeoProperty<Boolean> {
25
26 @Override
27 public Boolean get(LatLon ll) {
28 for (Area a : leftHandTrafficPolygons) {
29 if (a.contains(ll.lon(), ll.lat()))
30 return true;
31 }
32 return false;
33 }
34
35 @Override
36 public Boolean get(BBox box) {
37 Area abox = new Area(box.toRectangle());
38 for (Area a : leftHandTrafficPolygons) {
39 PolygonIntersection is = Geometry.polygonIntersection(abox, a, 1e-10 /* using deg and not meters */);
40 if (is == PolygonIntersection.FIRST_INSIDE_SECOND)
41 return true;
42 if (is != PolygonIntersection.OUTSIDE)
43 return null;
44 }
45 return false;
46 }
47 }
48
49 private static Collection<Area> leftHandTrafficPolygons;
50 private static GeoPropertyIndex<Boolean> rlCache;
51
52 /**
53 * Check if there is right-hand traffic at a certain location.
54 *
55 * TODO: Synchronization can be refined inside the {@link GeoPropertyIndex}
56 * as most look-ups are read-only.
57 * @param ll the coordinates of the point
58 * @return true if there is right-hand traffic, false if there is left-hand traffic
59 */
60 public static synchronized boolean isRightHandTraffic(LatLon ll) {
61 if (leftHandTrafficPolygons == null) {
62 initialize();
63 }
64 return !rlCache.get(ll);
65 }
66
67 private static void initialize() {
68 leftHandTrafficPolygons = new ArrayList<>();
69 try (InputStream is = new MirroredInputStream("resource://data/left-right-hand-traffic.osm")) {
70 DataSet data = OsmReader.parseDataSet(is, null);
71 for (Way w : data.getWays()) {
72 leftHandTrafficPolygons.add(Geometry.getAreaLatLon(w.getNodes()));
73 }
74 } catch (IOException | IllegalDataException ex) {
75 throw new RuntimeException(ex);
76 }
77 rlCache = new GeoPropertyIndex<Boolean>(new RLTrafficGeoProperty(), 24);
78 }
79
80}
Note: See TracBrowser for help on using the repository browser.