- Timestamp:
- 2016-11-13T00:29:31+01:00 (8 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/Main.java
r11213 r11247 108 108 import org.openstreetmap.josm.tools.PlatformHookUnixoid; 109 109 import org.openstreetmap.josm.tools.PlatformHookWindows; 110 import org.openstreetmap.josm.tools.RightAndLefthandTraffic; 110 111 import org.openstreetmap.josm.tools.Shortcut; 112 import org.openstreetmap.josm.tools.Territories; 111 113 import org.openstreetmap.josm.tools.Utils; 112 114 … … 516 518 } 517 519 })); 520 521 tasks.add(new InitializationTask(tr("Initializing internal boundaries data"), Territories::initialize)); 522 523 tasks.add(new InitializationTask(tr("Initializing internal traffic data"), RightAndLefthandTraffic::initialize)); 518 524 519 525 tasks.add(new InitializationTask(tr("Initializing validator"), OsmValidator::initialize)); -
trunk/src/org/openstreetmap/josm/actions/SelectByInternalPointAction.java
r11240 r11247 37 37 */ 38 38 public static Collection<OsmPrimitive> getSurroundingObjects(EastNorth internalPoint) { 39 return getSurroundingObjects(Main.getLayerManager().getEditDataSet(), internalPoint );39 return getSurroundingObjects(Main.getLayerManager().getEditDataSet(), internalPoint, false); 40 40 } 41 41 … … 46 46 * @param ds the data set 47 47 * @param internalPoint the internal point. 48 * @param includeMultipolygonWays whether to include multipolygon ways in the result (false by default) 48 49 * @return the surrounding polygons/multipolygons 49 * @since 1124 050 * @since 11247 50 51 */ 51 public static Collection<OsmPrimitive> getSurroundingObjects(DataSet ds, EastNorth internalPoint ) {52 public static Collection<OsmPrimitive> getSurroundingObjects(DataSet ds, EastNorth internalPoint, boolean includeMultipolygonWays) { 52 53 if (ds == null) { 53 54 return Collections.emptySet(); … … 62 63 for (Relation r : ds.getRelations()) { 63 64 if (r.isUsable() && r.isMultipolygon() && r.isSelectable() && Geometry.isNodeInsideMultiPolygon(n, r, null)) { 64 for (RelationMember m : r.getMembers()) { 65 if (m.isWay() && m.getWay().isClosed()) { 66 found.values().remove(m.getWay()); 65 if (!includeMultipolygonWays) { 66 for (RelationMember m : r.getMembers()) { 67 if (m.isWay() && m.getWay().isClosed()) { 68 found.values().remove(m.getWay()); 69 } 67 70 } 68 71 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
r10837 r11247 16 16 import java.util.Collections; 17 17 import java.util.List; 18 import java.util.Locale; 18 19 import java.util.Objects; 20 import java.util.Set; 19 21 import java.util.TreeSet; 20 22 import java.util.function.Function; … … 27 29 import org.openstreetmap.josm.actions.search.SearchCompiler.Match; 28 30 import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError; 31 import org.openstreetmap.josm.data.coor.LatLon; 29 32 import org.openstreetmap.josm.data.osm.Node; 30 33 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 40 43 import org.openstreetmap.josm.tools.RightAndLefthandTraffic; 41 44 import org.openstreetmap.josm.tools.SubclassFilteredCollection; 45 import org.openstreetmap.josm.tools.Territories; 42 46 import org.openstreetmap.josm.tools.Utils; 43 47 … … 867 871 */ 868 872 public static boolean is_right_hand_traffic(Environment env) { 869 if (env.osm instanceof Node) 870 return RightAndLefthandTraffic.isRightHandTraffic(((Node) env.osm).getCoor()); 871 return RightAndLefthandTraffic.isRightHandTraffic(env.osm.getBBox().getCenter()); 873 return RightAndLefthandTraffic.isRightHandTraffic(center(env)); 872 874 } 873 875 … … 944 946 public static Object setting(Environment env, String key) { // NO_UCD (unused code) 945 947 return env.source.settingValues.get(key); 948 } 949 950 /** 951 * Returns the center of the environment OSM primitive. 952 * @param env the environment 953 * @return the center of the environment OSM primitive 954 * @since 11247 955 */ 956 public static LatLon center(Environment env) { // NO_UCD (unused code) 957 return env.osm instanceof Node ? ((Node) env.osm).getCoor() : env.osm.getBBox().getCenter(); 958 } 959 960 /** 961 * Determines if the object is inside territories matching given ISO3166 codes. 962 * @param env the environment 963 * @param codes comma-separated list of ISO3166-1-alpha2 or ISO3166-2 country/subdivision codes 964 * @return {@code true} if the object is inside territory matching given ISO3166 codes 965 * @since 11247 966 */ 967 public static boolean inside(Environment env, String codes) { // NO_UCD (unused code) 968 Set<String> osmCodes = Territories.getIso3166Codes(center(env)); 969 for (String code : codes.toUpperCase(Locale.ENGLISH).split(",")) { 970 if (osmCodes.contains(code.trim())) { 971 return true; 972 } 973 } 974 return false; 975 } 976 977 /** 978 * Determines if the object is outside territories matching given ISO3166 codes. 979 * @param env the environment 980 * @param codes comma-separated list of ISO3166-1-alpha2 or ISO3166-2 country/subdivision codes 981 * @return {@code true} if the object is outside territory matching given ISO3166 codes 982 * @since 11247 983 */ 984 public static boolean outside(Environment env, String codes) { // NO_UCD (unused code) 985 return !inside(env, codes); 946 986 } 947 987 } -
trunk/src/org/openstreetmap/josm/gui/preferences/validator/ValidatorTagCheckerRulesPreference.java
r10378 r11247 154 154 addDefault(def, "religion", tr("Religion"), tr("Checks for errors on religious objects")); 155 155 addDefault(def, "relation", tr("Relations"), tr("Checks for errors on relations")); 156 addDefault(def, "territories", tr("Territories"), tr("Checks for territories-specific features")); 156 157 addDefault(def, "unnecessary", tr("Unnecessary tags"), tr("Checks for unnecessary tags")); 157 158 addDefault(def, "wikipedia", tr("Wikipedia"), tr("Checks for wrong wikipedia tags")); -
trunk/src/org/openstreetmap/josm/tools/RightAndLefthandTraffic.java
r9639 r11247 3 3 4 4 import java.awt.geom.Area; 5 import java.io.File; 6 import java.io.FileInputStream; 7 import java.io.FileOutputStream; 5 8 import java.io.IOException; 6 9 import java.io.InputStream; 10 import java.io.OutputStreamWriter; 11 import java.io.PrintWriter; 12 import java.io.Writer; 13 import java.nio.charset.StandardCharsets; 7 14 import java.util.ArrayList; 8 15 import java.util.Collection; 9 16 import java.util.Collections; 17 import java.util.List; 18 import java.util.Set; 19 20 import org.openstreetmap.josm.Main; 21 import org.openstreetmap.josm.actions.JoinAreasAction; 22 import org.openstreetmap.josm.actions.JoinAreasAction.JoinAreasResult; 23 import org.openstreetmap.josm.actions.JoinAreasAction.Multipolygon; 24 import org.openstreetmap.josm.actions.PurgeAction; 10 25 import org.openstreetmap.josm.data.coor.LatLon; 11 26 import org.openstreetmap.josm.data.osm.BBox; 12 27 import org.openstreetmap.josm.data.osm.DataSet; 28 import org.openstreetmap.josm.data.osm.OsmPrimitive; 29 import org.openstreetmap.josm.data.osm.Relation; 30 import org.openstreetmap.josm.data.osm.RelationMember; 13 31 import org.openstreetmap.josm.data.osm.Way; 14 import org.openstreetmap.josm.io.CachedFile;15 32 import org.openstreetmap.josm.io.IllegalDataException; 16 33 import org.openstreetmap.josm.io.OsmReader; 34 import org.openstreetmap.josm.io.OsmWriter; 35 import org.openstreetmap.josm.io.OsmWriterFactory; 17 36 import org.openstreetmap.josm.tools.GeoPropertyIndex.GeoProperty; 18 37 import org.openstreetmap.josm.tools.Geometry.PolygonIntersection; … … 58 77 * Check if there is right-hand traffic at a certain location. 59 78 * 60 * TODO: Synchronization can be refined inside the {@link GeoPropertyIndex}61 * as most look-ups are read-only.62 79 * @param ll the coordinates of the point 63 80 * @return true if there is right-hand traffic, false if there is left-hand traffic 64 81 */ 65 82 public static synchronized boolean isRightHandTraffic(LatLon ll) { 66 if (leftHandTrafficPolygons == null) {67 initialize();68 }69 83 return !rlCache.get(ll); 70 84 } 71 85 72 private static void initialize() { 86 /** 87 * Initializes Right and lefthand traffic data. 88 * TODO: Synchronization can be refined inside the {@link GeoPropertyIndex} as most look-ups are read-only. 89 */ 90 public static synchronized void initialize() { 73 91 leftHandTrafficPolygons = new ArrayList<>(); 74 try (CachedFile cf = new CachedFile("resource://data/left-right-hand-traffic.osm"); 75 InputStream is = cf.getInputStream()) { 76 DataSet data = OsmReader.parseDataSet(is, null); 77 for (Way w : data.getWays()) { 78 leftHandTrafficPolygons.add(Geometry.getAreaLatLon(w.getNodes())); 79 } 80 } catch (IOException | IllegalDataException ex) { 92 Collection<Way> optimizedWays = loadOptimizedBoundaries(); 93 if (optimizedWays.isEmpty()) { 94 optimizedWays = computeOptimizedBoundaries(); 95 saveOptimizedBoundaries(optimizedWays); 96 } 97 for (Way w : optimizedWays) { 98 leftHandTrafficPolygons.add(Geometry.getAreaLatLon(w.getNodes())); 99 } 100 rlCache = new GeoPropertyIndex<>(new RLTrafficGeoProperty(), 24); 101 } 102 103 private static Collection<Way> computeOptimizedBoundaries() { 104 Collection<Way> ways = new ArrayList<>(); 105 Collection<OsmPrimitive> toPurge = new ArrayList<>(); 106 // Find all outer ways of left-driving countries. Many of them are adjacent (African and Asian states) 107 DataSet data = Territories.getDataSet(); 108 Collection<Relation> allRelations = data.getRelations(); 109 Collection<Way> allWays = data.getWays(); 110 for (Way w : allWays) { 111 if ("left".equals(w.get("driving_side"))) { 112 addWayIfNotInner(ways, w); 113 } 114 } 115 for (Relation r : allRelations) { 116 if (r.isMultipolygon() && "left".equals(r.get("driving_side"))) { 117 for (RelationMember rm : r.getMembers()) { 118 if (rm.isWay() && "outer".equals(rm.getRole())) { 119 addWayIfNotInner(ways, (Way) rm.getMember()); 120 } 121 } 122 } 123 } 124 toPurge.addAll(allRelations); 125 toPurge.addAll(allWays); 126 toPurge.removeAll(ways); 127 // Remove ways from parent relations for following optimizations 128 for (Relation r : OsmPrimitive.getParentRelations(ways)) { 129 r.setMembers(null); 130 } 131 // Remove all tags to avoid any conflict 132 for (Way w : ways) { 133 w.removeAll(); 134 } 135 // Purge all other ways and relations so dataset only contains lefthand traffic data 136 new PurgeAction().doPurge(toPurge, false); 137 // Combine adjacent countries into a single polygon 138 Collection<Way> optimizedWays = new ArrayList<>(); 139 List<Multipolygon> areas = JoinAreasAction.collectMultipolygons(ways); 140 if (areas != null) { 141 try { 142 JoinAreasResult result = new JoinAreasAction().joinAreas(areas); 143 if (result.hasChanges) { 144 for (Multipolygon mp : result.polygons) { 145 optimizedWays.add(mp.outerWay); 146 } 147 } 148 } catch (UserCancelException ex) { 149 Main.warn(ex); 150 } 151 } 152 if (optimizedWays.isEmpty()) { 153 // Problem: don't optimize 154 Main.warn("Unable to join left-driving countries polygons"); 155 optimizedWays.addAll(ways); 156 } 157 return optimizedWays; 158 } 159 160 /** 161 * Adds w to ways, except if it is an inner way of another lefthand driving multipolygon, 162 * as Lesotho in South Africa and Cyprus village in British Cyprus base. 163 * @param ways ways 164 * @param w way 165 */ 166 private static void addWayIfNotInner(Collection<Way> ways, Way w) { 167 Set<Way> s = Collections.singleton(w); 168 for (Relation r : OsmPrimitive.getParentRelations(s)) { 169 if (r.isMultipolygon() && "left".equals(r.get("driving_side")) && 170 "inner".equals(r.getMembersFor(s).iterator().next().getRole())) { 171 if (Main.isDebugEnabled()) { 172 Main.debug("Skipping " + w.get("name:en") + " because inner part of " + r.get("name:en")); 173 } 174 return; 175 } 176 } 177 ways.add(w); 178 } 179 180 private static void saveOptimizedBoundaries(Collection<Way> optimizedWays) { 181 DataSet ds = optimizedWays.iterator().next().getDataSet(); 182 File file = new File(Main.pref.getCacheDirectory(), "left-right-hand-traffic.osm"); 183 try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); 184 OsmWriter w = OsmWriterFactory.createOsmWriter(new PrintWriter(writer), false, ds.getVersion()) 185 ) { 186 w.header(false); 187 w.writeContent(ds); 188 w.footer(); 189 } catch (IOException ex) { 81 190 throw new RuntimeException(ex); 82 191 } 83 rlCache = new GeoPropertyIndex<>(new RLTrafficGeoProperty(), 24); 192 } 193 194 private static Collection<Way> loadOptimizedBoundaries() { 195 try (InputStream is = new FileInputStream(new File(Main.pref.getCacheDirectory(), "left-right-hand-traffic.osm"))) { 196 return OsmReader.parseDataSet(is, null).getWays(); 197 } catch (IllegalDataException | IOException ex) { 198 Main.trace(ex); 199 return Collections.emptyList(); 200 } 84 201 } 85 202 }
Note:
See TracChangeset
for help on using the changeset viewer.