2011-01-10 01:03:40 +01:00
|
|
|
package net.osmand.data;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
2011-09-26 21:08:29 +02:00
|
|
|
import java.util.Collections;
|
2011-01-10 01:03:40 +01:00
|
|
|
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;
|
2011-09-19 01:35:51 +02:00
|
|
|
private int adminLevel;
|
2011-01-10 01:03:40 +01:00
|
|
|
|
|
|
|
|
2011-05-03 00:57:02 +02:00
|
|
|
// not necessary ready rings
|
2011-10-07 01:14:16 +02:00
|
|
|
private List<Way> outerWays = new ArrayList<Way>(1);
|
|
|
|
private List<Way> innerWays = new ArrayList<Way>(0);
|
|
|
|
private boolean closedWay;
|
2011-01-10 01:03:40 +01:00
|
|
|
|
2011-09-20 01:47:15 +02:00
|
|
|
public Boundary(boolean closedWay){
|
|
|
|
this.closedWay = closedWay;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isClosedWay() {
|
|
|
|
return closedWay;
|
|
|
|
}
|
2011-01-10 01:03:40 +01:00
|
|
|
|
2011-10-07 01:14:16 +02:00
|
|
|
public void setClosedWay(boolean closedWay) {
|
|
|
|
this.closedWay = closedWay;
|
|
|
|
}
|
2011-10-31 14:20:15 +01:00
|
|
|
|
|
|
|
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<Node> nodes = getOuterWays().get(0).getNodes();
|
|
|
|
closedWay = getOuterWays().size() == 1 && nodes.get(0).getId() == nodes.get(nodes.size() - 1).getId();
|
|
|
|
} else {
|
|
|
|
closedWay = false;
|
2011-09-26 21:08:29 +02:00
|
|
|
}
|
2011-10-07 01:14:16 +02:00
|
|
|
return closedWay;
|
2011-09-26 21:08:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void mergeOuterWays() {
|
|
|
|
Way way = getOuterWays().get(0);
|
|
|
|
List<Node> 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-10 01:03:40 +01:00
|
|
|
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<w.getNodes().size() - 1; i++){
|
2011-06-30 14:11:40 +02:00
|
|
|
if(MapAlgorithms.ray_intersect_lon(w.getNodes().get(i), w.getNodes().get(i+1), latitude, longitude) != -360d){
|
2011-01-10 01:03:40 +01:00
|
|
|
intersections ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(Way w : innerWays){
|
|
|
|
for(int i=0; i<w.getNodes().size() - 1; i++){
|
2011-06-30 14:11:40 +02:00
|
|
|
if(MapAlgorithms.ray_intersect_lon(w.getNodes().get(i), w.getNodes().get(i+1), latitude, longitude) != -360d){
|
2011-01-10 01:03:40 +01:00
|
|
|
intersections ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return intersections % 2 == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public LatLon getCenterPoint(){
|
|
|
|
List<Node> points = new ArrayList<Node>();
|
|
|
|
for(Way w : outerWays){
|
|
|
|
points.addAll(w.getNodes());
|
|
|
|
}
|
|
|
|
for(Way w : innerWays){
|
|
|
|
points.addAll(w.getNodes());
|
|
|
|
}
|
|
|
|
return MapUtils.getWeightCenterForNodes(points);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public List<Way> getOuterWays() {
|
|
|
|
return outerWays;
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<Way> 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;
|
|
|
|
}
|
|
|
|
|
2011-09-19 01:35:51 +02:00
|
|
|
public int getAdminLevel() {
|
2011-01-10 01:03:40 +01:00
|
|
|
return adminLevel;
|
|
|
|
}
|
|
|
|
|
2011-09-19 01:35:51 +02:00
|
|
|
public void setAdminLevel(int adminLevel) {
|
2011-01-10 01:03:40 +01:00
|
|
|
this.adminLevel = adminLevel;
|
|
|
|
}
|
|
|
|
|
2011-10-07 01:14:16 +02:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return getName() + " alevel:" + getAdminLevel() + " type: relation closed:" + isClosedWay();
|
|
|
|
}
|
2011-08-28 15:15:21 +02:00
|
|
|
|
2011-01-10 01:03:40 +01:00
|
|
|
}
|