2013-09-16 22:21:11 +02:00
|
|
|
package net.osmand.map;
|
|
|
|
|
|
|
|
|
2014-04-14 02:08:48 +02:00
|
|
|
import gnu.trove.iterator.TIntObjectIterator;
|
2013-09-16 22:21:11 +02:00
|
|
|
import gnu.trove.list.array.TIntArrayList;
|
2014-04-14 02:08:48 +02:00
|
|
|
|
2015-08-01 20:52:21 +02:00
|
|
|
import java.io.File;
|
2014-04-14 02:08:48 +02:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.RandomAccessFile;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Iterator;
|
2014-12-06 13:17:54 +01:00
|
|
|
import java.util.LinkedHashMap;
|
2014-04-14 02:08:48 +02:00
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.TreeSet;
|
|
|
|
|
2013-09-16 22:21:11 +02:00
|
|
|
import net.osmand.ResultMatcher;
|
|
|
|
import net.osmand.binary.BinaryMapDataObject;
|
|
|
|
import net.osmand.binary.BinaryMapIndexReader;
|
2014-04-14 02:08:48 +02:00
|
|
|
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
|
|
|
|
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
2013-09-16 22:21:11 +02:00
|
|
|
import net.osmand.data.QuadRect;
|
|
|
|
import net.osmand.data.QuadTree;
|
2015-06-04 10:04:35 +02:00
|
|
|
import net.osmand.util.Algorithms;
|
2013-09-16 22:21:11 +02:00
|
|
|
import net.osmand.util.MapAlgorithms;
|
|
|
|
import net.osmand.util.MapUtils;
|
|
|
|
|
|
|
|
public class OsmandRegions {
|
|
|
|
|
2015-06-06 01:57:56 +02:00
|
|
|
private static final String MAP_TYPE = "region_map";
|
|
|
|
// regionSrtm = object.getMapIndex().getRule("region_srtm", null);
|
|
|
|
// regionWiki = object.getMapIndex().getRule("region_wiki", null);
|
|
|
|
// regionRoads = object.getMapIndex().getRule("region_roads", null);
|
|
|
|
// regionHillshade = object.getMapIndex().getRule("region_hillshade", null);
|
|
|
|
|
2013-09-24 18:53:48 +02:00
|
|
|
private BinaryMapIndexReader reader;
|
2014-04-14 02:08:48 +02:00
|
|
|
Map<String, LinkedList<BinaryMapDataObject>> countriesByDownloadName = new HashMap<String, LinkedList<BinaryMapDataObject>>();
|
2015-06-05 09:36:37 +02:00
|
|
|
Map<String, String> fullNamesToLocaleNames = new HashMap<String, String>();
|
2015-06-06 01:57:56 +02:00
|
|
|
Map<String, String> fullMapNamesToDownloadNames = new HashMap<String, String>();
|
2015-06-05 09:36:37 +02:00
|
|
|
Map<String, String> downloadNamesToFullNames = new HashMap<String, String>();
|
|
|
|
Map<String, String> fullNamesToLowercaseIndex = new HashMap<String, String>();
|
2013-09-24 18:53:48 +02:00
|
|
|
QuadTree<String> quadTree = null ;
|
|
|
|
|
|
|
|
|
2015-06-04 10:04:35 +02:00
|
|
|
Integer parentFullName = null;
|
|
|
|
Integer fullNameType = null;
|
2014-04-14 02:08:48 +02:00
|
|
|
Integer downloadNameType = null;
|
|
|
|
Integer nameEnType = null;
|
|
|
|
Integer nameType = null;
|
|
|
|
Integer nameLocaleType = null;
|
|
|
|
String locale = "en";
|
2013-09-24 18:53:48 +02:00
|
|
|
|
2013-09-16 22:21:11 +02:00
|
|
|
|
2013-09-24 18:53:48 +02:00
|
|
|
public void prepareFile(String fileName) throws IOException {
|
2015-08-01 20:52:21 +02:00
|
|
|
reader = new BinaryMapIndexReader(new RandomAccessFile(fileName, "r"), new File(fileName));
|
2014-04-14 02:08:48 +02:00
|
|
|
initLocaleNames();
|
2013-09-16 22:21:11 +02:00
|
|
|
}
|
|
|
|
|
2013-09-25 11:09:31 +02:00
|
|
|
public boolean containsCountry(String name){
|
2014-04-14 02:08:48 +02:00
|
|
|
return countriesByDownloadName.containsKey(name);
|
2013-09-25 11:09:31 +02:00
|
|
|
}
|
|
|
|
|
2013-09-24 18:53:48 +02:00
|
|
|
public String getDownloadName(BinaryMapDataObject o) {
|
|
|
|
if(downloadNameType == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return o.getNameByType(downloadNameType);
|
|
|
|
}
|
2014-04-14 02:08:48 +02:00
|
|
|
|
2014-12-09 20:20:21 +01:00
|
|
|
public Integer getNameEnType() {
|
|
|
|
return nameEnType;
|
|
|
|
}
|
|
|
|
|
2014-04-14 02:08:48 +02:00
|
|
|
public String getLocaleName(String downloadName) {
|
|
|
|
final String lc = downloadName.toLowerCase();
|
2015-06-05 09:36:37 +02:00
|
|
|
if (downloadNamesToFullNames.containsKey(lc)) {
|
|
|
|
String fullName = downloadNamesToFullNames.get(lc);
|
|
|
|
if (fullNamesToLocaleNames.containsKey(fullName)) {
|
|
|
|
return fullNamesToLocaleNames.get(fullName);
|
|
|
|
}
|
2014-04-14 02:08:48 +02:00
|
|
|
}
|
|
|
|
return downloadName.replace('_', ' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getDownloadNameIndexLowercase(String downloadName) {
|
2014-05-27 01:36:58 +02:00
|
|
|
if(downloadName == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2014-04-14 02:08:48 +02:00
|
|
|
final String lc = downloadName.toLowerCase();
|
2015-06-05 09:36:37 +02:00
|
|
|
if (downloadNamesToFullNames.containsKey(lc)) {
|
|
|
|
String fullName = downloadNamesToFullNames.get(lc);
|
|
|
|
if (fullNamesToLowercaseIndex.containsKey(fullName)) {
|
|
|
|
return fullNamesToLowercaseIndex.get(fullName);
|
|
|
|
}
|
2014-04-14 02:08:48 +02:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getLocaleName(BinaryMapDataObject object) {
|
|
|
|
String locName = "";
|
|
|
|
if(locName == null || locName.length() == 0){
|
|
|
|
if(nameLocaleType != null) {
|
|
|
|
locName = object.getNameByType(nameLocaleType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(locName == null || locName.length() == 0){
|
|
|
|
if(nameEnType != null) {
|
|
|
|
locName = object.getNameByType(nameEnType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(locName == null || locName.length() == 0){
|
|
|
|
if(nameType != null) {
|
|
|
|
locName = object.getNameByType(nameType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return locName;
|
|
|
|
}
|
2013-09-16 22:21:11 +02:00
|
|
|
|
2015-06-04 10:04:35 +02:00
|
|
|
public String getParentFullName(BinaryMapDataObject o) {
|
|
|
|
if(parentFullName == null) {
|
2013-09-24 18:53:48 +02:00
|
|
|
return null;
|
|
|
|
}
|
2015-06-04 10:04:35 +02:00
|
|
|
return o.getNameByType(parentFullName);
|
2013-09-16 22:21:11 +02:00
|
|
|
}
|
|
|
|
|
2014-12-06 13:17:54 +01:00
|
|
|
|
2015-06-04 10:04:35 +02:00
|
|
|
|
|
|
|
public String getFullName(BinaryMapDataObject o) {
|
|
|
|
if(fullNameType == null) {
|
2014-12-06 13:17:54 +01:00
|
|
|
return null;
|
|
|
|
}
|
2015-06-04 10:04:35 +02:00
|
|
|
return o.getNameByType(fullNameType);
|
2014-12-06 13:17:54 +01:00
|
|
|
}
|
2013-09-16 22:21:11 +02:00
|
|
|
|
2013-09-24 18:53:48 +02:00
|
|
|
public boolean isInitialized(){
|
|
|
|
return reader != null;
|
2013-09-16 22:21:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2015-07-20 01:17:26 +02:00
|
|
|
|
|
|
|
public boolean intersect(BinaryMapDataObject bo, int lx, int ty, int rx, int by) {
|
|
|
|
int t = 0;
|
|
|
|
// 1. polygon in object
|
|
|
|
if(contain(bo, lx, ty)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// 2. object in polygon
|
|
|
|
if(bo.getPointsLength() == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(bo.getPoint31XTile(0) >= lx && bo.getPoint31XTile(0) <= rx &&
|
|
|
|
bo.getPoint31YTile(0) >= ty && bo.getPoint31YTile(0) <= by ){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3. find intersection
|
|
|
|
for (int i = 1; i < bo.getPointsLength(); i++) {
|
|
|
|
int px = bo.getPoint31XTile(i - 1);
|
|
|
|
int x = bo.getPoint31XTile(i);
|
|
|
|
int py = bo.getPoint31YTile(i - 1);
|
|
|
|
int y = bo.getPoint31YTile(i);
|
|
|
|
if(x < lx && px < lx) {
|
|
|
|
continue;
|
|
|
|
} else if(x > rx && px > rx) {
|
|
|
|
continue;
|
|
|
|
} else if(y > by && py > by) {
|
|
|
|
continue;
|
|
|
|
} else if(y < ty && py < ty) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
long in = MapAlgorithms.calculateIntersection(px, py, x, y, lx, rx, by, ty);
|
|
|
|
if(in != -1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-16 22:21:11 +02:00
|
|
|
|
2013-09-24 18:53:48 +02:00
|
|
|
private List<BinaryMapDataObject> getCountries(int tile31x, int tile31y) {
|
2013-09-16 22:21:11 +02:00
|
|
|
HashSet<String> set = new HashSet<String>(quadTree.queryInBox(new QuadRect(tile31x, tile31y, tile31x, tile31y),
|
|
|
|
new ArrayList<String>()));
|
|
|
|
List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>();
|
|
|
|
Iterator<String> it = set.iterator();
|
|
|
|
|
|
|
|
while (it.hasNext()) {
|
|
|
|
String cname = it.next();
|
|
|
|
BinaryMapDataObject container = null;
|
|
|
|
int count = 0;
|
2014-04-14 02:08:48 +02:00
|
|
|
for (BinaryMapDataObject bo : countriesByDownloadName.get(cname)) {
|
2013-09-16 22:21:11 +02:00
|
|
|
if (contain(bo, tile31x, tile31y)) {
|
|
|
|
count++;
|
|
|
|
container = bo;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (count % 2 == 1) {
|
|
|
|
result.add(container);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-24 18:53:48 +02:00
|
|
|
public List<BinaryMapDataObject> query(final int tile31x, final int tile31y) throws IOException {
|
|
|
|
if(quadTree != null) {
|
|
|
|
return getCountries(tile31x, tile31y);
|
|
|
|
}
|
|
|
|
return queryNoInit(tile31x, tile31y);
|
|
|
|
}
|
|
|
|
|
2015-03-18 01:12:02 +01:00
|
|
|
private synchronized List<BinaryMapDataObject> queryNoInit(final int tile31x, final int tile31y) throws IOException {
|
2013-09-17 01:53:24 +02:00
|
|
|
final List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>();
|
|
|
|
BinaryMapIndexReader.SearchRequest<BinaryMapDataObject> sr = BinaryMapIndexReader.buildSearchRequest(tile31x, tile31x, tile31y, tile31y,
|
|
|
|
5, new BinaryMapIndexReader.SearchFilter() {
|
|
|
|
@Override
|
|
|
|
public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex index) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}, new ResultMatcher<BinaryMapDataObject>() {
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean publish(BinaryMapDataObject object) {
|
|
|
|
if (object.getPointsLength() < 1) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-24 18:53:48 +02:00
|
|
|
initTypes(object);
|
2013-09-17 01:53:24 +02:00
|
|
|
if (contain(object, tile31x, tile31y)) {
|
|
|
|
result.add(object);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isCancelled() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2013-10-27 00:37:32 +02:00
|
|
|
if(reader != null) {
|
|
|
|
reader.searchMapIndex(sr);
|
|
|
|
}
|
2013-09-17 01:53:24 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-18 01:12:02 +01:00
|
|
|
public synchronized List<BinaryMapDataObject> queryBbox(int lx, int rx, int ty, int by) throws IOException {
|
2013-09-24 18:53:48 +02:00
|
|
|
final List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>();
|
|
|
|
BinaryMapIndexReader.SearchRequest<BinaryMapDataObject> sr = BinaryMapIndexReader.buildSearchRequest(lx, rx, ty, by,
|
|
|
|
5, new BinaryMapIndexReader.SearchFilter() {
|
|
|
|
@Override
|
|
|
|
public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex index) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}, new ResultMatcher<BinaryMapDataObject>() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean publish(BinaryMapDataObject object) {
|
|
|
|
if (object.getPointsLength() < 1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
initTypes(object);
|
|
|
|
result.add(object);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isCancelled() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2015-07-19 11:44:16 +02:00
|
|
|
sr.log = false;
|
2013-10-27 00:37:32 +02:00
|
|
|
if(reader != null) {
|
|
|
|
reader.searchMapIndex(sr);
|
|
|
|
}
|
2013-09-24 18:53:48 +02:00
|
|
|
return result;
|
|
|
|
}
|
2014-04-14 02:08:48 +02:00
|
|
|
|
|
|
|
public void setLocale(String locale) {
|
|
|
|
this.locale = locale;
|
|
|
|
}
|
|
|
|
|
2015-06-06 01:57:56 +02:00
|
|
|
public String getMapDownloadType(String fullname) {
|
|
|
|
return fullMapNamesToDownloadNames.get(fullname);
|
|
|
|
}
|
|
|
|
|
2014-04-14 02:08:48 +02:00
|
|
|
public void initLocaleNames() throws IOException {
|
|
|
|
// final Collator clt = OsmAndCollator.primaryCollator();
|
2015-06-04 10:04:35 +02:00
|
|
|
final Map<String, String> parentRelations = new LinkedHashMap<String, String>();
|
2014-04-14 02:08:48 +02:00
|
|
|
final ResultMatcher<BinaryMapDataObject> resultMatcher = new ResultMatcher<BinaryMapDataObject>() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean publish(BinaryMapDataObject object) {
|
|
|
|
initTypes(object);
|
2015-06-06 01:57:56 +02:00
|
|
|
int[] types = object.getTypes();
|
|
|
|
for(int i = 0; i < types.length; i++ ) {
|
|
|
|
TagValuePair tp = object.getMapIndex().decodeType(types[i]);
|
|
|
|
if("boundary".equals(tp.value)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2015-06-04 10:04:35 +02:00
|
|
|
String parentFullName = getParentFullName(object);
|
|
|
|
String fullName = getFullName(object);
|
|
|
|
if(!Algorithms.isEmpty(parentFullName)) {
|
|
|
|
parentRelations.put(fullName, parentFullName);
|
2015-06-05 09:36:37 +02:00
|
|
|
}
|
2014-04-14 02:08:48 +02:00
|
|
|
String locName = getLocaleName(object);
|
2015-06-05 09:36:37 +02:00
|
|
|
if(!Algorithms.isEmpty(locName)){
|
|
|
|
fullNamesToLocaleNames.put(fullName, locName);
|
2014-04-14 02:08:48 +02:00
|
|
|
}
|
|
|
|
MapIndex mi = object.getMapIndex();
|
|
|
|
TIntObjectIterator<String> it = object.getObjectNames().iterator();
|
|
|
|
StringBuilder ind = new StringBuilder();
|
|
|
|
while(it.hasNext()) {
|
|
|
|
it.advance();
|
|
|
|
TagValuePair tp = mi.decodeType(it.key());
|
2015-06-05 09:36:37 +02:00
|
|
|
if (tp.tag.equals("key_name") && Algorithms.isEmpty(locName)) {
|
|
|
|
fullNamesToLocaleNames.put(fullName,
|
|
|
|
Algorithms.capitalizeFirstLetterAndLowercase(it.value().replace('_', '-')));
|
|
|
|
}
|
2015-05-30 14:14:15 +02:00
|
|
|
if(tp.tag.startsWith("name") || tp.tag.equals("key_name")) {
|
2014-04-14 02:08:48 +02:00
|
|
|
final String vl = it.value().toLowerCase();
|
|
|
|
// if (!CollatorStringMatcher.ccontains(clt, ind.toString(), vl)) {
|
|
|
|
if(ind.indexOf(vl) == -1) {
|
|
|
|
ind.append(" ").append(vl);
|
|
|
|
}
|
2015-06-05 09:36:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
fullNamesToLowercaseIndex.put(fullName, ind.toString());
|
|
|
|
String downloadName = getDownloadName(object);
|
|
|
|
if(downloadName != null) {
|
|
|
|
downloadNamesToFullNames.put(downloadName, fullName);
|
2015-06-06 01:57:56 +02:00
|
|
|
if(isDownloadOfType(object, MAP_TYPE)) {
|
|
|
|
fullMapNamesToDownloadNames.put(fullName, downloadName);
|
|
|
|
}
|
2014-04-14 02:08:48 +02:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-06-06 01:57:56 +02:00
|
|
|
|
2014-04-14 02:08:48 +02:00
|
|
|
@Override
|
|
|
|
public boolean isCancelled() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
iterateOverAllObjects(resultMatcher);
|
2014-12-06 13:17:54 +01:00
|
|
|
// post process download names
|
2015-06-05 09:36:37 +02:00
|
|
|
for(Map.Entry<String, String> e : parentRelations.entrySet()) {
|
2015-06-04 10:04:35 +02:00
|
|
|
String fullName = e.getKey();
|
2015-06-05 09:36:37 +02:00
|
|
|
String parentFullName = e.getValue();
|
|
|
|
String parentParentFulName = parentRelations.get(parentFullName);
|
2015-06-04 10:04:35 +02:00
|
|
|
if(!Algorithms.isEmpty(parentFullName) &&
|
2015-06-05 09:36:37 +02:00
|
|
|
!Algorithms.isEmpty(parentParentFulName)) {
|
|
|
|
if(parentParentFulName.contains("russia") || parentParentFulName.contains("japan")) {
|
|
|
|
parentFullName = parentParentFulName;
|
|
|
|
}
|
|
|
|
String locPrefix = fullNamesToLocaleNames.get(parentFullName);
|
|
|
|
String locName = fullNamesToLocaleNames.get(fullName);
|
2015-06-04 10:04:35 +02:00
|
|
|
if(locPrefix == null || locName == null) {
|
2015-06-05 09:36:37 +02:00
|
|
|
throw new IllegalStateException("There is no prefix registered for " + fullName + " (" + parentFullName + ") ");
|
2015-06-04 10:04:35 +02:00
|
|
|
}
|
2015-06-05 09:36:37 +02:00
|
|
|
fullNamesToLocaleNames.put(fullName, locPrefix + " " + locName);
|
|
|
|
String index = fullNamesToLowercaseIndex.get(fullName);
|
|
|
|
String prindex = fullNamesToLowercaseIndex.get(parentFullName);
|
|
|
|
fullNamesToLowercaseIndex.put(fullName, index + " " + prindex);
|
2015-02-16 09:42:49 +01:00
|
|
|
}
|
2014-12-06 13:17:54 +01:00
|
|
|
}
|
|
|
|
|
2014-04-14 02:08:48 +02:00
|
|
|
}
|
2015-06-06 01:57:56 +02:00
|
|
|
|
|
|
|
private boolean isDownloadOfType(BinaryMapDataObject object, String type) {
|
|
|
|
int[] addtypes = object.getAdditionalTypes();
|
|
|
|
for(int i = 0; i < addtypes.length; i++) {
|
|
|
|
TagValuePair tp = object.getMapIndex().decodeType(addtypes[i]);
|
|
|
|
if(type.equals(tp.tag) && "yes".equals(tp.value)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-17 01:53:24 +02:00
|
|
|
|
2013-09-16 22:21:11 +02:00
|
|
|
|
2013-09-24 18:53:48 +02:00
|
|
|
public void cacheAllCountries() throws IOException {
|
|
|
|
quadTree = new QuadTree<String>(new QuadRect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE),
|
|
|
|
8, 0.55f);
|
2014-04-14 02:08:48 +02:00
|
|
|
final ResultMatcher<BinaryMapDataObject> resultMatcher = new ResultMatcher<BinaryMapDataObject>() {
|
2015-07-17 09:15:17 +02:00
|
|
|
// int c = 0;
|
2014-04-14 02:08:48 +02:00
|
|
|
@Override
|
|
|
|
public boolean publish(BinaryMapDataObject object) {
|
|
|
|
if (object.getPointsLength() < 1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
initTypes(object);
|
|
|
|
String nm = object.getNameByType(downloadNameType);
|
2015-07-17 09:15:17 +02:00
|
|
|
// if(nm != null) {
|
|
|
|
// System.out.println((c++) +" " + nm);
|
|
|
|
// }
|
2014-04-14 02:08:48 +02:00
|
|
|
if (!countriesByDownloadName.containsKey(nm)) {
|
|
|
|
LinkedList<BinaryMapDataObject> ls = new LinkedList<BinaryMapDataObject>();
|
|
|
|
countriesByDownloadName.put(nm, ls);
|
|
|
|
ls.add(object);
|
|
|
|
} else {
|
|
|
|
countriesByDownloadName.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;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
iterateOverAllObjects(resultMatcher);
|
|
|
|
}
|
|
|
|
|
2015-03-18 01:12:02 +01:00
|
|
|
private synchronized void iterateOverAllObjects(final ResultMatcher<BinaryMapDataObject> resultMatcher) throws IOException {
|
2013-09-16 22:21:11 +02:00
|
|
|
BinaryMapIndexReader.SearchRequest<BinaryMapDataObject> 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;
|
|
|
|
}
|
2014-04-14 02:08:48 +02:00
|
|
|
}, resultMatcher);
|
2013-10-27 00:37:32 +02:00
|
|
|
if(reader != null) {
|
|
|
|
reader.searchMapIndex(sr);
|
|
|
|
}
|
2013-09-16 22:21:11 +02:00
|
|
|
}
|
|
|
|
|
2014-04-14 02:08:48 +02:00
|
|
|
|
2013-09-24 18:53:48 +02:00
|
|
|
private void initTypes(BinaryMapDataObject object) {
|
|
|
|
if (downloadNameType == null) {
|
|
|
|
downloadNameType = object.getMapIndex().getRule("download_name", null);
|
2014-04-14 02:08:48 +02:00
|
|
|
nameType = object.getMapIndex().getRule("name", null);
|
|
|
|
nameEnType = object.getMapIndex().getRule("name:en", null);
|
|
|
|
nameLocaleType = object.getMapIndex().getRule("name:" + locale, null);
|
2015-06-04 10:04:35 +02:00
|
|
|
parentFullName = object.getMapIndex().getRule("region_parent_name", null);
|
|
|
|
fullNameType = object.getMapIndex().getRule("region_full_name", null);
|
2015-06-06 01:57:56 +02:00
|
|
|
|
2014-04-14 02:08:48 +02:00
|
|
|
if (downloadNameType == null || nameType == null) {
|
2013-09-24 18:53:48 +02:00
|
|
|
throw new IllegalStateException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-16 22:21:11 +02:00
|
|
|
|
2013-09-17 01:53:24 +02:00
|
|
|
private static void testCountry(OsmandRegions or, double lat, double lon, String... test) throws IOException {
|
2013-09-24 18:53:48 +02:00
|
|
|
long t = System.currentTimeMillis();
|
|
|
|
List<BinaryMapDataObject> cs = or.query(MapUtils.get31TileNumberX(lon), MapUtils.get31TileNumberY(lat));
|
|
|
|
Set<String> expected = new TreeSet<String>(Arrays.asList(test));
|
|
|
|
Set<String> found = new TreeSet<String>();
|
2014-12-09 20:20:21 +01:00
|
|
|
|
|
|
|
for (BinaryMapDataObject b : cs) {
|
|
|
|
String nm = b.getNameByType(or.nameEnType);
|
|
|
|
if(nm == null) {
|
|
|
|
nm = b.getName();
|
2013-09-16 22:21:11 +02:00
|
|
|
}
|
2015-07-09 14:14:52 +02:00
|
|
|
if(or.isDownloadOfType(b, MAP_TYPE)) {
|
|
|
|
found.add(nm.toLowerCase());
|
|
|
|
}
|
2014-12-09 20:20:21 +01:00
|
|
|
}
|
2013-09-17 01:53:24 +02:00
|
|
|
|
2014-12-09 20:20:21 +01:00
|
|
|
if (!found.equals(expected)) {
|
2013-09-24 18:53:48 +02:00
|
|
|
throw new IllegalStateException(" Expected " + expected + " but was " + found);
|
2013-09-16 22:21:11 +02:00
|
|
|
}
|
2013-09-24 18:53:48 +02:00
|
|
|
System.out.println("Found " + expected + " in " + (System.currentTimeMillis() - t) + " ms");
|
2013-09-16 22:21:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) throws IOException {
|
|
|
|
OsmandRegions or = new OsmandRegions();
|
2015-07-09 14:14:52 +02:00
|
|
|
or.prepareFile("/Users/victorshcherb/osmand/repos/resources/countries-info/regions.ocbf");
|
2014-12-09 20:20:21 +01:00
|
|
|
or.cacheAllCountries();
|
2013-09-24 18:53:48 +02:00
|
|
|
// long t = System.currentTimeMillis();
|
|
|
|
// or.cacheAllCountries();
|
|
|
|
// System.out.println("Init " + (System.currentTimeMillis() - t));
|
2013-09-17 01:53:24 +02:00
|
|
|
|
|
|
|
//testCountry(or, 15.8, 23.09, "chad");
|
2015-07-09 14:14:52 +02:00
|
|
|
testCountry(or, 52.10, 4.92, "the netherlands", "utrecht");
|
2014-12-09 20:20:21 +01:00
|
|
|
testCountry(or, 52.15, 7.50, "north rhine-westphalia");
|
2015-07-09 14:14:52 +02:00
|
|
|
testCountry(or, 28.8056, 29.9858, "egypt" );
|
|
|
|
// testCountry(or, 40.0760, 9.2807, "italy", "sardinia");
|
2013-09-17 01:53:24 +02:00
|
|
|
testCountry(or, 35.7521, 139.7887, "japan");
|
|
|
|
testCountry(or, 46.5145, 102.2580, "mongolia");
|
2014-12-09 20:20:21 +01:00
|
|
|
testCountry(or, 62.54, 43.36, "arkhangelsk oblast", "northwestern federal district");
|
2013-09-17 01:53:24 +02:00
|
|
|
|
2013-09-16 22:21:11 +02:00
|
|
|
|
|
|
|
}
|
2015-07-20 01:17:26 +02:00
|
|
|
|
|
|
|
|
2013-09-16 22:21:11 +02:00
|
|
|
}
|