package dk.network42.osmfocus; import java.util.ArrayList; import java.util.Comparator; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.util.Log; abstract public class OsmElement implements Comparable { private static final String TAG = "OsmElement"; protected long mOsmId; protected long mOsmVersion; protected SortedMap tags; protected double mCompare=0; // Cached compare value, only calculate once boolean mFiltered = false; boolean mIsArea = false; OsmDB mDb = null; enum Compare implements Comparator { X_COORD { public int compare(OsmElement e1, OsmElement e2) { if (e1.getX() >= e2.getX()) return 1; else return -1; } }, X_COORD_DESCENDING { public int compare(OsmElement e1, OsmElement e2) { if (e2.getX() >= e1.getX()) return 1; else return -1; } }, Y_COORD { public int compare(OsmElement e1, OsmElement e2) { if (e1.getY() >= e2.getY()) return 1; else return -1; } }, Y_COORD_DESCENDING { public int compare(OsmElement e1, OsmElement e2) { if (e2.getY() >= e1.getY()) return 1; else return -1; } }, } OsmElement(final long id, final long version) { this.mOsmId = id; this.mOsmVersion = version; this.tags = new TreeMap(); } void addOrUpdateTag(final String tag, final String value) { tags.put(tag, value); } public int getTagCnt() { return tags.size(); } public boolean hasTag(final String key, final String value) { String keyValue = tags.get(key); return keyValue != null && keyValue.equals(value); } public String getTagWithKey(final String key) { return tags.get(key); } public boolean hasTagKey(final String key) { return getTagWithKey(key) != null; } public boolean tagsIdentical(OsmElement other) { if (getTagCnt() != other.getTagCnt()) return false; for(Map.Entry entry : tags.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); String othertag = other.getTagWithKey(key); if (othertag == null || value.equalsIgnoreCase(othertag)) return false; } return true; } public long getOsmId() { return mOsmId; } public String toString() { return "OsmId="+mOsmId; } void updateVisuals(OsmDB db) { /* See also notes on http://wiki.openstreetmap.org/wiki/The_Future_of_Areas */ mIsArea = hasTag("area", "yes") || hasTagKey("landuse") || hasTagKey("building") || hasTagKey("natural"); } public boolean tagIsFiltered(String key, String value) { //return false; return key.startsWith("kms:") || key.startsWith("osak:") || key.equals("created_by") || key.equals("addr:country") || key.equals("addr:postcode") || key.equals("source"); } // Number of lines a given text needs given a maximum width protected int getTagTextLines(String text, Paint paint, float maxw, float indentw) { float w = paint.measureText(text); if (w<= maxw) return 1; return 1 + (int)((w-maxw)/(maxw-indentw)); // FIXME: Approximation, needs char algo } protected float formatWrappedText(ArrayList lines, String text, Paint paint, float maxw) { float w = paint.measureText(text); if (w <= maxw) { lines.add(text); return w; } while (!text.isEmpty()) { int ch = paint.breakText(text, true, maxw, null); lines.add(text.substring(0, ch)); text = text.substring(ch); if (!text.isEmpty()) text = "\u21AA "+text; } return maxw; } // Special headlines where two tags are combined, currently only highwayType : NameValue protected int headLines() { int lines = 0; if (hasTagKey("highway") && hasTagKey("name")) lines += 1; //if (hasTagKey("amenity") && hasTagKey("name")) // lines += 1; return lines; } protected float formatWrappedText(ArrayList lines, Paint paint, float maxw) { String head = null; float w = 0.0f; // Compact headlines like "ValueOfHighway : ValueOfName" if (hasTagKey("highway") && hasTagKey("name")) { head = getTagWithKey("highway") + " : '" + getTagWithKey("name") + "'"; w = formatWrappedText(lines, head, paint, maxw); } // if (hasTagKey("amenity") && hasTagKey("name")) { // head = getTagWithKey("amenity") + " : '" + getTagWithKey("name") + "'"; // float tmp = formatWrappedText(lines, head, paint, maxw); // if (w entry : tags.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); if (head != null && (key.equalsIgnoreCase("highway") || key.equalsIgnoreCase("name"))) continue; if (!tagIsFiltered(key, value)) { String txt = key+" = "+value; float tmp = formatWrappedText(lines, txt, paint, maxw); if (w lines, int idx, Paint paint, float maxw) { //final String sym = "\u21a9"; // bend arrow final String sym = " \u21df"; final String spc = " "; String txt = lines.get(idx); float txtw = paint.measureText(txt); float symw = paint.measureText(sym); float spcw = paint.measureText(spc); if (txtw+symw < maxw) { int spcs = (int)((maxw-(txtw+symw))/spcw); for (int ii=0; ii list = new ArrayList(); final int inset = 3; // inset relative to viewbox final int xborder = 4; int yborder = 4; // margin between text and surrounding box float x,y, w; int lines; float round = 1.0f; float lspace = pcfg.tag.getTextSize()+1; float maxx = viewrect.width() * 0.49f; float maxy = viewrect.height() * 0.49f; float maxw = maxx-2*xborder-inset; int maxl = (int)(maxy/lspace); w = formatWrappedText(list, pcfg.tag, maxw); lines = list.size(); if (lines>maxl) { lines=maxl; clipLine(list, maxl-1, pcfg.tag, maxw); } if (xalign == Paint.Align.LEFT) { // x,y is upper left corner of box x = viewrect.left+inset; } else if (xalign == Paint.Align.RIGHT) { x = viewrect.right-w-2*xborder-inset; } else { x = (viewrect.right-viewrect.left)/2-w/2-inset; } if (yalign == Paint.Align.LEFT) { y = viewrect.top+inset; } else if (yalign == Paint.Align.RIGHT) { y = viewrect.bottom-(2*yborder+lines*lspace)-inset; } else { y = (viewrect.bottom-viewrect.top)/2-(lines*lspace)/2-inset; } // Draw box RectF rrect = new RectF(x,y,x+w+2*xborder,y+2*yborder+lines*lspace); if (headLines() > 0) { drawFancyFrame(canvas, pcfg.tagback, pcfg.tagback3, rrect, lines-1, lspace); } else { canvas.drawRoundRect(rrect, 2*round, 2*round, pcfg.tagback3); } canvas.drawRoundRect(rrect, 2*round, 2*round, pcfg.focus2[style]); // Draw text for (int ii=0; ii= e.mCompare) { return 1; } else { return -1; } } public void compareSetDistTo(double lon, double lat_merc) { mCompare = distTo(lon, lat_merc); } public void compareSetAngleTo(double lon, double lat_merc, double offset) { mCompare = angleTo(lon, lat_merc)+offset; } public double compareGet() { return mCompare; } }