package net.osmand.data; import java.util.ArrayList; import java.util.Collections; import java.util.List; import net.osmand.osm.LatLon; import net.osmand.osm.MapUtils; import net.osmand.osm.Node; import net.osmand.osm.Way; public class Boundary { private long boundaryId; private String name; private int adminLevel; // not necessary ready rings private List outerWays = new ArrayList(1); private List innerWays = new ArrayList(0); private boolean closedWay; public Boundary(boolean closedWay){ this.closedWay = closedWay; } public boolean isClosedWay() { return closedWay; } public void setClosedWay(boolean closedWay) { this.closedWay = closedWay; } public boolean computeIsClosedWay() { if (getOuterWays().size() > 0) { // now we try to merge the ways until we have only one int oldSize = 0; while (getOuterWays().size() != oldSize) { oldSize = getOuterWays().size(); mergeOuterWays(); } // there is one way and last element is equal to the first... List nodes = getOuterWays().get(0).getNodes(); closedWay = getOuterWays().size() == 1 && nodes.get(0).getId() == nodes.get(nodes.size() - 1).getId(); } else { closedWay = false; } return closedWay; } private void mergeOuterWays() { Way way = getOuterWays().get(0); List nodes = way.getNodes(); if (!nodes.isEmpty()) { int nodesSize = nodes.size(); Node first = nodes.get(0); Node last = nodes.get(nodesSize-1); int size = getOuterWays().size(); for (int i = size-1; i >= 1; i--) { //try to find way, that matches the one ... Way anotherWay = getOuterWays().get(i); if (anotherWay.getNodes().isEmpty()) { //remove empty one... getOuterWays().remove(i); } else { if (anotherWay.getNodes().get(0).getId() == first.getId()) { //reverese this way and add it to the actual Collections.reverse(anotherWay.getNodes()); way.getNodes().addAll(0,anotherWay.getNodes()); getOuterWays().remove(i); } else if (anotherWay.getNodes().get(0).getId() == last.getId()) { way.getNodes().addAll(anotherWay.getNodes()); getOuterWays().remove(i); } else if (anotherWay.getNodes().get(anotherWay.getNodes().size()-1).getId() == first.getId()) { //add at begging way.getNodes().addAll(0,anotherWay.getNodes()); getOuterWays().remove(i); } else if (anotherWay.getNodes().get(anotherWay.getNodes().size()-1).getId() == last.getId()) { Collections.reverse(anotherWay.getNodes()); way.getNodes().addAll(anotherWay.getNodes()); getOuterWays().remove(i); } } } } else { //remove way with no nodes! getOuterWays().remove(0); } } public boolean containsPoint(LatLon point) { return containsPoint(point.getLatitude(), point.getLongitude()); } public boolean containsPoint(double latitude, double longitude) { int intersections = 0; for(Way w : outerWays){ for(int i=0; i points = new ArrayList(); for(Way w : outerWays){ points.addAll(w.getNodes()); } for(Way w : innerWays){ points.addAll(w.getNodes()); } return MapUtils.getWeightCenterForNodes(points); } public List getOuterWays() { return outerWays; } public List getInnerWays() { return innerWays; } public long getBoundaryId() { return boundaryId; } public void setBoundaryId(long boundaryId) { this.boundaryId = boundaryId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAdminLevel() { return adminLevel; } public void setAdminLevel(int adminLevel) { this.adminLevel = adminLevel; } @Override public String toString() { return getName() + " alevel:" + getAdminLevel() + " type: relation closed:" + isClosedWay(); } }