Extracted Multipolygon class from Boundary class and tested with junits.
This could resolve some address issues, we will need to check. (recreate maps, etc...)
This commit is contained in:
parent
547b156c5b
commit
16922dffc8
5 changed files with 467 additions and 166 deletions
|
@ -0,0 +1,173 @@
|
|||
package net.osmand.data;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.Node;
|
||||
import net.osmand.osm.Way;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class MultipolygonTest {
|
||||
|
||||
private Multipolygon testee;
|
||||
private Way poly1_1_of_2;
|
||||
private Way poly1_2_of_2;
|
||||
private int wayid;
|
||||
private Way poly2;
|
||||
private Way openedBaseCircle;
|
||||
private Way closedBaseCircle;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
testee = new Multipolygon();
|
||||
poly1_1_of_2 = polygon(n(0,0),n(1,0),n(1,1),n(1,2));
|
||||
poly1_2_of_2 = polygon(n(1,2),n(0,2),n(-1,2),n(0,0));
|
||||
poly2 = polygon(n(4,4), n(4,5), n(3,5), n(4,4));
|
||||
openedBaseCircle = polygon(n(1,-1), n(1,1), n(-1,1), n(-1,-1));
|
||||
closedBaseCircle = polygon(n(1,-1), n(1,1), n(-1,1), n(-1,-1), n(1,-1));
|
||||
}
|
||||
|
||||
public Way polygon(Node... n) {
|
||||
Way way = new Way(wayid++);
|
||||
for (Node nn : n) {
|
||||
way.addNode(nn);
|
||||
}
|
||||
return way;
|
||||
}
|
||||
|
||||
public Way scale(int i, Way w) {
|
||||
Way way = new Way(wayid++);
|
||||
for (Node nn : w.getNodes()) {
|
||||
way.addNode(n(i*(int)nn.getLatitude(),i*(int)nn.getLongitude()));
|
||||
}
|
||||
return way;
|
||||
}
|
||||
|
||||
public Way move(int i, int j, Way w) {
|
||||
Way way = new Way(wayid++);
|
||||
for (Node nn : w.getNodes()) {
|
||||
way.addNode(n(i+(int)nn.getLatitude(),j+(int)nn.getLongitude()));
|
||||
}
|
||||
return way;
|
||||
}
|
||||
|
||||
public Node n(int i, int j) {
|
||||
return new Node(i, j, i*i + j*j + i*j + i + j); //Node has ID derived from i,j
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_twoWayPolygon() {
|
||||
testee.addOuterWay(poly1_1_of_2);
|
||||
testee.addOuterWay(poly1_2_of_2);
|
||||
assertEquals(1, testee.countOuterPolygons());
|
||||
assertFalse(testee.hasOpenedPolygons());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_oneWayPolygon() {
|
||||
testee.addOuterWay(poly2);
|
||||
assertEquals(1, testee.countOuterPolygons());
|
||||
assertFalse(testee.hasOpenedPolygons());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_containsPoint()
|
||||
{
|
||||
testee.addOuterWay(scale(4,poly2));
|
||||
LatLon center = testee.getCenterPoint();
|
||||
assertTrue(testee.containsPoint(center));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_containsPointOpenedCircle()
|
||||
{
|
||||
testee.addOuterWay(scale(4,openedBaseCircle));
|
||||
LatLon center = testee.getCenterPoint();
|
||||
assertTrue(testee.containsPoint(center));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_containsPointClosedCircle()
|
||||
{
|
||||
testee.addOuterWay(scale(4,openedBaseCircle));
|
||||
LatLon center = testee.getCenterPoint();
|
||||
assertTrue(testee.containsPoint(center));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_oneInnerRingOneOuterRingOpenedCircle()
|
||||
{
|
||||
test_oneInnerRingOneOuterRing(openedBaseCircle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_oneInnerRingOneOuterRingClosedCircle()
|
||||
{
|
||||
test_oneInnerRingOneOuterRing(closedBaseCircle);
|
||||
}
|
||||
|
||||
public void test_oneInnerRingOneOuterRing(Way polygon)
|
||||
{
|
||||
testee.addOuterWay(scale(4,polygon));
|
||||
LatLon center = testee.getCenterPoint();
|
||||
assertTrue(testee.containsPoint(center));
|
||||
|
||||
Multipolygon mpoly2 = new Multipolygon();
|
||||
mpoly2.addOuterWay(polygon);
|
||||
|
||||
assertTrue(testee.containsPoint(mpoly2.getCenterPoint()));
|
||||
|
||||
testee.addInnerWay(polygon);
|
||||
|
||||
assertFalse(testee.containsPoint(mpoly2.getCenterPoint()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_twoInnerRingsOneOuterRingOpenedCircle()
|
||||
{
|
||||
test_twoInnerRingsOneOuterRing(openedBaseCircle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_twoInnerRingsOneOuterRingClosedCircle()
|
||||
{
|
||||
test_twoInnerRingsOneOuterRing(closedBaseCircle);
|
||||
}
|
||||
|
||||
public void test_twoInnerRingsOneOuterRing(Way polygon)
|
||||
{
|
||||
testee.addOuterWay(scale(40,polygon));
|
||||
LatLon center = testee.getCenterPoint();
|
||||
assertTrue(testee.containsPoint(center));
|
||||
|
||||
Multipolygon mpoly2 = new Multipolygon();
|
||||
mpoly2.addOuterWay(polygon);
|
||||
Multipolygon movepoly2 = new Multipolygon();
|
||||
movepoly2.addOuterWay(move(10,10,polygon));
|
||||
|
||||
assertTrue(testee.containsPoint(mpoly2.getCenterPoint()));
|
||||
assertTrue(testee.containsPoint(movepoly2.getCenterPoint()));
|
||||
|
||||
testee.addInnerWay(polygon);
|
||||
testee.addInnerWay(move(10,10,polygon));
|
||||
|
||||
assertFalse(testee.containsPoint(mpoly2.getCenterPoint()));
|
||||
assertFalse(testee.containsPoint(movepoly2.getCenterPoint()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_multipolygon1twoWay2oneWay()
|
||||
{
|
||||
testee.addOuterWay(poly1_1_of_2);
|
||||
testee.addOuterWay(poly1_2_of_2);
|
||||
testee.addOuterWay(poly2);
|
||||
assertEquals(2, testee.countOuterPolygons());
|
||||
assertFalse(testee.hasOpenedPolygons());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,146 +1,18 @@
|
|||
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 {
|
||||
public class Boundary
|
||||
extends Multipolygon
|
||||
{
|
||||
|
||||
private long boundaryId;
|
||||
private String name;
|
||||
private int adminLevel;
|
||||
|
||||
|
||||
// not necessary ready rings
|
||||
private List<Way> outerWays = new ArrayList<Way>(1);
|
||||
private List<Way> innerWays = new ArrayList<Way>(0);
|
||||
private boolean closedWay;
|
||||
private long adminCenterId;
|
||||
|
||||
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 && !getOuterWays().isEmpty()) {
|
||||
oldSize = getOuterWays().size();
|
||||
mergeOuterWays();
|
||||
}
|
||||
if (!getOuterWays().isEmpty()) {
|
||||
// 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();
|
||||
//if not closed, but we have only one way, make it close
|
||||
if (!closedWay && getOuterWays().size() == 1) {
|
||||
nodes.add(nodes.get(0));
|
||||
closedWay = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
closedWay = false;
|
||||
}
|
||||
return closedWay;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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++){
|
||||
if(MapAlgorithms.ray_intersect_lon(w.getNodes().get(i), w.getNodes().get(i+1), latitude, longitude) != -360d){
|
||||
intersections ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(Way w : innerWays){
|
||||
for(int i=0; i<w.getNodes().size() - 1; i++){
|
||||
if(MapAlgorithms.ray_intersect_lon(w.getNodes().get(i), w.getNodes().get(i+1), latitude, longitude) != -360d){
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
private List<Way> getOuterWays() {
|
||||
return outerWays;
|
||||
}
|
||||
|
||||
private List<Way> getInnerWays() {
|
||||
return innerWays;
|
||||
public Boundary() {
|
||||
}
|
||||
|
||||
public long getBoundaryId() {
|
||||
|
@ -169,7 +41,7 @@ public class Boundary {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + " alevel:" + getAdminLevel() + " type: relation closed:" + isClosedWay();
|
||||
return getName() + " alevel:" + getAdminLevel() + " type: has opened polygons:" + hasOpenedPolygons() + " no. of outer polygons:" + countOuterPolygons();
|
||||
}
|
||||
|
||||
public void setAdminCenterId(long l) {
|
||||
|
@ -180,21 +52,4 @@ public class Boundary {
|
|||
return adminCenterId;
|
||||
}
|
||||
|
||||
public void addInnerWay(Way es) {
|
||||
innerWays.add(new Way(es));
|
||||
}
|
||||
|
||||
public void addOuterWay(Way es) {
|
||||
outerWays.add(new Way(es));
|
||||
}
|
||||
|
||||
public void copyWaysFrom(Boundary boundary) {
|
||||
getInnerWays().addAll(boundary.getInnerWays());
|
||||
getOuterWays().addAll(boundary.getOuterWays());
|
||||
}
|
||||
|
||||
public void addOuterWays(List<Way> ring) {
|
||||
outerWays.addAll(ring);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
278
DataExtractionOSM/src/net/osmand/data/Multipolygon.java
Normal file
278
DataExtractionOSM/src/net/osmand/data/Multipolygon.java
Normal file
|
@ -0,0 +1,278 @@
|
|||
package net.osmand.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.osm.Node;
|
||||
import net.osmand.osm.Way;
|
||||
|
||||
/**
|
||||
* The idea of multipolygon:
|
||||
* - we treat each outer way as closed polygon
|
||||
* - multipolygon is always closed!
|
||||
* - each way we try to assign to existing way and form
|
||||
* so a more complex polygon
|
||||
* - number of outer ways, is number of polygons
|
||||
*
|
||||
* @author Pavol Zibrita
|
||||
*/
|
||||
public class Multipolygon {
|
||||
|
||||
protected List<Way> closedOuterWays;
|
||||
protected List<Way> outerWays;
|
||||
protected List<Way> closedInnerWays;
|
||||
protected List<Way> innerWays;
|
||||
|
||||
protected IdentityHashMap<Way,List<Way>> outerInnerMapping;
|
||||
|
||||
private void addNewPolygonPart(List<Way> polygons, List<Way> closedPolygons, Way newPoly) {
|
||||
if (isClosed(newPoly)) {
|
||||
closedPolygons.add(newPoly); //if closed, put directly to closed polygons
|
||||
} else if (polygons.isEmpty()) {
|
||||
polygons.add(newPoly); //if open, and first, put to polygons..
|
||||
} else {
|
||||
// now we try to merge the ways to form bigger polygons
|
||||
Stack<Way> wayStack = new Stack<Way>();
|
||||
wayStack.push(newPoly);
|
||||
addAndMergePolygon(polygons, closedPolygons, wayStack);
|
||||
}
|
||||
//reset the mapping
|
||||
outerInnerMapping = null;
|
||||
}
|
||||
|
||||
private boolean isClosed(Way newPoly) {
|
||||
List<Node> ns = newPoly.getNodes();
|
||||
return !ns.isEmpty() && ns.get(0).getId() == ns.get(ns.size()-1).getId();
|
||||
}
|
||||
|
||||
private void addAndMergePolygon(List<Way> polygons, List<Way> closedPolygons, Stack<Way> workStack) {
|
||||
while (!workStack.isEmpty()) {
|
||||
Way changedWay = workStack.pop();
|
||||
List<Node> nodes = changedWay.getNodes();
|
||||
if (nodes.isEmpty()) {
|
||||
//don't bother with it!
|
||||
continue;
|
||||
}
|
||||
if (isClosed(changedWay)) {
|
||||
polygons.remove(changedWay);
|
||||
closedPolygons.add(changedWay);
|
||||
continue;
|
||||
}
|
||||
|
||||
Node first = nodes.get(0);
|
||||
Node last = nodes.get(nodes.size()-1);
|
||||
for (Way anotherWay : polygons) {
|
||||
if (anotherWay == changedWay) {
|
||||
continue;
|
||||
}
|
||||
//try to find way, that matches the one ...
|
||||
if (anotherWay.getNodes().get(0).getId() == first.getId()) {
|
||||
Collections.reverse(changedWay.getNodes());
|
||||
anotherWay.getNodes().addAll(0,changedWay.getNodes());
|
||||
workStack.push(anotherWay);
|
||||
break;
|
||||
} else if (anotherWay.getNodes().get(0).getId() == last.getId()) {
|
||||
anotherWay.getNodes().addAll(0,changedWay.getNodes());
|
||||
workStack.push(anotherWay);
|
||||
break;
|
||||
} else if (anotherWay.getNodes().get(anotherWay.getNodes().size()-1).getId() == first.getId()) {
|
||||
anotherWay.getNodes().addAll(changedWay.getNodes());
|
||||
workStack.push(anotherWay);
|
||||
break;
|
||||
} else if (anotherWay.getNodes().get(anotherWay.getNodes().size()-1).getId() == last.getId()) {
|
||||
Collections.reverse(changedWay.getNodes());
|
||||
anotherWay.getNodes().addAll(changedWay.getNodes());
|
||||
workStack.push(anotherWay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//if we could not merge the new polygon, and it is not already there, add it!
|
||||
if (workStack.isEmpty() && !polygons.contains(changedWay)) {
|
||||
polygons.add(changedWay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsPoint(LatLon point) {
|
||||
return containsPoint(point.getLatitude(), point.getLongitude());
|
||||
}
|
||||
|
||||
public boolean containsPoint(double latitude, double longitude) {
|
||||
return containsPointInPolygons(closedOuterWays, latitude, longitude) || containsPointInPolygons(outerWays, latitude, longitude);
|
||||
}
|
||||
|
||||
private boolean containsPointInPolygons(List<Way> outerPolygons, double latitude, double longitude) {
|
||||
if (outerPolygons != null) {
|
||||
for (Way polygon : outerPolygons) {
|
||||
List<Way> inners = getOuterInnerMapping().get(polygon);
|
||||
if (polygonContainsPoint(latitude, longitude, polygon, inners)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean polygonContainsPoint(double latitude, double longitude,
|
||||
Way polygon, List<Way> inners) {
|
||||
int intersections = 0;
|
||||
intersections = countIntersections(latitude, longitude, polygon,
|
||||
intersections);
|
||||
if (inners != null) {
|
||||
for (Way w : inners) {
|
||||
intersections = countIntersections(latitude, longitude, w,
|
||||
intersections);
|
||||
}
|
||||
}
|
||||
return intersections % 2 == 1;
|
||||
}
|
||||
|
||||
private int countIntersections(double latitude, double longitude,
|
||||
Way polygon, int intersections) {
|
||||
List<Node> polyNodes = polygon.getNodes();
|
||||
for (int i = 0; i < polyNodes.size() - 1; i++) {
|
||||
if (MapAlgorithms.ray_intersect_lon(polyNodes.get(i),
|
||||
polyNodes.get(i + 1), latitude, longitude) != -360d) {
|
||||
intersections++;
|
||||
}
|
||||
}
|
||||
// special handling, also count first and last, might not be closed, but
|
||||
// we want this!
|
||||
if (MapAlgorithms.ray_intersect_lon(polyNodes.get(0),
|
||||
polyNodes.get(polyNodes.size() - 1), latitude, longitude) != -360d) {
|
||||
intersections++;
|
||||
}
|
||||
return intersections;
|
||||
}
|
||||
|
||||
private IdentityHashMap<Way, List<Way>> getOuterInnerMapping() {
|
||||
if (outerInnerMapping == null) {
|
||||
outerInnerMapping = new IdentityHashMap<Way, List<Way>>();
|
||||
//compute the mapping
|
||||
if ((innerWays != null || closedInnerWays != null)
|
||||
&& countOuterPolygons() != 0) {
|
||||
fillOuterInnerMapping(closedOuterWays);
|
||||
fillOuterInnerMapping(outerWays);
|
||||
}
|
||||
}
|
||||
return outerInnerMapping;
|
||||
}
|
||||
|
||||
private void fillOuterInnerMapping(List<Way> outerPolygons) {
|
||||
for (Way outer : outerPolygons) {
|
||||
List<Way> inners = new ArrayList<Way>();
|
||||
inners.addAll(findInnersFor(outer, innerWays));
|
||||
inners.addAll(findInnersFor(outer, closedInnerWays));
|
||||
outerInnerMapping.put(outer, inners);
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<Way> findInnersFor(Way outer, List<Way> inners) {
|
||||
List<Way> result = new ArrayList<Way>(inners.size());
|
||||
for (Way in : inners) {
|
||||
boolean inIsIn = true;
|
||||
for (Node n : in.getNodes()) {
|
||||
if (!polygonContainsPoint(n.getLatitude(), n.getLongitude(), outer, null)) {
|
||||
inIsIn = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inIsIn) {
|
||||
result.add(in);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Way> getOuterWays() {
|
||||
if (outerWays == null) {
|
||||
outerWays = new ArrayList<Way>(1);
|
||||
}
|
||||
return outerWays;
|
||||
}
|
||||
|
||||
private List<Way> getClosedOuterWays() {
|
||||
if (closedOuterWays == null) {
|
||||
closedOuterWays = new ArrayList<Way>(1);
|
||||
}
|
||||
return closedOuterWays;
|
||||
}
|
||||
|
||||
|
||||
private List<Way> getInnerWays() {
|
||||
if (innerWays == null) {
|
||||
innerWays = new ArrayList<Way>(1);
|
||||
}
|
||||
return innerWays;
|
||||
}
|
||||
|
||||
private List<Way> getClosedInnerWays() {
|
||||
if (closedInnerWays == null) {
|
||||
closedInnerWays = new ArrayList<Way>(1);
|
||||
}
|
||||
return closedInnerWays;
|
||||
}
|
||||
|
||||
public int countOuterPolygons()
|
||||
{
|
||||
return zeroSizeIfNull(outerWays) + zeroSizeIfNull(closedOuterWays);
|
||||
}
|
||||
|
||||
public boolean hasOpenedPolygons()
|
||||
{
|
||||
return zeroSizeIfNull(outerWays) != 0;
|
||||
}
|
||||
|
||||
private int zeroSizeIfNull(List<Way> list) {
|
||||
return list != null ? list.size() : 0;
|
||||
}
|
||||
|
||||
public void addInnerWay(Way es) {
|
||||
addNewPolygonPart(getInnerWays(), getClosedInnerWays(), new Way(es));
|
||||
}
|
||||
|
||||
public void addOuterWay(Way es) {
|
||||
addNewPolygonPart(getOuterWays(), getClosedOuterWays(), new Way(es));
|
||||
}
|
||||
|
||||
public void copyPolygonsFrom(Multipolygon multipolygon) {
|
||||
for (Way inner : multipolygon.getInnerWays()) {
|
||||
addInnerWay(inner);
|
||||
}
|
||||
for (Way outer : multipolygon.getOuterWays()) {
|
||||
addOuterWay(outer);
|
||||
}
|
||||
getClosedInnerWays().addAll(multipolygon.getClosedInnerWays());
|
||||
getClosedOuterWays().addAll(multipolygon.getClosedOuterWays());
|
||||
}
|
||||
|
||||
public void addOuterWays(List<Way> ring) {
|
||||
for (Way outer : ring) {
|
||||
addOuterWay(outer);
|
||||
}
|
||||
}
|
||||
|
||||
public LatLon getCenterPoint() {
|
||||
List<Node> points = new ArrayList<Node>();
|
||||
collectPoints(points, outerWays);
|
||||
collectPoints(points, closedOuterWays);
|
||||
collectPoints(points, innerWays);
|
||||
collectPoints(points, closedInnerWays);
|
||||
return MapUtils.getWeightCenterForNodes(points);
|
||||
}
|
||||
|
||||
private void collectPoints(List<Node> points, List<Way> polygons) {
|
||||
if (polygons != null) {
|
||||
for(Way w : polygons){
|
||||
points.addAll(w.getNodes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -33,6 +33,7 @@ import net.osmand.data.City;
|
|||
import net.osmand.data.City.CityType;
|
||||
import net.osmand.data.DataTileManager;
|
||||
import net.osmand.data.MapObject;
|
||||
import net.osmand.data.Multipolygon;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.data.WayBoundary;
|
||||
import net.osmand.data.preparation.DBStreetDAO.SimpleStreet;
|
||||
|
@ -134,7 +135,7 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
|
|||
|
||||
public void indexBoundariesRelation(Entity e, OsmDbAccessorContext ctx) throws SQLException {
|
||||
Boundary boundary = extractBoundary(e, ctx);
|
||||
if (boundary != null && boundary.isClosedWay() && boundary.getAdminLevel() >= 4 && boundary.getCenterPoint() != null && !Algoritms.isEmpty(boundary.getName())) {
|
||||
if (boundary != null && boundary.getAdminLevel() >= 4 && boundary.getCenterPoint() != null && !Algoritms.isEmpty(boundary.getName())) {
|
||||
LatLon boundaryCenter = boundary.getCenterPoint();
|
||||
List<City> citiesToSearch = new ArrayList<City>();
|
||||
citiesToSearch.addAll(cityManager.getClosestObjects(boundaryCenter.getLatitude(), boundaryCenter.getLongitude(), 3));
|
||||
|
@ -170,11 +171,11 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
|
|||
putCityBoundary(boundary, cityFound);
|
||||
}
|
||||
allBoundaries.add(boundary);
|
||||
} else if (boundary != null && !boundary.isClosedWay()){
|
||||
} else if (boundary != null){
|
||||
if(logMapDataWarn != null) {
|
||||
logMapDataWarn.warn("Not using opened boundary: " + boundary);
|
||||
logMapDataWarn.warn("Not using boundary: " + boundary);
|
||||
} else {
|
||||
log.info("Not using opened boundary: " + boundary);
|
||||
log.info("Not using boundary: " + boundary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,9 +262,7 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
|
|||
&& oldBoundary != boundary
|
||||
&& boundary.getName().equalsIgnoreCase(
|
||||
oldBoundary.getName())) {
|
||||
if (!oldBoundary.isClosedWay() && !boundary.isClosedWay()) {
|
||||
oldBoundary.copyWaysFrom(boundary);
|
||||
}
|
||||
oldBoundary.copyPolygonsFrom(boundary);
|
||||
}
|
||||
} else {
|
||||
cityBoundaries.put(cityFound, boundary);
|
||||
|
@ -299,7 +298,7 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
|
|||
if (e instanceof Relation) {
|
||||
Relation aRelation = (Relation) e;
|
||||
ctx.loadEntityRelation(aRelation);
|
||||
boundary = new Boundary(true); //is computed later
|
||||
boundary = new Boundary(); //is computed later
|
||||
boundary.setName(aRelation.getTag(OSMTagKey.NAME));
|
||||
boundary.setBoundaryId(aRelation.getId());
|
||||
boundary.setAdminLevel(extractBoundaryAdminLevel(aRelation));
|
||||
|
@ -321,14 +320,9 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
|
|||
boundary.setAdminCenterId(es.getId());
|
||||
}
|
||||
}
|
||||
boundary.computeIsClosedWay();
|
||||
} else if (e instanceof Way) {
|
||||
if (!visitedBoundaryWays.contains(e.getId())) {
|
||||
boolean closed = false;
|
||||
if(((Way) e).getNodeIds().size() > 1){
|
||||
closed = ((Way) e).getFirstNodeId() == ((Way) e).getLastNodeId();
|
||||
}
|
||||
boundary = new WayBoundary(closed);
|
||||
boundary = new WayBoundary();
|
||||
boundary.setName(e.getTag(OSMTagKey.NAME));
|
||||
boundary.setBoundaryId(e.getId());
|
||||
boundary.setAdminLevel(extractBoundaryAdminLevel(e));
|
||||
|
@ -543,7 +537,7 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
|
|||
nearestObjects.addAll(cityVillageManager.getClosestObjects(location.getLatitude(),location.getLongitude()));
|
||||
//either we found a city boundary the street is in
|
||||
for (City c : nearestObjects) {
|
||||
Boundary boundary = cityBoundaries.get(c);
|
||||
Multipolygon boundary = cityBoundaries.get(c);
|
||||
if (isInNames.contains(c.getName()) || (boundary != null && boundary.containsPoint(location))) {
|
||||
result.add(c);
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
|
||||
private Node checkOuterWaysEncloseInnerWays(List<List<Way>> completedRings, Map<Entity, String> entities) {
|
||||
List<List<Way>> innerWays = new ArrayList<List<Way>>();
|
||||
Boundary outerBoundary = new Boundary(true);
|
||||
Boundary outerBoundary = new Boundary();
|
||||
Node toReturn = null;
|
||||
for (List<Way> ring : completedRings) {
|
||||
boolean innerType = "inner".equals(entities.get(ring.get(0))); //$NON-NLS-1$
|
||||
|
@ -263,6 +263,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
return w1;
|
||||
}
|
||||
|
||||
//TODO Can the Multipolygon class be the one that replaces this?
|
||||
private void combineMultiPolygons(Way w, List<List<Way>> completedRings, List<List<Way>> incompletedRings) {
|
||||
long lId = w.getEntityIds().get(w.getEntityIds().size() - 1).getId().longValue();
|
||||
long fId = w.getEntityIds().get(0).getId().longValue();
|
||||
|
|
Loading…
Reference in a new issue