From b063b65583336f523fec1bc742524098f1799724 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Mon, 16 Sep 2013 22:21:11 +0200 Subject: [PATCH] Create osmand-regions --- .../net/osmand/binary/BinaryInspector.java | 7 +- OsmAnd-java/src/net/osmand/data/QuadTree.java | 3 +- .../src/net/osmand/map/OsmandRegions.java | 171 ++++++++++++++++++ 3 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 OsmAnd-java/src/net/osmand/map/OsmandRegions.java diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java b/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java index 1b1e41a872..7f135747c9 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java @@ -49,9 +49,10 @@ public class BinaryInspector { public static void main(String[] args) throws IOException { inspector(args); // test cases show info - -// inspector(new String[]{"-vaddress", "-vcities", "-vstreets", "-bbox=14.4,50.1,14.5,50.01", "/home/victor/projects/osmand/osm-gen/Monaco.obf"}); - // test case extract parts + +// inspector(new String[]{"/home/victor/projects/osmand/osm-gen/World_basemap_2.obf"}); + inspector(new String[]{"-vmap", "-vmapobjects", /*"-vstreets", "-bbox=14.4,50.1,14.5,50.01", */"/home/victor/projects/osmand/osm-gen/Osmand_regions.obf"}); +// test case extract parts // test case } diff --git a/OsmAnd-java/src/net/osmand/data/QuadTree.java b/OsmAnd-java/src/net/osmand/data/QuadTree.java index 5c8b8635fc..92c726556a 100644 --- a/OsmAnd-java/src/net/osmand/data/QuadTree.java +++ b/OsmAnd-java/src/net/osmand/data/QuadTree.java @@ -39,9 +39,10 @@ public class QuadTree { insert(data, new QuadRect(x, y, x, y)); } - public void queryInBox(QuadRect box, List result) { + public List queryInBox(QuadRect box, List result) { result.clear(); queryNode(box, result, root); + return result; } private void queryNode(QuadRect box, List result, Node node) { diff --git a/OsmAnd-java/src/net/osmand/map/OsmandRegions.java b/OsmAnd-java/src/net/osmand/map/OsmandRegions.java new file mode 100644 index 0000000000..905e5a8799 --- /dev/null +++ b/OsmAnd-java/src/net/osmand/map/OsmandRegions.java @@ -0,0 +1,171 @@ +package net.osmand.map; + + +import gnu.trove.list.array.TIntArrayList; +import net.osmand.ResultMatcher; +import net.osmand.binary.BinaryMapDataObject; +import net.osmand.binary.BinaryMapIndexReader; +import net.osmand.data.QuadRect; +import net.osmand.data.QuadTree; +import net.osmand.util.MapAlgorithms; +import net.osmand.util.MapUtils; + +import java.io.*; +import java.util.*; + +public class OsmandRegions { + + Map> countries = new HashMap>(); + QuadTree quadTree = new QuadTree(new QuadRect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE), + 8, 0.55f); + Integer downloadNameType = null; + Integer prefixType = null; + Integer suffixType = null; + + public OsmandRegions() { + } + + + Integer getDownloadNameType(){ + return downloadNameType; + } + + Integer getPrefixType() { + return prefixType; + } + + Integer getSuffixType() { + return suffixType; + } + + + + public boolean contain(BinaryMapDataObject bo, int tx, int ty) { + int t = 0; + for (int i = 1; i < bo.getPointsLength(); i++) { + int fx = MapAlgorithms.ray_intersect_x(bo.getPoint31XTile(i - 1), + bo.getPoint31YTile(i - 1), + bo.getPoint31XTile(i), + bo.getPoint31YTile(i), ty); + if (Integer.MIN_VALUE != fx && tx >= fx) { + t++; + } + } + return t % 2 == 1; + } + + public List getCountries(int tile31x, int tile31y) { + HashSet set = new HashSet(quadTree.queryInBox(new QuadRect(tile31x, tile31y, tile31x, tile31y), + new ArrayList())); + List result = new ArrayList(); + Iterator it = set.iterator(); + + while (it.hasNext()) { + String cname = it.next(); + BinaryMapDataObject container = null; + int count = 0; + for (BinaryMapDataObject bo : countries.get(cname)) { + if (contain(bo, tile31x, tile31y)) { + count++; + container = bo; + break; + } + } + if (count % 2 == 1) { + result.add(container); + } + } + return result; + } + + + private void init(String fileName) throws IOException { + + BinaryMapIndexReader reader = new BinaryMapIndexReader(new RandomAccessFile(fileName, "r")); + BinaryMapIndexReader.SearchRequest sr = BinaryMapIndexReader.buildSearchRequest(0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, + 5, new BinaryMapIndexReader.SearchFilter() { + @Override + public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex index) { + return true; + } + }, new ResultMatcher() { + + + @Override + public boolean publish(BinaryMapDataObject object) { + if (object.getPointsLength() < 1) { + return false; + } + if (downloadNameType == null) { + downloadNameType = object.getMapIndex().getRule("download_name", null); + prefixType = object.getMapIndex().getRule("region_prefix", null); + suffixType = object.getMapIndex().getRule("region_suffix", null); + if (downloadNameType == null) { + throw new IllegalStateException(); + } + } + String nm = object.getNameByType(downloadNameType); + if (!countries.containsKey(nm)) { + LinkedList ls = new LinkedList(); + countries.put(nm, ls); + ls.add(object); + } else { + countries.get(nm).add(object); + } + + int maxx = object.getPoint31XTile(0); + int maxy = object.getPoint31YTile(0); + int minx = maxx; + int miny = maxy; + for (int i = 1; i < object.getPointsLength(); i++) { + int x = object.getPoint31XTile(i); + int y = object.getPoint31YTile(i); + if (y < miny) { + miny = y; + } else if (y > maxy) { + maxy = y; + } + if (x < minx) { + minx = x; + } else if (x > maxx) { + maxx = x; + } + } + quadTree.insert(nm, new QuadRect(minx, miny, maxx, maxy)); + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + } + ); + reader.searchMapIndex(sr); + } + + + private static void testCountry(OsmandRegions or, double lat, double lon, String test) { + List cs = or.getCountries(MapUtils.get31TileNumberX(15.8), MapUtils.get31TileNumberY(23.09)); + if(cs.size() != 1) { + StringBuilder found = new StringBuilder(); + for(BinaryMapDataObject b : cs) { + found.append(b.getName()).append(' '); + } + throw new IllegalStateException(" Expected " + test + " - Lat " + lat + " lon " + lon + ", but found : " + found); + } + String nm = cs.get(0).getName(); + if(!test.equals(nm)) { + throw new IllegalStateException(" Expected " + test + " but was " + nm); + } + } + + + public static void main(String[] args) throws IOException { + OsmandRegions or = new OsmandRegions(); + or.init("/home/victor/projects/osmand/osm-gen/Osmand_regions.obf"); + + testCountry(or, 15.8, 23.09, "chad"); + + } +}