Overpass tile source (#665)
This commit is contained in:
parent
c0c8abe3a7
commit
23d65486e6
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright 2014 Hannes Janetzek
|
||||
* Copyright 2017 devemux86
|
||||
* Copyright 2019 Gustl22
|
||||
*
|
||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.tiling.source.overpass;
|
||||
|
||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tag;
|
||||
import org.oscim.core.TagSet;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.core.osm.OsmData;
|
||||
import org.oscim.core.osm.OsmElement;
|
||||
import org.oscim.core.osm.OsmNode;
|
||||
import org.oscim.core.osm.OsmRelation;
|
||||
import org.oscim.core.osm.OsmWay;
|
||||
import org.oscim.tiling.ITileDataSink;
|
||||
import org.oscim.tiling.source.ITileDecoder;
|
||||
import org.oscim.tiling.source.mapfile.OSMUtils;
|
||||
import org.oscim.utils.overpass.OverpassAPIReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.oscim.core.MercatorProjection.latitudeToY;
|
||||
import static org.oscim.core.MercatorProjection.longitudeToX;
|
||||
|
||||
public class OverpassTileDecoder implements ITileDecoder {
|
||||
|
||||
private final MapElement mMapElement;
|
||||
private ITileDataSink mTileDataSink;
|
||||
|
||||
private double mTileY, mTileX, mTileScale;
|
||||
|
||||
public OverpassTileDecoder() {
|
||||
mMapElement = new MapElement();
|
||||
mMapElement.layer = 5;
|
||||
}
|
||||
|
||||
public synchronized boolean decode(Tile tile, ITileDataSink sink, InputStream is) {
|
||||
mTileDataSink = sink;
|
||||
mTileScale = 1 << tile.zoomLevel;
|
||||
mTileX = tile.tileX / mTileScale;
|
||||
mTileY = tile.tileY / mTileScale;
|
||||
mTileScale *= Tile.SIZE;
|
||||
|
||||
OsmData data;
|
||||
try {
|
||||
OverpassAPIReader reader = new OverpassAPIReader();
|
||||
reader.parse(is);
|
||||
data = reader.getData();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
for (OsmNode element : data.getNodes())
|
||||
parseFeature(element);
|
||||
for (OsmWay element : data.getWays())
|
||||
parseFeature(element);
|
||||
for (OsmRelation element : data.getRelations())
|
||||
parseFeature(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private synchronized void parseFeature(OsmElement element) {
|
||||
if (element.tags == null || element.tags.size() == 0)
|
||||
return;
|
||||
|
||||
synchronized (mMapElement) {
|
||||
mMapElement.clear();
|
||||
mMapElement.tags.clear();
|
||||
|
||||
mMapElement.tags.set(element.tags);
|
||||
//add tag information
|
||||
decodeTags(mMapElement);
|
||||
|
||||
parseGeometry(element);
|
||||
|
||||
if (mMapElement.type == GeometryType.NONE)
|
||||
return;
|
||||
|
||||
mTileDataSink.process(mMapElement);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseGeometry(OsmElement element) {
|
||||
//TODO mulipolygons
|
||||
if (element instanceof OsmWay) {
|
||||
boolean linearFeature = !OSMUtils.isArea(mMapElement);
|
||||
if (linearFeature) {
|
||||
mMapElement.type = GeometryType.LINE;
|
||||
parseLine((OsmWay) element);
|
||||
} else {
|
||||
mMapElement.type = GeometryType.POLY;
|
||||
parsePolygon((OsmWay) element);
|
||||
}
|
||||
} else if (element instanceof OsmNode) {
|
||||
mMapElement.type = GeometryType.POINT;
|
||||
mMapElement.startPoints();
|
||||
parseCoordinate((OsmNode) element);
|
||||
}
|
||||
}
|
||||
|
||||
private void parsePolygon(OsmWay element) {
|
||||
//int ring = 0;
|
||||
|
||||
//for (element.rings) {
|
||||
//if (ring == 0)
|
||||
mMapElement.startPolygon();
|
||||
//else
|
||||
// mMapElement.startHole();
|
||||
|
||||
//ring++;
|
||||
parseCoordSequence(element);
|
||||
removeLastPoint();
|
||||
//}
|
||||
}
|
||||
|
||||
private void removeLastPoint() {
|
||||
mMapElement.pointNextPos -= 2;
|
||||
mMapElement.index[mMapElement.indexCurrentPos] -= 2;
|
||||
}
|
||||
|
||||
private void parseLine(OsmWay element) {
|
||||
mMapElement.startLine();
|
||||
parseCoordSequence(element);
|
||||
}
|
||||
|
||||
private void parseCoordSequence(OsmWay element) {
|
||||
for (OsmNode node : element.nodes)
|
||||
parseCoordinate(node);
|
||||
}
|
||||
|
||||
private void parseCoordinate(OsmNode element) {
|
||||
mMapElement.addPoint((float) ((longitudeToX(element.lon) - mTileX) * mTileScale),
|
||||
(float) ((latitudeToY(element.lat) - mTileY) * mTileScale));
|
||||
|
||||
}
|
||||
|
||||
private void decodeTags(MapElement mapElement) {
|
||||
TagSet tags = mapElement.tags;
|
||||
Tag tag = tags.get(Tag.KEY_ROOF_DIRECTION);
|
||||
if (tag != null) {
|
||||
if (!isNumeric(tag.value)) {
|
||||
switch (tag.value.toLowerCase()) {
|
||||
case "n":
|
||||
case "north":
|
||||
tag.value = "0";
|
||||
break;
|
||||
case "e":
|
||||
case "east":
|
||||
tag.value = "90";
|
||||
break;
|
||||
case "s":
|
||||
case "south":
|
||||
tag.value = "180";
|
||||
break;
|
||||
case "w":
|
||||
case "west":
|
||||
tag.value = "270";
|
||||
break;
|
||||
|
||||
case "ne":
|
||||
tag.value = "45";
|
||||
break;
|
||||
case "se":
|
||||
tag.value = "135";
|
||||
break;
|
||||
case "sw":
|
||||
tag.value = "225";
|
||||
break;
|
||||
case "nw":
|
||||
tag.value = "315";
|
||||
break;
|
||||
|
||||
case "nne":
|
||||
tag.value = "22";
|
||||
break;
|
||||
case "ene":
|
||||
tag.value = "67";
|
||||
break;
|
||||
case "ese":
|
||||
tag.value = "112";
|
||||
break;
|
||||
case "sse":
|
||||
tag.value = "157";
|
||||
break;
|
||||
case "ssw":
|
||||
tag.value = "202";
|
||||
break;
|
||||
case "wsw":
|
||||
tag.value = "247";
|
||||
break;
|
||||
case "wnw":
|
||||
tag.value = "292";
|
||||
break;
|
||||
case "nnw":
|
||||
tag.value = "337";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isNumeric(String str) {
|
||||
try {
|
||||
Float.parseFloat(str);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
* Copyright 2018 devemux86
|
||||
* Copyright 2019 Gustl22
|
||||
*
|
||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.tiling.source.overpass;
|
||||
|
||||
import org.oscim.core.BoundingBox;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.tiling.ITileDataSource;
|
||||
import org.oscim.tiling.OverzoomTileDataSource;
|
||||
import org.oscim.tiling.source.UrlTileDataSource;
|
||||
import org.oscim.tiling.source.UrlTileSource;
|
||||
import org.oscim.utils.overpass.OverpassAPIReader;
|
||||
|
||||
public class OverpassTileSource extends UrlTileSource {
|
||||
|
||||
private static final String DEFAULT_URL = "https://www.overpass-api.de/api/interpreter?data=[out:json];";
|
||||
private static final String DEFAULT_PATH = "(node{{bbox}};way{{bbox}};>;);out%20body;";
|
||||
|
||||
public static class Builder<T extends Builder<T>> extends UrlTileSource.Builder<T> {
|
||||
|
||||
public Builder() {
|
||||
super(DEFAULT_URL, DEFAULT_PATH);
|
||||
zoomMax(17);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OverpassTileSource build() {
|
||||
return new OverpassTileSource(this);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static Builder<?> builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public OverpassTileSource(Builder<?> builder) {
|
||||
super(builder);
|
||||
|
||||
setUrlFormatter(new TileUrlFormatter() {
|
||||
@Override
|
||||
public String formatTilePath(UrlTileSource tileSource, Tile tile) {
|
||||
BoundingBox bb = tile.getBoundingBox();
|
||||
|
||||
String query = OverpassAPIReader.query(
|
||||
bb.getMinLongitude(),
|
||||
bb.getMaxLongitude(),
|
||||
bb.getMaxLatitude(),
|
||||
bb.getMinLatitude(),
|
||||
DEFAULT_PATH);
|
||||
|
||||
/*String encoded;
|
||||
try {
|
||||
query = URLEncoder.encode(query, "utf-8");
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
e1.printStackTrace();
|
||||
return null;
|
||||
}*/
|
||||
return query;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
return new OverzoomTileDataSource(new UrlTileDataSource(this, new OverpassTileDecoder(), getHttpEngine()), mOverZoom);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
* Copyright 2016 devemux86
|
||||
* Copyright 2019 Gustl22
|
||||
*
|
||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||
*
|
||||
@ -75,25 +76,36 @@ public class OverpassAPIReader {
|
||||
|
||||
private final String query;
|
||||
|
||||
public OverpassAPIReader() {
|
||||
this.query = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the specified geographical coordinates.
|
||||
*
|
||||
* @param left The longitude marking the left edge of the bounding box.
|
||||
* @param right The longitude marking the right edge of the bounding box.
|
||||
* @param top The latitude marking the top edge of the bounding box.
|
||||
* @param bottom The latitude marking the bottom edge of the bounding box.
|
||||
* @param baseUrl (optional) The base url of the server (eg.
|
||||
* http://www.openstreetmap.org/api/0.5).
|
||||
*/
|
||||
public OverpassAPIReader(final double left, final double right,
|
||||
final double top, final double bottom, final String baseUrl,
|
||||
final double top, final double bottom,
|
||||
final String query) {
|
||||
this.query = query(left, right, top, bottom, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param left The longitude marking the left edge of the bounding box.
|
||||
* @param right The longitude marking the right edge of the bounding box.
|
||||
* @param top The latitude marking the top edge of the bounding box.
|
||||
* @param bottom The latitude marking the bottom edge of the bounding box.
|
||||
* @param query The prepared query.
|
||||
* @return the processed query with specified bounding box
|
||||
*/
|
||||
public static String query(final double left, final double right,
|
||||
final double top, final double bottom,
|
||||
final String query) {
|
||||
|
||||
String bbox = "(" + Math.min(top, bottom) + "," + Math.min(left, right)
|
||||
+ "," + Math.max(top, bottom) + "," + Math.max(left, right)
|
||||
+ ")";
|
||||
|
||||
this.query = query.replaceAll("\\{\\{bbox\\}\\}", bbox);
|
||||
return query.replaceAll("\\{\\{bbox\\}\\}", bbox);
|
||||
|
||||
}
|
||||
|
||||
@ -335,14 +347,13 @@ public class OverpassAPIReader {
|
||||
System.out.println(msg);
|
||||
}
|
||||
|
||||
public OsmData getData() {
|
||||
|
||||
public void parseInputStream() {
|
||||
String encoded;
|
||||
try {
|
||||
encoded = URLEncoder.encode(this.query, "utf-8");
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
e1.printStackTrace();
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
System.out.println(myBaseUrl + "?data=" + encoded);
|
||||
|
||||
@ -363,6 +374,9 @@ public class OverpassAPIReader {
|
||||
}
|
||||
inputStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
public OsmData getData() {
|
||||
|
||||
for (Entry<OsmRelation, List<TmpRelation>> entry : relationMembersForRelation
|
||||
.entrySet()) {
|
||||
@ -392,8 +406,8 @@ public class OverpassAPIReader {
|
||||
}
|
||||
}
|
||||
}
|
||||
log("nodes: " + ownNodes.size() + " ways: " + ownWays.size()
|
||||
+ " relations: " + ownRelations.size());
|
||||
/*log("nodes: " + ownNodes.size() + " ways: " + ownWays.size()
|
||||
+ " relations: " + ownRelations.size());*/
|
||||
|
||||
// give up references to original collections
|
||||
nodesById = null;
|
||||
|
@ -5,6 +5,7 @@ dependencies {
|
||||
file("${rootDir}/vtm-desktop/natives").eachDir() { dir ->
|
||||
implementation files(dir.path)
|
||||
}
|
||||
implementation project(':vtm-extras')
|
||||
implementation project(':vtm-gdx-poi3d')
|
||||
implementation project(':vtm-http')
|
||||
implementation project(':vtm-jeo')
|
||||
|
88
vtm-playground/src/org/oscim/test/OverpassTest.java
Normal file
88
vtm-playground/src/org/oscim/test/OverpassTest.java
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2016-2018 devemux86
|
||||
* Copyright 2019 Gustl22
|
||||
*
|
||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.test;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.gdx.GdxMapApp;
|
||||
import org.oscim.layers.GroupLayer;
|
||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||
import org.oscim.layers.tile.buildings.S3DBLayer;
|
||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.map.Viewport;
|
||||
import org.oscim.theme.VtmThemes;
|
||||
import org.oscim.tiling.TileSource;
|
||||
import org.oscim.tiling.source.OkHttpEngine;
|
||||
import org.oscim.tiling.source.bitmap.DefaultSources;
|
||||
import org.oscim.tiling.source.overpass.OverpassTileSource;
|
||||
|
||||
/**
|
||||
* Use Overpass API data for vector layer.
|
||||
* Only for developing as can be error-prone.
|
||||
* Take care of overpass provider licenses.
|
||||
*/
|
||||
public class OverpassTest extends GdxMapApp {
|
||||
|
||||
@Override
|
||||
public void createLayers() {
|
||||
Map map = getMap();
|
||||
|
||||
TileSource tileSource = OverpassTileSource.builder()
|
||||
.httpFactory(new OkHttpEngine.OkHttpFactory())
|
||||
.zoomMin(15)
|
||||
.zoomMax(17)
|
||||
.build();
|
||||
VectorTileLayer l = map.setBaseMap(tileSource);
|
||||
|
||||
TileSource bitmapTileSource = DefaultSources.OPENSTREETMAP
|
||||
.httpFactory(new OkHttpEngine.OkHttpFactory())
|
||||
.zoomMax(15)
|
||||
.fadeSteps(new BitmapTileLayer.FadeStep[]{
|
||||
new BitmapTileLayer.FadeStep(15, 16, 1f, 0f),
|
||||
new BitmapTileLayer.FadeStep(16, Viewport.MAX_ZOOM_LEVEL, 0f, 0f)
|
||||
})
|
||||
.build();
|
||||
mMap.layers().add(new BitmapTileLayer(mMap, bitmapTileSource));
|
||||
|
||||
BuildingLayer.RAW_DATA = true;
|
||||
GroupLayer groupLayer = new GroupLayer(mMap);
|
||||
groupLayer.layers.add(new S3DBLayer(map, l));
|
||||
groupLayer.layers.add(new LabelLayer(map, l));
|
||||
map.layers().add(groupLayer);
|
||||
|
||||
map.setTheme(VtmThemes.DEFAULT);
|
||||
MapPosition pos = MapPreferences.getMapPosition();
|
||||
if (pos != null)
|
||||
map.setMapPosition(pos);
|
||||
else
|
||||
map.setMapPosition(53.075, 8.808, 1 << 17);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
MapPreferences.saveMapPosition(mMap.getMapPosition());
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
GdxMapApp.init();
|
||||
GdxMapApp.run(new OverpassTest());
|
||||
}
|
||||
}
|
@ -35,6 +35,7 @@ import org.oscim.renderer.bucket.RenderBuckets;
|
||||
import org.oscim.theme.IRenderTheme;
|
||||
import org.oscim.theme.styles.ExtrusionStyle;
|
||||
import org.oscim.theme.styles.RenderStyle;
|
||||
import org.oscim.utils.geom.GeometryUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -53,6 +54,11 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook, ZoomLim
|
||||
*/
|
||||
public static boolean POST_AA = false;
|
||||
|
||||
/**
|
||||
* Use real time calculations to pre-process data.
|
||||
*/
|
||||
public static boolean RAW_DATA = false;
|
||||
|
||||
/**
|
||||
* Let vanish extrusions / meshes which are covered by others.
|
||||
* {@link org.oscim.renderer.bucket.RenderBucket#EXTRUSION}: roofs are always translucent.
|
||||
@ -147,6 +153,10 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook, ZoomLim
|
||||
mBuildings.put(tile.hashCode(), buildingElements);
|
||||
}
|
||||
element = new MapElement(element); // Deep copy, because element will be cleared
|
||||
if (RAW_DATA && element.isClockwise() > 0) {
|
||||
// Buildings must be counter clockwise in VTM (mirrored to OSM)
|
||||
element.reverse();
|
||||
}
|
||||
buildingElements.add(new BuildingElement(element, extrusion));
|
||||
return true;
|
||||
}
|
||||
@ -216,8 +226,13 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook, ZoomLim
|
||||
|
||||
// Search buildings which inherit parts
|
||||
for (BuildingElement rootBuilding : tileBuildings) {
|
||||
if (rootBuilding.element.isBuildingPart()
|
||||
|| !(refId.equals(getValue(rootBuilding.element, Tag.KEY_ID))))
|
||||
if (rootBuilding.element.isBuildingPart())
|
||||
continue;
|
||||
if (RAW_DATA) {
|
||||
float[] center = GeometryUtils.center(partBuilding.element.points, 0, partBuilding.element.pointNextPos, null);
|
||||
if (!GeometryUtils.pointInPoly(center[0], center[1], rootBuilding.element.points, rootBuilding.element.index[0], 0))
|
||||
continue;
|
||||
} else if (!(refId.equals(getValue(rootBuilding.element, Tag.KEY_ID))))
|
||||
continue;
|
||||
|
||||
rootBuildings.add(rootBuilding);
|
||||
|
@ -27,6 +27,7 @@ import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.theme.styles.ExtrusionStyle;
|
||||
import org.oscim.utils.ExtrusionUtils;
|
||||
import org.oscim.utils.geom.GeometryUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -191,15 +192,20 @@ public class S3DBLayer extends BuildingLayer {
|
||||
continue;
|
||||
|
||||
String refId = getValue(partBuilding.element, Tag.KEY_REF);
|
||||
if (refId == null)
|
||||
if (!RAW_DATA && refId == null)
|
||||
continue;
|
||||
|
||||
TagSet partTags = partBuilding.element.tags;
|
||||
|
||||
// Search buildings which inherit parts
|
||||
for (BuildingElement rootBuilding : tileBuildings) {
|
||||
if (rootBuilding.element.isBuildingPart()
|
||||
|| !(refId.equals(rootBuilding.element.tags.getValue(Tag.KEY_ID))))
|
||||
if (rootBuilding.element.isBuildingPart())
|
||||
continue;
|
||||
if (RAW_DATA) {
|
||||
float[] center = GeometryUtils.center(partBuilding.element.points, 0, partBuilding.element.pointNextPos, null);
|
||||
if (!GeometryUtils.pointInPoly(center[0], center[1], rootBuilding.element.points, rootBuilding.element.index[0], 0))
|
||||
continue;
|
||||
} else if (!refId.equals(rootBuilding.element.tags.getValue(Tag.KEY_ID)))
|
||||
continue;
|
||||
|
||||
if ((getValue(rootBuilding.element, Tag.KEY_ROOF_SHAPE) != null)
|
||||
|
Loading…
x
Reference in New Issue
Block a user