144 lines
4.5 KiB
Java
144 lines
4.5 KiB
Java
package dk.network42.osmfocus;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Path;
|
|
import android.util.Log;
|
|
|
|
public class OsmRelation extends OsmElement {
|
|
private static final String TAG = "OsmRelation";
|
|
private class RelMember {
|
|
String mRole;
|
|
String mType;
|
|
long mRef;
|
|
OsmElement mElem;
|
|
boolean mRender;
|
|
}
|
|
protected final ArrayList<RelMember> mElems;
|
|
protected Path mPath = new Path();
|
|
boolean mDrawInners = false; // Set if inners have tags different from relation/outer
|
|
OsmElement mVisualDefiningElem; // Normally relation, but may be outer way
|
|
|
|
OsmRelation(final long osmId, final long osmVersion) {
|
|
super(osmId, osmVersion);
|
|
mElems = new ArrayList<RelMember>();
|
|
}
|
|
|
|
boolean hasRole(String role) {
|
|
for (RelMember member: mElems) {
|
|
if (member.mRole.equalsIgnoreCase(role)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
long getRoleRef(String role) {
|
|
for (RelMember member: mElems) {
|
|
if (member.mRole.equalsIgnoreCase(role)) {
|
|
if (member.mElem == null) {
|
|
Log.d(TAG, "Relation w NULL elem, ref="+member.mRef);
|
|
return 0; // FIXME
|
|
}
|
|
return member.mElem.getOsmId();
|
|
}
|
|
}
|
|
return 0; // FIXME
|
|
}
|
|
|
|
void addMember(final String type, final String role, long ref, OsmElement e) {
|
|
RelMember elem = new RelMember();
|
|
elem.mRole = role;
|
|
elem.mType = type;
|
|
elem.mElem = e;
|
|
elem.mRef = ref;
|
|
elem.mRender = false;
|
|
mElems.add(elem);
|
|
}
|
|
|
|
/* Detect which object define how the relation should be rendered.
|
|
* In principle tags should be on relations, but sometimes they are
|
|
* on the outer element(s) */
|
|
void updateVisualDefiningElem() {
|
|
if (!hasTag("type", "multipolygon")) {
|
|
Log.d(TAG, "Relation "+mOsmId+" is not a multipolygon");
|
|
return;
|
|
}
|
|
mVisualDefiningElem = this;
|
|
for (RelMember member: mElems) {
|
|
if (member.mRole.equalsIgnoreCase("outer") &&
|
|
member.mElem != null &&
|
|
member.mElem.getTagCnt() > 0 &&
|
|
getTagCnt() == 1) {
|
|
// If relation only has one tag ('type') and we have an outer
|
|
// with tags, use the outer for defining the visuals
|
|
mVisualDefiningElem = member.mElem;
|
|
}
|
|
}
|
|
for (RelMember member: mElems) {
|
|
// If we have an inner that differs from the element defining
|
|
// the visuals of the relation, then we render it
|
|
if (member.mRole.equalsIgnoreCase("inner") &&
|
|
member.mElem != null &&
|
|
member.mElem.getTagCnt()>0 &&
|
|
!mVisualDefiningElem.tagsIdentical(member.mElem)) {
|
|
mDrawInners = true;
|
|
member.mRender = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void updateVisuals(OsmDB db) {
|
|
if (!hasTag("type", "multipolygon")) {
|
|
Log.d(TAG, "Relation "+mOsmId+" is not a multipolygon");
|
|
return;
|
|
}
|
|
super.updateVisuals(db);
|
|
mPath.rewind();
|
|
mPath.setFillType(Path.FillType.EVEN_ODD);
|
|
for (RelMember member: mElems) {
|
|
OsmWay way = (OsmWay) member.mElem;
|
|
if (way != null) {
|
|
if (this.mOsmId==446026) { Log.d(TAG, "Add Path "+way.mOsmId); }
|
|
mPath.addPath(way.mPath); // FIXME: Polygons may be build from several ways
|
|
} else {
|
|
Log.d(TAG, "Relation w id="+mOsmId+" is missing way with id="+member.mRef+" for role="+member.mRole);
|
|
}
|
|
}
|
|
updateVisualDefiningElem();
|
|
}
|
|
|
|
public void draw(Canvas canvas, OsmDB db, PaintConfig pcfg) {
|
|
//Log.d(TAG, "draw Relation: id="+mOsmId);
|
|
if (!pcfg.wireframe) {
|
|
pcfg.getWayPaints(this, mVisualDefiningElem);
|
|
if (pcfg.look != null) {
|
|
canvas.drawPath(mPath, pcfg.look);
|
|
}
|
|
if (pcfg.look2 != null) {
|
|
canvas.drawPath(mPath, pcfg.look2);
|
|
}
|
|
// if (pcfg.nodelook != null) {
|
|
// for (int ii = 0, size = mNodes.size(); ii<size; ii++)
|
|
// canvas.drawPoint(mNodes.get(ii).getX(db), mNodes.get(ii).getY(db), pcfg.nodelook);
|
|
// }
|
|
// if (mDrawInners) {
|
|
// for (RelMember member: mElems) {
|
|
// if (member.mRender) {
|
|
// member.mElem.draw(canvas, db, pcfg);
|
|
// }
|
|
// }
|
|
// }
|
|
} else { // Wireframe
|
|
if (pcfg.getLayer()==1) {
|
|
canvas.drawPath(mPath, pcfg.paint);
|
|
}
|
|
}
|
|
}
|
|
|
|
// FIXME
|
|
public double distTo(double lon, double lat_merc) { return Double.POSITIVE_INFINITY; }
|
|
public double angleTo(double lon, double lat_merc) { return 0; }
|
|
}
|