Added search tests
This commit is contained in:
parent
d4d31d0877
commit
113c5fd8e9
19 changed files with 13175 additions and 119 deletions
|
@ -40,9 +40,15 @@ task collectRegionsInfoResources(type: Copy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
task collectTestResources(type: Copy) {
|
task collectTestResources(type: Copy) {
|
||||||
from "../../resources/test-resources"
|
|
||||||
into "src/test/resources/"
|
into "src/test/resources/"
|
||||||
include "*"
|
from("../../resources/test-resources") {
|
||||||
|
include "*"
|
||||||
|
}
|
||||||
|
from("../../resources/poi") {
|
||||||
|
include "poi_types.xml"
|
||||||
|
include "/phrases/en/*"
|
||||||
|
//include "/phrases/ru/*"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,9 @@
|
||||||
package net.osmand.binary;
|
package net.osmand.binary;
|
||||||
|
|
||||||
|
|
||||||
import gnu.trove.list.array.TIntArrayList;
|
import com.google.protobuf.CodedInputStream;
|
||||||
import gnu.trove.map.TIntObjectMap;
|
import com.google.protobuf.CodedOutputStream;
|
||||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
import com.google.protobuf.WireFormat;
|
||||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
|
||||||
import gnu.trove.set.hash.TIntHashSet;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.RandomAccessFile;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
import net.osmand.Collator;
|
import net.osmand.Collator;
|
||||||
import net.osmand.CollatorStringMatcher;
|
import net.osmand.CollatorStringMatcher;
|
||||||
|
@ -72,9 +44,37 @@ import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import com.google.protobuf.CodedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import com.google.protobuf.CodedOutputStream;
|
import java.io.BufferedReader;
|
||||||
import com.google.protobuf.WireFormat;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import gnu.trove.list.array.TIntArrayList;
|
||||||
|
import gnu.trove.map.TIntObjectMap;
|
||||||
|
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||||
|
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||||
|
import gnu.trove.set.hash.TIntHashSet;
|
||||||
|
|
||||||
public class BinaryMapIndexReader {
|
public class BinaryMapIndexReader {
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ public class BinaryMapIndexReader {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private */BinaryMapIndexReader(final RandomAccessFile raf, File file, boolean init) throws IOException {
|
public BinaryMapIndexReader(final RandomAccessFile raf, File file, boolean init) throws IOException {
|
||||||
this.raf = raf;
|
this.raf = raf;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
codedIS = CodedInputStream.newInstance(raf);
|
codedIS = CodedInputStream.newInstance(raf);
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
package net.osmand.data;
|
package net.osmand.data;
|
||||||
|
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
|
import net.osmand.osm.MapPoiTypes;
|
||||||
import net.osmand.osm.PoiCategory;
|
import net.osmand.osm.PoiCategory;
|
||||||
import net.osmand.osm.edit.Node;
|
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -317,4 +320,49 @@ public class Amenity extends MapObject {
|
||||||
public boolean isClosed() {
|
public boolean isClosed() {
|
||||||
return OSM_DELETE_VALUE.equals(getAdditionalInfo(OSM_DELETE_TAG));
|
return OSM_DELETE_VALUE.equals(getAdditionalInfo(OSM_DELETE_TAG));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject toJSON() {
|
||||||
|
JSONObject json = super.toJSON();
|
||||||
|
json.put("subType", subType);
|
||||||
|
json.put("type", type.getKeyName());
|
||||||
|
json.put("openingHours", openingHours);
|
||||||
|
if (additionalInfo != null && additionalInfo.size() > 0) {
|
||||||
|
JSONObject additionalInfoObj = new JSONObject();
|
||||||
|
for (Entry<String, String> e : additionalInfo.entrySet()) {
|
||||||
|
additionalInfoObj.put(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
json.put("additionalInfo", additionalInfoObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Amenity parseJSON(JSONObject json) {
|
||||||
|
Amenity a = new Amenity();
|
||||||
|
MapObject.parseJSON(json, a);
|
||||||
|
|
||||||
|
if (json.has("subType")) {
|
||||||
|
a.subType = json.getString("subType");
|
||||||
|
}
|
||||||
|
if (json.has("type")) {
|
||||||
|
String categoryName = json.getString("type");
|
||||||
|
a.setType(MapPoiTypes.getDefault().getPoiCategoryByName(categoryName));
|
||||||
|
} else {
|
||||||
|
a.setType(MapPoiTypes.getDefault().getOtherPoiCategory());
|
||||||
|
}
|
||||||
|
if (json.has("openingHours")) {
|
||||||
|
a.openingHours = json.getString("openingHours");
|
||||||
|
}
|
||||||
|
if (json.has("additionalInfo")) {
|
||||||
|
JSONObject namesObj = json.getJSONObject("additionalInfo");
|
||||||
|
a.additionalInfo = new HashMap<>();
|
||||||
|
Iterator<String> iterator = namesObj.keys();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
String key = iterator.next();
|
||||||
|
String value = namesObj.getString(key);
|
||||||
|
a.additionalInfo.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package net.osmand.data;
|
package net.osmand.data;
|
||||||
|
|
||||||
|
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.osmand.util.Algorithms;
|
|
||||||
|
|
||||||
public class Building extends MapObject {
|
public class Building extends MapObject {
|
||||||
|
|
||||||
private String postcode;
|
private String postcode;
|
||||||
|
@ -216,4 +219,43 @@ public class Building extends MapObject {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject toJSON() {
|
||||||
|
JSONObject json = super.toJSON();
|
||||||
|
json.put("postcode", postcode);
|
||||||
|
if (latLon2 != null) {
|
||||||
|
json.put("lat2", String.format(Locale.US, "%.5f", latLon2.getLatitude()));
|
||||||
|
json.put("lon2", String.format(Locale.US, "%.5f", latLon2.getLongitude()));
|
||||||
|
}
|
||||||
|
if (interpolationType != null) {
|
||||||
|
json.put("interpolationType", interpolationType.name());
|
||||||
|
}
|
||||||
|
if (interpolationInterval != 0) {
|
||||||
|
json.put("interpolationInterval", interpolationInterval);
|
||||||
|
}
|
||||||
|
json.put("name2", name2);
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Building parseJSON(JSONObject json) throws IllegalArgumentException {
|
||||||
|
Building b = new Building();
|
||||||
|
MapObject.parseJSON(json, b);
|
||||||
|
|
||||||
|
if (json.has("postcode")) {
|
||||||
|
b.postcode = json.getString("postcode");
|
||||||
|
}
|
||||||
|
if (json.has("lat2") && json.has("lon2")) {
|
||||||
|
b.latLon2 = new LatLon(json.getDouble("lat2"), json.getDouble("lon2"));
|
||||||
|
}
|
||||||
|
if (json.has("interpolationType")) {
|
||||||
|
b.interpolationType = BuildingInterpolation.valueOf(json.getString("interpolationType"));
|
||||||
|
}
|
||||||
|
if (json.has("interpolationInterval")) {
|
||||||
|
b.interpolationInterval = json.getInt("interpolationInterval");
|
||||||
|
}
|
||||||
|
if (json.has("name2")) {
|
||||||
|
b.name2 = json.getString("name2");
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package net.osmand.data;
|
package net.osmand.data;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -55,7 +58,6 @@ public class City extends MapObject {
|
||||||
return new City(postcode, POSTCODE_INTERNAL_ID--);
|
return new City(postcode, POSTCODE_INTERNAL_ID--);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public City(CityType type) {
|
public City(CityType type) {
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
@ -156,4 +158,43 @@ public class City extends MapObject {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject toJSON() {
|
||||||
|
JSONObject json = super.toJSON();
|
||||||
|
json.put("type", type.name());
|
||||||
|
json.put("postcode", postcode);
|
||||||
|
JSONArray listOfStreetsArr = new JSONArray();
|
||||||
|
for (Street s : listOfStreets) {
|
||||||
|
listOfStreetsArr.put(s.toJSON());
|
||||||
|
}
|
||||||
|
json.put("listOfStreets", listOfStreetsArr);
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static City parseJSON(JSONObject json) throws IllegalArgumentException {
|
||||||
|
CityType type;
|
||||||
|
if (json.has("type")) {
|
||||||
|
type = CityType.valueOf(json.getString("type"));
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
City c = new City(type);
|
||||||
|
MapObject.parseJSON(json, c);
|
||||||
|
|
||||||
|
if (json.has("postcode")) {
|
||||||
|
c.postcode = json.getString("postcode");
|
||||||
|
}
|
||||||
|
if (json.has("listOfStreets")) {
|
||||||
|
JSONArray streetsArr = json.getJSONArray("listOfStreets");
|
||||||
|
c.listOfStreets = new ArrayList<>();
|
||||||
|
for (int i = 0; i < streetsArr.length(); i++) {
|
||||||
|
JSONObject streetObj = streetsArr.getJSONObject(i);
|
||||||
|
Street street = Street.parseJSON(c, streetObj);
|
||||||
|
if (street != null) {
|
||||||
|
c.listOfStreets.add(street);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
package net.osmand.data;
|
package net.osmand.data;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import net.osmand.Collator;
|
import net.osmand.Collator;
|
||||||
import net.osmand.OsmAndCollator;
|
import net.osmand.OsmAndCollator;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
import net.sf.junidecode.Junidecode;
|
import net.sf.junidecode.Junidecode;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
|
||||||
public abstract class MapObject implements Comparable<MapObject> {
|
public abstract class MapObject implements Comparable<MapObject> {
|
||||||
|
|
||||||
|
@ -289,4 +293,48 @@ public abstract class MapObject implements Comparable<MapObject> {
|
||||||
return referenceFile;
|
return referenceFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject toJSON() {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("name", name);
|
||||||
|
json.put("enName", enName);
|
||||||
|
if (names != null && names.size() > 0) {
|
||||||
|
JSONObject namesObj = new JSONObject();
|
||||||
|
for (Entry<String, String> e : names.entrySet()) {
|
||||||
|
namesObj.put(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
json.put("names", namesObj);
|
||||||
|
}
|
||||||
|
if (location != null) {
|
||||||
|
json.put("lat", String.format(Locale.US, "%.5f", location.getLatitude()));
|
||||||
|
json.put("lon", String.format(Locale.US, "%.5f", location.getLongitude()));
|
||||||
|
}
|
||||||
|
json.put("id", id);
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void parseJSON(JSONObject json, MapObject o) {
|
||||||
|
if (json.has("name")) {
|
||||||
|
o.name = json.getString("name");
|
||||||
|
}
|
||||||
|
if (json.has("enName")) {
|
||||||
|
o.enName = json.getString("enName");
|
||||||
|
}
|
||||||
|
if (json.has("names")) {
|
||||||
|
JSONObject namesObj = json.getJSONObject("names");
|
||||||
|
o.names = new HashMap<>();
|
||||||
|
Iterator<String> iterator = namesObj.keys();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
String key = iterator.next();
|
||||||
|
String value = namesObj.getString(key);
|
||||||
|
o.names.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (json.has("lat") && json.has("lon")) {
|
||||||
|
o.location = new LatLon(json.getDouble("lat"), json.getDouble("lon"));
|
||||||
|
}
|
||||||
|
if (json.has("id")) {
|
||||||
|
o.id = json.getLong("id");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package net.osmand.data;
|
package net.osmand.data;
|
||||||
|
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.osmand.util.Algorithms;
|
|
||||||
|
|
||||||
|
|
||||||
public class Street extends MapObject {
|
public class Street extends MapObject {
|
||||||
|
|
||||||
|
@ -86,4 +89,53 @@ public class Street extends MapObject {
|
||||||
}
|
}
|
||||||
return nm;
|
return nm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject toJSON() {
|
||||||
|
JSONObject json = super.toJSON();
|
||||||
|
if (buildings.size() > 0) {
|
||||||
|
JSONArray buildingsArr = new JSONArray();
|
||||||
|
for (Building b : buildings) {
|
||||||
|
buildingsArr.put(b.toJSON());
|
||||||
|
}
|
||||||
|
json.put("buildings", buildingsArr);
|
||||||
|
}
|
||||||
|
if (intersectedStreets != null) {
|
||||||
|
JSONArray intersectedStreetsArr = new JSONArray();
|
||||||
|
for (Street s : intersectedStreets) {
|
||||||
|
intersectedStreetsArr.put(s.toJSON());
|
||||||
|
}
|
||||||
|
json.put("intersectedStreets", intersectedStreetsArr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Street parseJSON(City city, JSONObject json) throws IllegalArgumentException {
|
||||||
|
Street s = new Street(city);
|
||||||
|
MapObject.parseJSON(json, s);
|
||||||
|
|
||||||
|
if (json.has("buildings")) {
|
||||||
|
JSONArray buildingsArr = json.getJSONArray("buildings");
|
||||||
|
s.buildings = new ArrayList<>();
|
||||||
|
for (int i = 0; i < buildingsArr.length(); i++) {
|
||||||
|
JSONObject buildingObj = buildingsArr.getJSONObject(i);
|
||||||
|
Building building = Building.parseJSON(buildingObj);
|
||||||
|
if (building != null) {
|
||||||
|
s.buildings.add(building);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (json.has("intersectedStreets")) {
|
||||||
|
JSONArray streetsArr = json.getJSONArray("intersectedStreets");
|
||||||
|
s.intersectedStreets = new ArrayList<>();
|
||||||
|
for (int i = 0; i < streetsArr.length(); i++) {
|
||||||
|
JSONObject streetObj = streetsArr.getJSONObject(i);
|
||||||
|
Street street = parseJSON(city, streetObj);
|
||||||
|
if (street != null) {
|
||||||
|
s.intersectedStreets.add(street);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@ import net.osmand.PlatformUtil;
|
||||||
import net.osmand.ResultMatcher;
|
import net.osmand.ResultMatcher;
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
import net.osmand.data.Amenity;
|
import net.osmand.data.Amenity;
|
||||||
|
import net.osmand.data.City;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
import net.osmand.data.MapObject;
|
||||||
import net.osmand.data.Street;
|
import net.osmand.data.Street;
|
||||||
import net.osmand.osm.MapPoiTypes;
|
import net.osmand.osm.MapPoiTypes;
|
||||||
import net.osmand.search.core.CustomSearchPoiFilter;
|
import net.osmand.search.core.CustomSearchPoiFilter;
|
||||||
|
@ -25,14 +27,18 @@ import net.osmand.util.Algorithms;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -480,7 +486,7 @@ public class SearchUICore {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
searchInBackground(phrase, rm);
|
searchInternal(phrase, rm);
|
||||||
if (!rm.isCancelled()) {
|
if (!rm.isCancelled()) {
|
||||||
SearchResultCollection collection = new SearchResultCollection(
|
SearchResultCollection collection = new SearchResultCollection(
|
||||||
phrase);
|
phrase);
|
||||||
|
@ -492,6 +498,9 @@ public class SearchUICore {
|
||||||
LOG.info("Finishing search <" + phrase + "> Results=" + rm.getRequestResults().size());
|
LOG.info("Finishing search <" + phrase + "> Results=" + rm.getRequestResults().size());
|
||||||
}
|
}
|
||||||
currentSearchResult = collection;
|
currentSearchResult = collection;
|
||||||
|
if (phrase.getSettings().isExportObjects()) {
|
||||||
|
rm.createTestJSON(collection);
|
||||||
|
}
|
||||||
rm.searchFinished(phrase);
|
rm.searchFinished(phrase);
|
||||||
if (onResultsComplete != null) {
|
if (onResultsComplete != null) {
|
||||||
onResultsComplete.run();
|
onResultsComplete.run();
|
||||||
|
@ -548,7 +557,7 @@ public class SearchUICore {
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchInBackground(final SearchPhrase phrase, SearchResultMatcher matcher) {
|
void searchInternal(final SearchPhrase phrase, SearchResultMatcher matcher) {
|
||||||
preparePhrase(phrase);
|
preparePhrase(phrase);
|
||||||
ArrayList<SearchCoreAPI> lst = new ArrayList<>(apis);
|
ArrayList<SearchCoreAPI> lst = new ArrayList<>(apis);
|
||||||
Collections.sort(lst, new Comparator<SearchCoreAPI>() {
|
Collections.sort(lst, new Comparator<SearchCoreAPI>() {
|
||||||
|
@ -600,10 +609,7 @@ public class SearchUICore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class SearchResultMatcher implements ResultMatcher<SearchResult>{
|
||||||
|
|
||||||
|
|
||||||
public static class SearchResultMatcher implements ResultMatcher<SearchResult>{
|
|
||||||
private final List<SearchResult> requestResults = new ArrayList<>();
|
private final List<SearchResult> requestResults = new ArrayList<>();
|
||||||
private final ResultMatcher<SearchResult> matcher;
|
private final ResultMatcher<SearchResult> matcher;
|
||||||
private final int request;
|
private final int request;
|
||||||
|
@ -612,7 +618,8 @@ public class SearchUICore {
|
||||||
private final AtomicInteger requestNumber;
|
private final AtomicInteger requestNumber;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
private SearchPhrase phrase;
|
private SearchPhrase phrase;
|
||||||
|
private List<MapObject> exportedObjects;
|
||||||
|
private List<City> exportedCities;
|
||||||
|
|
||||||
public SearchResultMatcher(ResultMatcher<SearchResult> matcher, SearchPhrase phrase, int request,
|
public SearchResultMatcher(ResultMatcher<SearchResult> matcher, SearchPhrase phrase, int request,
|
||||||
AtomicInteger requestNumber, int totalLimit) {
|
AtomicInteger requestNumber, int totalLimit) {
|
||||||
|
@ -714,6 +721,111 @@ public class SearchUICore {
|
||||||
boolean cancelled = request != requestNumber.get();
|
boolean cancelled = request != requestNumber.get();
|
||||||
return cancelled || (matcher != null && matcher.isCancelled());
|
return cancelled || (matcher != null && matcher.isCancelled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<MapObject> getExportedObjects() {
|
||||||
|
return exportedObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<City> getExportedCities() {
|
||||||
|
return exportedCities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void exportObject(MapObject object) {
|
||||||
|
if (exportedObjects == null) {
|
||||||
|
exportedObjects = new ArrayList<>();
|
||||||
|
}
|
||||||
|
exportedObjects.add(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void exportCity(City city) {
|
||||||
|
if (exportedCities == null) {
|
||||||
|
exportedCities = new ArrayList<>();
|
||||||
|
}
|
||||||
|
exportedCities.add(city);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject createTestJSON(SearchResultCollection searchResult) {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
|
||||||
|
Set<Amenity> amenities = new HashSet<>();
|
||||||
|
Set<City> cities;
|
||||||
|
Set<City> matchedCities = new HashSet<>();
|
||||||
|
Set<City> streetCities = new HashSet<>();
|
||||||
|
if (exportedCities != null) {
|
||||||
|
cities = new HashSet<>(exportedCities);
|
||||||
|
} else {
|
||||||
|
cities = new HashSet<>();
|
||||||
|
}
|
||||||
|
Set<Street> streets = new HashSet<>();
|
||||||
|
|
||||||
|
for (MapObject obj : exportedObjects) {
|
||||||
|
if (obj instanceof Amenity) {
|
||||||
|
amenities.add((Amenity) obj);
|
||||||
|
} else if (obj instanceof Street) {
|
||||||
|
Street street = (Street) obj;
|
||||||
|
streets.add(street);
|
||||||
|
if (street.getCity() != null) {
|
||||||
|
final City city = street.getCity();
|
||||||
|
cities.add(city);
|
||||||
|
streetCities.add(city);
|
||||||
|
}
|
||||||
|
} else if (obj instanceof City) {
|
||||||
|
City city = (City) obj;
|
||||||
|
cities.add(city);
|
||||||
|
matchedCities.add(city);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (City city : cities) {
|
||||||
|
List<Street> cityStreets = city.getStreets();
|
||||||
|
for (Street street : streets) {
|
||||||
|
if (city.equals(street.getCity()) && !cityStreets.contains(street)) {
|
||||||
|
cityStreets.add(street);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json.put("settings", phrase.getSettings().toJSON());
|
||||||
|
json.put("phrase", phrase.getRawUnknownSearchPhrase());
|
||||||
|
if (searchResult.searchResults != null && searchResult.searchResults.size() > 0) {
|
||||||
|
JSONArray resultsArr = new JSONArray();
|
||||||
|
for (SearchResult r : searchResult.searchResults) {
|
||||||
|
resultsArr.put(r.toString());
|
||||||
|
}
|
||||||
|
json.put("results", resultsArr);
|
||||||
|
}
|
||||||
|
if (amenities.size() > 0) {
|
||||||
|
JSONArray amenitiesArr = new JSONArray();
|
||||||
|
for (Amenity amenity : amenities) {
|
||||||
|
amenitiesArr.put(amenity.toJSON());
|
||||||
|
}
|
||||||
|
json.put("amenities", amenitiesArr);
|
||||||
|
}
|
||||||
|
if (exportedCities != null && exportedCities.size() > 0) {
|
||||||
|
JSONArray citiesArr = new JSONArray();
|
||||||
|
for (City city : exportedCities) {
|
||||||
|
citiesArr.put(city.toJSON());
|
||||||
|
}
|
||||||
|
json.put("cities", citiesArr);
|
||||||
|
}
|
||||||
|
if (cities.size() > 0) {
|
||||||
|
JSONArray citiesArr = new JSONArray();
|
||||||
|
for (City city : cities) {
|
||||||
|
final JSONObject cityObj = city.toJSON();
|
||||||
|
if (exportedCities.contains(city)) {
|
||||||
|
cityObj.put("init", 1);
|
||||||
|
}
|
||||||
|
if (matchedCities.contains(city)) {
|
||||||
|
cityObj.put("matchCity", 1);
|
||||||
|
}
|
||||||
|
if (streetCities.contains(city)) {
|
||||||
|
cityObj.put("matchStreet", 1);
|
||||||
|
}
|
||||||
|
citiesArr.put(cityObj);
|
||||||
|
}
|
||||||
|
json.put("cities", citiesArr);
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SearchResultComparator implements Comparator<SearchResult> {
|
public static class SearchResultComparator implements Comparator<SearchResult> {
|
||||||
|
|
|
@ -226,8 +226,6 @@ public class SearchCoreFactory {
|
||||||
return retName;
|
return retName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class SearchAddressByNameAPI extends SearchBaseAPI {
|
public static class SearchAddressByNameAPI extends SearchBaseAPI {
|
||||||
|
|
||||||
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100 * 1000;
|
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100 * 1000;
|
||||||
|
@ -322,6 +320,9 @@ public class SearchCoreFactory {
|
||||||
resArray = townCitiesQR.queryInBox(bbox, resArray);
|
resArray = townCitiesQR.queryInBox(bbox, resArray);
|
||||||
int limit = 0;
|
int limit = 0;
|
||||||
for (City c : resArray) {
|
for (City c : resArray) {
|
||||||
|
if (phrase.getSettings().isExportObjects()) {
|
||||||
|
resultMatcher.exportCity(c);
|
||||||
|
}
|
||||||
SearchResult res = new SearchResult(phrase);
|
SearchResult res = new SearchResult(phrase);
|
||||||
res.object = c;
|
res.object = c;
|
||||||
res.file = (BinaryMapIndexReader) c.getReferenceFile();
|
res.file = (BinaryMapIndexReader) c.getReferenceFile();
|
||||||
|
@ -347,7 +348,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void searchByName(final SearchPhrase phrase, final SearchResultMatcher resultMatcher)
|
private void searchByName(final SearchPhrase phrase, final SearchResultMatcher resultMatcher)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (phrase.getRadiusLevel() > 1 || phrase.getUnknownSearchWordLength() > 3 || phrase.getUnknownSearchWords().size() > 0) {
|
if (phrase.getRadiusLevel() > 1 || phrase.getUnknownSearchWordLength() > 3 || phrase.getUnknownSearchWords().size() > 0) {
|
||||||
|
@ -362,11 +362,13 @@ public class SearchCoreFactory {
|
||||||
SEARCH_ADDRESS_BY_NAME_PRIORITY : SEARCH_ADDRESS_BY_NAME_PRIORITY_RADIUS2;
|
SEARCH_ADDRESS_BY_NAME_PRIORITY : SEARCH_ADDRESS_BY_NAME_PRIORITY_RADIUS2;
|
||||||
final BinaryMapIndexReader[] currentFile = new BinaryMapIndexReader[1];
|
final BinaryMapIndexReader[] currentFile = new BinaryMapIndexReader[1];
|
||||||
|
|
||||||
|
|
||||||
ResultMatcher<MapObject> rm = new ResultMatcher<MapObject>() {
|
ResultMatcher<MapObject> rm = new ResultMatcher<MapObject>() {
|
||||||
int limit = 0;
|
int limit = 0;
|
||||||
@Override
|
@Override
|
||||||
public boolean publish(MapObject object) {
|
public boolean publish(MapObject object) {
|
||||||
|
if (phrase.getSettings().isExportObjects()) {
|
||||||
|
resultMatcher.exportObject(object);
|
||||||
|
}
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -408,7 +410,6 @@ public class SearchCoreFactory {
|
||||||
|| !phrase.isSearchTypeAllowed(ObjectType.CITY)) {
|
|| !phrase.isSearchTypeAllowed(ObjectType.CITY)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sr.objectType = ObjectType.CITY;
|
sr.objectType = ObjectType.CITY;
|
||||||
sr.priorityDistance = 0.1;
|
sr.priorityDistance = 0.1;
|
||||||
} else if (((City)object).isPostcode()) {
|
} else if (((City)object).isPostcode()) {
|
||||||
|
@ -418,7 +419,7 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
sr.objectType = ObjectType.POSTCODE;
|
sr.objectType = ObjectType.POSTCODE;
|
||||||
sr.priorityDistance = 0;
|
sr.priorityDistance = 0;
|
||||||
} else {
|
} else {
|
||||||
if ((locSpecified && !villagesBbox.contains(x, y, x, y))
|
if ((locSpecified && !villagesBbox.contains(x, y, x, y))
|
||||||
|| !phrase.isSearchTypeAllowed(ObjectType.VILLAGE)) {
|
|| !phrase.isSearchTypeAllowed(ObjectType.VILLAGE)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -453,8 +454,6 @@ public class SearchCoreFactory {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCancelled() {
|
public boolean isCancelled() {
|
||||||
return limit > LIMIT * phrase.getRadiusLevel() ||
|
return limit > LIMIT * phrase.getRadiusLevel() ||
|
||||||
|
@ -497,8 +496,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class SearchAmenityByNameAPI extends SearchBaseAPI {
|
public static class SearchAmenityByNameAPI extends SearchBaseAPI {
|
||||||
private static final int LIMIT = 10000;
|
private static final int LIMIT = 10000;
|
||||||
private static final int BBOX_RADIUS = 500 * 1000;
|
private static final int BBOX_RADIUS = 500 * 1000;
|
||||||
|
@ -543,6 +540,9 @@ public class SearchCoreFactory {
|
||||||
int limit = 0;
|
int limit = 0;
|
||||||
@Override
|
@Override
|
||||||
public boolean publish(Amenity object) {
|
public boolean publish(Amenity object) {
|
||||||
|
if (phrase.getSettings().isExportObjects()) {
|
||||||
|
resultMatcher.exportObject(object);
|
||||||
|
}
|
||||||
if (limit ++ > LIMIT) {
|
if (limit ++ > LIMIT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -630,8 +630,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class SearchAmenityTypesAPI extends SearchBaseAPI {
|
public static class SearchAmenityTypesAPI extends SearchBaseAPI {
|
||||||
|
|
||||||
private Map<String, PoiType> translatedNames = new LinkedHashMap<>();
|
private Map<String, PoiType> translatedNames = new LinkedHashMap<>();
|
||||||
|
@ -762,8 +760,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class SearchAmenityByTypeAPI extends SearchBaseAPI {
|
public static class SearchAmenityByTypeAPI extends SearchBaseAPI {
|
||||||
private static final int BBOX_RADIUS = 10000;
|
private static final int BBOX_RADIUS = 10000;
|
||||||
private SearchAmenityTypesAPI searchAmenityTypesAPI;
|
private SearchAmenityTypesAPI searchAmenityTypesAPI;
|
||||||
|
@ -884,6 +880,9 @@ public class SearchCoreFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean publish(Amenity object) {
|
public boolean publish(Amenity object) {
|
||||||
|
if (phrase.getSettings().isExportObjects()) {
|
||||||
|
resultMatcher.exportObject(object);
|
||||||
|
}
|
||||||
SearchResult res = new SearchResult(phrase);
|
SearchResult res = new SearchResult(phrase);
|
||||||
String poiID = object.getType().getKeyName() + "_" + object.getId();
|
String poiID = object.getType().getKeyName() + "_" + object.getId();
|
||||||
if(!searchedPois.add(poiID)) {
|
if(!searchedPois.add(poiID)) {
|
||||||
|
@ -977,8 +976,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class SearchStreetByCityAPI extends SearchBaseAPI {
|
public static class SearchStreetByCityAPI extends SearchBaseAPI {
|
||||||
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100 * 1000;
|
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100 * 1000;
|
||||||
|
|
||||||
|
@ -1076,8 +1073,6 @@ public class SearchCoreFactory {
|
||||||
p.isLastWord(ObjectType.VILLAGE);
|
p.isLastWord(ObjectType.VILLAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class SearchBuildingAndIntersectionsByStreetAPI extends SearchBaseAPI {
|
public static class SearchBuildingAndIntersectionsByStreetAPI extends SearchBaseAPI {
|
||||||
Street cacheBuilding;
|
Street cacheBuilding;
|
||||||
|
|
||||||
|
@ -1219,8 +1214,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class SearchLocationAndUrlAPI extends SearchBaseAPI {
|
public static class SearchLocationAndUrlAPI extends SearchBaseAPI {
|
||||||
|
|
||||||
public SearchLocationAndUrlAPI() {
|
public SearchLocationAndUrlAPI() {
|
||||||
|
@ -1345,6 +1338,4 @@ public class SearchCoreFactory {
|
||||||
return SEARCH_LOCATION_PRIORITY;
|
return SEARCH_LOCATION_PRIORITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
package net.osmand.search.core;
|
package net.osmand.search.core;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
import net.osmand.data.Amenity;
|
||||||
|
import net.osmand.data.City;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
import net.osmand.data.Street;
|
||||||
|
import net.osmand.osm.AbstractPoiType;
|
||||||
|
import net.osmand.osm.PoiCategory;
|
||||||
|
import net.osmand.osm.PoiFilter;
|
||||||
|
import net.osmand.osm.PoiType;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
public class SearchResult {
|
public class SearchResult {
|
||||||
// search phrase that makes search result valid
|
// search phrase that makes search result valid
|
||||||
public SearchPhrase requiredSearchPhrase;
|
public SearchPhrase requiredSearchPhrase;
|
||||||
|
@ -75,10 +83,63 @@ public class SearchResult {
|
||||||
public Object relatedObject;
|
public Object relatedObject;
|
||||||
public double distRelatedObjectName;
|
public double distRelatedObjectName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
if (!Algorithms.isEmpty(localeName)) {
|
||||||
|
b.append(localeName);
|
||||||
|
}
|
||||||
|
if (!Algorithms.isEmpty(localeRelatedObjectName)) {
|
||||||
|
if (b.length() > 0) {
|
||||||
|
b.append(", ");
|
||||||
|
}
|
||||||
|
b.append(localeRelatedObjectName);
|
||||||
|
if (relatedObject instanceof Street) {
|
||||||
|
Street street = (Street) relatedObject;
|
||||||
|
City city = street.getCity();
|
||||||
|
if (city != null) {
|
||||||
|
b.append(", ").append(city.getName(requiredSearchPhrase.getSettings().getLang(),
|
||||||
|
requiredSearchPhrase.getSettings().isTransliterate()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (object instanceof AbstractPoiType) {
|
||||||
|
if (b.length() > 0) {
|
||||||
|
b.append(" ");
|
||||||
|
}
|
||||||
|
AbstractPoiType poiType = (AbstractPoiType) object;
|
||||||
|
if (poiType instanceof PoiCategory) {
|
||||||
|
b.append("(Category)");
|
||||||
|
} else if (poiType instanceof PoiFilter) {
|
||||||
|
b.append("(Filter)");
|
||||||
|
} else if (poiType instanceof PoiType) {
|
||||||
|
PoiType p = (PoiType) poiType;
|
||||||
|
final AbstractPoiType parentType = p.getParentType();
|
||||||
|
if (parentType != null) {
|
||||||
|
final String translation = parentType.getTranslation();
|
||||||
|
b.append("(").append(translation);
|
||||||
|
if (parentType instanceof PoiCategory) {
|
||||||
|
b.append(" / Category)");
|
||||||
|
} else if (parentType instanceof PoiFilter) {
|
||||||
|
b.append(" / Filter)");
|
||||||
|
} else if (parentType instanceof PoiType) {
|
||||||
|
PoiType pp = (PoiType) poiType;
|
||||||
|
PoiFilter filter = pp.getFilter();
|
||||||
|
PoiCategory category = pp.getCategory();
|
||||||
|
if (filter != null && !filter.getTranslation().equals(translation)) {
|
||||||
|
b.append(" / ").append(filter.getTranslation()).append(")");
|
||||||
|
} else if (category != null && !category.getTranslation().equals(translation)) {
|
||||||
|
b.append(" / ").append(category.getTranslation()).append(")");
|
||||||
|
} else {
|
||||||
|
b.append(")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (p.getFilter() != null) {
|
||||||
|
b.append("(").append(p.getFilter().getTranslation()).append(")");
|
||||||
|
} else if (p.getCategory() != null) {
|
||||||
|
b.append("(").append(p.getCategory().getTranslation()).append(")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,18 @@ package net.osmand.search.core;
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
import net.osmand.data.MapObject;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
// immutable object
|
// immutable object
|
||||||
public class SearchSettings {
|
public class SearchSettings {
|
||||||
|
@ -19,21 +27,24 @@ public class SearchSettings {
|
||||||
private ObjectType[] searchTypes;
|
private ObjectType[] searchTypes;
|
||||||
private boolean emptyQueryAllowed;
|
private boolean emptyQueryAllowed;
|
||||||
private boolean sortByName;
|
private boolean sortByName;
|
||||||
|
private boolean exportObjects = true;
|
||||||
|
|
||||||
public SearchSettings(SearchSettings s) {
|
public SearchSettings(SearchSettings s) {
|
||||||
if(s != null) {
|
if(s != null) {
|
||||||
this.radiusLevel = s.radiusLevel;
|
this.radiusLevel = s.radiusLevel;
|
||||||
this.lang = s.lang;
|
this.lang = s.lang;
|
||||||
|
this.transliterateIfMissing = s.transliterateIfMissing;
|
||||||
this.totalLimit = s.totalLimit;
|
this.totalLimit = s.totalLimit;
|
||||||
this.offlineIndexes = s.offlineIndexes;
|
this.offlineIndexes = s.offlineIndexes;
|
||||||
this.originalLocation = s.originalLocation;
|
this.originalLocation = s.originalLocation;
|
||||||
this.searchTypes = s.searchTypes;
|
this.searchTypes = s.searchTypes;
|
||||||
this.emptyQueryAllowed = s.emptyQueryAllowed;
|
this.emptyQueryAllowed = s.emptyQueryAllowed;
|
||||||
this.sortByName = s.sortByName;
|
this.sortByName = s.sortByName;
|
||||||
|
this.exportObjects = s.exportObjects;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchSettings(List<BinaryMapIndexReader> offlineIndexes) {
|
public SearchSettings(List<? extends BinaryMapIndexReader> offlineIndexes) {
|
||||||
this.offlineIndexes = Collections.unmodifiableList(offlineIndexes);
|
this.offlineIndexes = Collections.unmodifiableList(offlineIndexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +53,7 @@ public class SearchSettings {
|
||||||
return offlineIndexes;
|
return offlineIndexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOfflineIndexes(List<BinaryMapIndexReader> offlineIndexes) {
|
public void setOfflineIndexes(List<? extends BinaryMapIndexReader> offlineIndexes) {
|
||||||
this.offlineIndexes = Collections.unmodifiableList(offlineIndexes);
|
this.offlineIndexes = Collections.unmodifiableList(offlineIndexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +142,16 @@ public class SearchSettings {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isExportObjects() {
|
||||||
|
return exportObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchSettings setExportObjects(boolean exportObjects) {
|
||||||
|
SearchSettings s = new SearchSettings(this);
|
||||||
|
this.exportObjects = exportObjects;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasCustomSearchType(ObjectType type) {
|
public boolean hasCustomSearchType(ObjectType type) {
|
||||||
if (searchTypes != null) {
|
if (searchTypes != null) {
|
||||||
for (ObjectType t : searchTypes) {
|
for (ObjectType t : searchTypes) {
|
||||||
|
@ -141,4 +162,52 @@ public class SearchSettings {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject toJSON() {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
if (originalLocation != null) {
|
||||||
|
json.put("lat", String.format(Locale.US, "%.5f", originalLocation.getLatitude()));
|
||||||
|
json.put("lon", String.format(Locale.US, "%.5f", originalLocation.getLongitude()));
|
||||||
|
}
|
||||||
|
json.put("radiusLevel", radiusLevel);
|
||||||
|
json.put("totalLimit", totalLimit);
|
||||||
|
json.put("lang", lang);
|
||||||
|
json.put("transliterateIfMissing", transliterateIfMissing);
|
||||||
|
json.put("emptyQueryAllowed", emptyQueryAllowed);
|
||||||
|
json.put("sortByName", sortByName);
|
||||||
|
if (searchTypes != null && searchTypes.length > 0) {
|
||||||
|
JSONArray searchTypesArr = new JSONArray();
|
||||||
|
for (ObjectType type : searchTypes) {
|
||||||
|
searchTypesArr.put(type.name());
|
||||||
|
}
|
||||||
|
json.put("searchTypes", searchTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SearchSettings parseJSON(JSONObject json) {
|
||||||
|
SearchSettings s = new SearchSettings(new ArrayList<BinaryMapIndexReader>());
|
||||||
|
if (json.has("lat") && json.has("lon")) {
|
||||||
|
s.originalLocation = new LatLon(json.getDouble("lat"), json.getDouble("lon"));
|
||||||
|
}
|
||||||
|
s.radiusLevel = json.optInt("radiusLevel", 1);
|
||||||
|
s.totalLimit = json.optInt("totalLimit", -1);
|
||||||
|
s.transliterateIfMissing = json.optBoolean("transliterateIfMissing", false);
|
||||||
|
s.emptyQueryAllowed = json.optBoolean("emptyQueryAllowed", false);
|
||||||
|
s.sortByName = json.optBoolean("sortByName", false);
|
||||||
|
if (json.has("lang")) {
|
||||||
|
s.lang = json.getString("lang");
|
||||||
|
}
|
||||||
|
if (json.has("searchTypes")) {
|
||||||
|
JSONArray searchTypesArr = json.getJSONArray("searchTypes");
|
||||||
|
ObjectType[] searchTypes = new ObjectType[searchTypesArr.length()];
|
||||||
|
for (int i = 0; i < searchTypesArr.length(); i++) {
|
||||||
|
String name = searchTypesArr.getString(i);
|
||||||
|
searchTypes[i] = ObjectType.valueOf(name);
|
||||||
|
}
|
||||||
|
s.searchTypes = searchTypes;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,12 @@ package net.osmand.util;
|
||||||
|
|
||||||
import net.osmand.IProgress;
|
import net.osmand.IProgress;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.router.GeneralRouter;
|
||||||
|
import net.osmand.router.RoutingConfiguration;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
@ -27,6 +31,7 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Stack;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
|
@ -691,4 +696,54 @@ public class Algorithms {
|
||||||
return str1.compareTo(str2);
|
return str1.compareTo(str2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getFileAsString(File file) {
|
||||||
|
try {
|
||||||
|
FileInputStream fin = new FileInputStream(file);
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(fin, "UTF-8"));
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
if (sb.length() > 0) {
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
sb.append(line);
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
fin.close();
|
||||||
|
return sb.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, String> parseStringsXml(File file) throws IOException, XmlPullParserException {
|
||||||
|
InputStream is = new FileInputStream(file);
|
||||||
|
XmlPullParser parser = PlatformUtil.newXMLPullParser();
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
parser.setInput(is, "UTF-8");
|
||||||
|
int tok;
|
||||||
|
String key = null;
|
||||||
|
StringBuilder text = null;
|
||||||
|
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
|
if (tok == XmlPullParser.START_TAG) {
|
||||||
|
text = new StringBuilder();
|
||||||
|
String name = parser.getName();
|
||||||
|
if ("string".equals(name)) {
|
||||||
|
key = parser.getAttributeValue("", "name");
|
||||||
|
}
|
||||||
|
} else if (tok == XmlPullParser.TEXT) {
|
||||||
|
if (text != null) {
|
||||||
|
text.append(parser.getText());
|
||||||
|
}
|
||||||
|
} else if (tok == XmlPullParser.END_TAG) {
|
||||||
|
if (key != null) {
|
||||||
|
map.put(key, text.toString());
|
||||||
|
}
|
||||||
|
key = null;
|
||||||
|
text = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is.close();
|
||||||
|
return map;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,22 +1,133 @@
|
||||||
package net.osmand.search;
|
package net.osmand.search;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import net.osmand.OsmAndCollator;
|
import net.osmand.OsmAndCollator;
|
||||||
|
import net.osmand.ResultMatcher;
|
||||||
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
import net.osmand.data.Amenity;
|
||||||
|
import net.osmand.data.Building;
|
||||||
|
import net.osmand.data.City;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
import net.osmand.data.MapObject;
|
||||||
|
import net.osmand.data.Street;
|
||||||
|
import net.osmand.osm.AbstractPoiType;
|
||||||
|
import net.osmand.osm.MapPoiTypes;
|
||||||
import net.osmand.search.SearchUICore.SearchResultCollection;
|
import net.osmand.search.SearchUICore.SearchResultCollection;
|
||||||
|
import net.osmand.search.SearchUICore.SearchResultMatcher;
|
||||||
import net.osmand.search.core.SearchPhrase;
|
import net.osmand.search.core.SearchPhrase;
|
||||||
import net.osmand.search.core.SearchResult;
|
import net.osmand.search.core.SearchResult;
|
||||||
import net.osmand.search.core.SearchSettings;
|
import net.osmand.search.core.SearchSettings;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class SearchCoreUITest {
|
public class SearchCoreUITest {
|
||||||
|
|
||||||
|
private static final String SEARCH_RESOURCES_PATH = "src/test/resources/search/";
|
||||||
|
private static Map<String, String> enPhrases = new HashMap<>();
|
||||||
|
private static Map<String, String> phrases = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
MapPoiTypes.setDefault(new MapPoiTypes("src/test/resources/poi_types.xml"));
|
||||||
|
MapPoiTypes poiTypes = MapPoiTypes.getDefault();
|
||||||
|
|
||||||
|
try {
|
||||||
|
enPhrases = Algorithms.parseStringsXml(new File("src/test/resources/phrases/en/phrases.xml"));
|
||||||
|
//phrases = Algorithms.parseStringsXml(new File("src/test/resources/phrases/ru/phrases.xml"));
|
||||||
|
phrases = enPhrases;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
poiTypes.setPoiTranslator(new MapPoiTypes.PoiTranslator() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTranslation(AbstractPoiType type) {
|
||||||
|
AbstractPoiType baseLangType = type.getBaseLangType();
|
||||||
|
if (baseLangType != null) {
|
||||||
|
return getTranslation(baseLangType) + " (" + type.getLang().toLowerCase() + ")";
|
||||||
|
}
|
||||||
|
return getTranslation(type.getIconKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTranslation(String keyName) {
|
||||||
|
String val = phrases.get("poi_" + keyName);
|
||||||
|
if (val != null) {
|
||||||
|
int ind = val.indexOf(';');
|
||||||
|
if (ind > 0) {
|
||||||
|
return val.substring(0, ind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSynonyms(AbstractPoiType type) {
|
||||||
|
AbstractPoiType baseLangType = type.getBaseLangType();
|
||||||
|
if (baseLangType != null) {
|
||||||
|
return getSynonyms(baseLangType);
|
||||||
|
}
|
||||||
|
return getSynonyms(type.getIconKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSynonyms(String keyName) {
|
||||||
|
String val = phrases.get("poi_" + keyName);
|
||||||
|
if (val != null) {
|
||||||
|
int ind = val.indexOf(';');
|
||||||
|
if (ind > 0) {
|
||||||
|
return val.substring(ind + 1);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEnTranslation(AbstractPoiType type) {
|
||||||
|
AbstractPoiType baseLangType = type.getBaseLangType();
|
||||||
|
if (baseLangType != null) {
|
||||||
|
return getEnTranslation(baseLangType) + " (" + type.getLang().toLowerCase() + ")";
|
||||||
|
}
|
||||||
|
return getEnTranslation(type.getIconKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEnTranslation(String keyName) {
|
||||||
|
if (enPhrases.isEmpty()) {
|
||||||
|
return Algorithms.capitalizeFirstLetter(keyName.replace('_', ' '));
|
||||||
|
}
|
||||||
|
String val = enPhrases.get("poi_" + keyName);
|
||||||
|
if (val != null) {
|
||||||
|
int ind = val.indexOf(';');
|
||||||
|
if (ind > 0) {
|
||||||
|
return val.substring(0, ind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicates() throws IOException {
|
public void testDuplicates() throws IOException {
|
||||||
SearchSettings ss = new SearchSettings((SearchSettings)null);
|
SearchSettings ss = new SearchSettings((SearchSettings)null);
|
||||||
|
@ -100,4 +211,220 @@ public class SearchCoreUITest {
|
||||||
rs.add(res);
|
rs.add(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchJsons() throws IOException {
|
||||||
|
final File[] files = new File(SEARCH_RESOURCES_PATH).listFiles(new FilenameFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File dir, String filename) {
|
||||||
|
return filename.endsWith(".json");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (files != null) {
|
||||||
|
for (File f : files) {
|
||||||
|
testSearchImpl(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testSearchImpl(File jsonFile) throws IOException, JSONException {
|
||||||
|
String sourceJsonText = Algorithms.getFileAsString(jsonFile);
|
||||||
|
Assert.assertNotNull(sourceJsonText);
|
||||||
|
Assert.assertTrue(sourceJsonText.length() > 0);
|
||||||
|
|
||||||
|
BinaryMapIndexReaderTest reader = new BinaryMapIndexReaderTest();
|
||||||
|
JSONObject sourceJson = new JSONObject(sourceJsonText);
|
||||||
|
String phraseText = sourceJson.getString("phrase");
|
||||||
|
JSONObject settingsJson = sourceJson.getJSONObject("settings");
|
||||||
|
if (sourceJson.has("amenities")) {
|
||||||
|
JSONArray amenitiesArr = sourceJson.getJSONArray("amenities");
|
||||||
|
List<Amenity> amenities = new ArrayList<>();
|
||||||
|
for (int i = 0; i < amenitiesArr.length(); i++) {
|
||||||
|
JSONObject amenityObj = amenitiesArr.getJSONObject(i);
|
||||||
|
amenities.add(Amenity.parseJSON(amenityObj));
|
||||||
|
}
|
||||||
|
reader.amenities = amenities;
|
||||||
|
}
|
||||||
|
if (sourceJson.has("cities")) {
|
||||||
|
JSONArray citiesArr = sourceJson.getJSONArray("cities");
|
||||||
|
List<City> cities = new ArrayList<>();
|
||||||
|
List<City> initCities = new ArrayList<>();
|
||||||
|
List<City> matchedCities = new ArrayList<>();
|
||||||
|
List<City> streetCities = new ArrayList<>();
|
||||||
|
for (int i = 0; i < citiesArr.length(); i++) {
|
||||||
|
JSONObject cityObj = citiesArr.getJSONObject(i);
|
||||||
|
final City city = City.parseJSON(cityObj);
|
||||||
|
cities.add(city);
|
||||||
|
if (cityObj.has("init")) {
|
||||||
|
initCities.add(city);
|
||||||
|
}
|
||||||
|
if (cityObj.has("matchCity")) {
|
||||||
|
matchedCities.add(city);
|
||||||
|
}
|
||||||
|
if (cityObj.has("matchStreet")) {
|
||||||
|
streetCities.add(city);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.cities = cities;
|
||||||
|
reader.initCities = initCities;
|
||||||
|
reader.matchedCities = matchedCities;
|
||||||
|
reader.streetCities = streetCities;
|
||||||
|
}
|
||||||
|
List<String> results = new ArrayList<>();
|
||||||
|
if (sourceJson.has("results")) {
|
||||||
|
JSONArray resultsArr = sourceJson.getJSONArray("results");
|
||||||
|
for (int i = 0; i < resultsArr.length(); i++) {
|
||||||
|
results.add(resultsArr.getString(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchSettings s = SearchSettings.parseJSON(settingsJson);
|
||||||
|
s.setOfflineIndexes(Collections.singletonList(reader));
|
||||||
|
|
||||||
|
SearchPhrase phrase = new SearchPhrase(s, OsmAndCollator.primaryCollator());
|
||||||
|
phrase = phrase.generateNewPhrase(phraseText, s);
|
||||||
|
|
||||||
|
final SearchUICore core = new SearchUICore(MapPoiTypes.getDefault(), "en", false);
|
||||||
|
core.init();
|
||||||
|
|
||||||
|
ResultMatcher<SearchResult> rm = new ResultMatcher<SearchResult>() {
|
||||||
|
@Override
|
||||||
|
public boolean publish(SearchResult object) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SearchResultMatcher matcher = new SearchResultMatcher(rm, phrase, 1, new AtomicInteger(1), -1);
|
||||||
|
core.searchInternal(phrase, matcher);
|
||||||
|
|
||||||
|
SearchResultCollection collection = new SearchResultCollection(phrase);
|
||||||
|
collection.addSearchResults(matcher.getRequestResults(), true, true);
|
||||||
|
List<SearchResult> searchResults = collection.getCurrentSearchResults();
|
||||||
|
int i = 0;
|
||||||
|
for (SearchResult result : searchResults) {
|
||||||
|
String expected = results.get(i++);
|
||||||
|
String present = result.toString();
|
||||||
|
//System.out.println(present);
|
||||||
|
Assert.assertEquals(expected, present);
|
||||||
|
if (i >= results.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BinaryMapIndexReaderTest extends BinaryMapIndexReader {
|
||||||
|
|
||||||
|
List<Amenity> amenities = Collections.emptyList();
|
||||||
|
List<City> cities = Collections.emptyList();
|
||||||
|
List<City> initCities = Collections.emptyList();
|
||||||
|
List<City> matchedCities = Collections.emptyList();
|
||||||
|
List<City> streetCities = Collections.emptyList();
|
||||||
|
|
||||||
|
BinaryMapIndexReaderTest() throws IOException {
|
||||||
|
super(null, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Amenity> searchPoiByName(SearchRequest<Amenity> req) throws IOException {
|
||||||
|
for (Amenity amenity : amenities) {
|
||||||
|
req.publish(amenity);
|
||||||
|
}
|
||||||
|
return req.getSearchResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Amenity> searchPoi(SearchRequest<Amenity> req) throws IOException {
|
||||||
|
for (Amenity amenity : amenities) {
|
||||||
|
req.publish(amenity);
|
||||||
|
}
|
||||||
|
return req.getSearchResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<City> getCities(SearchRequest<City> resultMatcher, int cityType) throws IOException {
|
||||||
|
for (City city : initCities) {
|
||||||
|
if (resultMatcher != null) {
|
||||||
|
resultMatcher.publish(city);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return initCities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int preloadStreets(City c, SearchRequest<Street> resultMatcher) throws IOException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preloadBuildings(Street s, SearchRequest<Building> resultMatcher) throws IOException {
|
||||||
|
// cities must be filled with streets and buildings
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MapObject> searchAddressDataByName(SearchRequest<MapObject> req) throws IOException {
|
||||||
|
for (City city : streetCities) {
|
||||||
|
for (Street street : city.getStreets()) {
|
||||||
|
req.publish(street);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (City city : matchedCities) {
|
||||||
|
req.publish(city);
|
||||||
|
}
|
||||||
|
return req.getSearchResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRegionName() {
|
||||||
|
return "Test region";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsPoiData(int left31x, int top31y, int right31x, int bottom31y) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsMapData() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsPoiData() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsRouteData() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsRouteData(int left31x, int top31y, int right31x, int bottom31y, int zoom) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAddressData(int left31x, int top31y, int right31x, int bottom31y) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsMapData(int tile31x, int tile31y, int zoom) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsMapData(int left31x, int top31y, int right31x, int bottom31y, int zoom) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAddressData() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
4
OsmAnd-java/src/test/resources/.gitignore
vendored
4
OsmAnd-java/src/test/resources/.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
*.json
|
/*.json
|
||||||
|
/osm_live/*.json
|
||||||
*.obf
|
*.obf
|
||||||
*.osm
|
*.osm
|
||||||
|
phrases.xml
|
700
OsmAnd-java/src/test/resources/search/double_parking.json
Normal file
700
OsmAnd-java/src/test/resources/search/double_parking.json
Normal file
|
@ -0,0 +1,700 @@
|
||||||
|
{
|
||||||
|
"settings": {
|
||||||
|
"lat": "55.28666",
|
||||||
|
"lon": "52.00556",
|
||||||
|
"radiusLevel": 1,
|
||||||
|
"totalLimit": -1,
|
||||||
|
"lang": "",
|
||||||
|
"transliterateIfMissing": false,
|
||||||
|
"emptyQueryAllowed": false,
|
||||||
|
"sortByName": false
|
||||||
|
},
|
||||||
|
"phrase": "parking",
|
||||||
|
"results": [
|
||||||
|
"Park (Leisure)",
|
||||||
|
"Parking (Filter)",
|
||||||
|
"Parking entrance (Personal transport)",
|
||||||
|
"Parking fee (Charging station / Transportation)",
|
||||||
|
"Parking fee: no (Charging station / Transportation)",
|
||||||
|
"Parking fee: yes (Charging station / Transportation)",
|
||||||
|
"Parking lot (Fire hydrant / Emergency infrastructure)",
|
||||||
|
"Parking tickets (Vending machine / Store)",
|
||||||
|
"Parking tickets (Vending machine / Store)",
|
||||||
|
"Parking time limit (Parking / Personal transport)",
|
||||||
|
"Parking",
|
||||||
|
"Parking",
|
||||||
|
"Parking",
|
||||||
|
"Parking",
|
||||||
|
"Parking",
|
||||||
|
"Parking"
|
||||||
|
],
|
||||||
|
"amenities": [
|
||||||
|
{
|
||||||
|
"lat": "55.29801",
|
||||||
|
"lon": "51.99100",
|
||||||
|
"id": 881010149,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29481",
|
||||||
|
"lon": "51.98964",
|
||||||
|
"id": 803545283,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Заинская ГРЭС",
|
||||||
|
"lat": "55.28492",
|
||||||
|
"lon": "52.02125",
|
||||||
|
"id": 481494555,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_yes": "yes",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29105",
|
||||||
|
"lon": "51.99531",
|
||||||
|
"id": 540237721,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28683",
|
||||||
|
"lon": "52.01479",
|
||||||
|
"id": 888343263,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_unpaved": "unpaved",
|
||||||
|
"access_permissive": "permissive",
|
||||||
|
"supervised_yes": "yes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.30317",
|
||||||
|
"lon": "52.00192",
|
||||||
|
"id": 1161722765,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"operator": "cахарный завод"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "для техосмотра",
|
||||||
|
"lat": "55.30439",
|
||||||
|
"lon": "52.01634",
|
||||||
|
"id": 484385195,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28615",
|
||||||
|
"lon": "52.00702",
|
||||||
|
"id": 1040771455,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28582",
|
||||||
|
"lon": "52.00758",
|
||||||
|
"id": 535925577,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.30950",
|
||||||
|
"lon": "51.96954",
|
||||||
|
"id": 1228158833,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29345",
|
||||||
|
"lon": "51.99385",
|
||||||
|
"id": 535897911,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.30957",
|
||||||
|
"lon": "52.00374",
|
||||||
|
"id": 897019441,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28602",
|
||||||
|
"lon": "52.00908",
|
||||||
|
"id": 268235957,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28777",
|
||||||
|
"lon": "51.99608",
|
||||||
|
"id": 4410403520512,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"surface_unpaved": "unpaved",
|
||||||
|
"supervised_yes": "yes",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"fee_yes": "yes",
|
||||||
|
"capacity": "70"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.34092",
|
||||||
|
"lon": "52.05172",
|
||||||
|
"id": 2136388576,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28271",
|
||||||
|
"lon": "52.00248",
|
||||||
|
"id": 536030271,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28391",
|
||||||
|
"lon": "52.00273",
|
||||||
|
"id": 536035007,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Служебная",
|
||||||
|
"lat": "55.28615",
|
||||||
|
"lon": "52.02350",
|
||||||
|
"id": 481491939,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"fee_no": "no",
|
||||||
|
"access_permissive": "permissive",
|
||||||
|
"supervised_yes": "yes",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.30969",
|
||||||
|
"lon": "51.96917",
|
||||||
|
"id": 1228158821,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.31022",
|
||||||
|
"lon": "51.97104",
|
||||||
|
"id": 1228158819,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29275",
|
||||||
|
"lon": "51.99355",
|
||||||
|
"id": 892959215,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "для посетителей",
|
||||||
|
"lat": "55.28688",
|
||||||
|
"lon": "52.00578",
|
||||||
|
"id": 11390213698,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.30838",
|
||||||
|
"lon": "51.96767",
|
||||||
|
"id": 1164434353,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Южная",
|
||||||
|
"lat": "55.27739",
|
||||||
|
"lon": "52.00544",
|
||||||
|
"id": 641567205,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"surface_unpaved": "unpaved",
|
||||||
|
"supervised_yes": "yes",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"fee_yes": "yes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28045",
|
||||||
|
"lon": "51.99550",
|
||||||
|
"id": 478137507,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"supervised_yes": "yes",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"fee_yes": "yes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Автостоянка №1",
|
||||||
|
"lat": "55.29028",
|
||||||
|
"lon": "51.99934",
|
||||||
|
"id": 502948005,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"surface_gravel": "gravel",
|
||||||
|
"supervised_yes": "yes",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"fee_yes": "yes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.27839",
|
||||||
|
"lon": "52.00301",
|
||||||
|
"id": 1168315587,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"operator": "Заинская ЦРБ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.30468",
|
||||||
|
"lon": "52.01335",
|
||||||
|
"id": 897014805,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.32509",
|
||||||
|
"lon": "51.99930",
|
||||||
|
"id": 1172111487,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Штрафстоянка (Эвакуатор)",
|
||||||
|
"lat": "55.30439",
|
||||||
|
"lon": "52.01346",
|
||||||
|
"id": 5153530824,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"supervised_yes": "yes",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"fee_yes": "yes",
|
||||||
|
"phone": "+7 (85558) 7-77-01"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Три тополя",
|
||||||
|
"lat": "55.29666",
|
||||||
|
"lon": "51.99048",
|
||||||
|
"id": 642175341,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"surface_unpaved": "unpaved",
|
||||||
|
"supervised_yes": "yes",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"fee_yes": "yes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29077",
|
||||||
|
"lon": "52.00812",
|
||||||
|
"id": 1168356553,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_yes": "yes",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"fee_yes": "yes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29429",
|
||||||
|
"lon": "51.99190",
|
||||||
|
"id": 893048919,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29959",
|
||||||
|
"lon": "52.00516",
|
||||||
|
"id": 1022216961,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28355",
|
||||||
|
"lon": "51.99881",
|
||||||
|
"id": 943827057,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28651",
|
||||||
|
"lon": "52.00479",
|
||||||
|
"id": 905757839,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28928",
|
||||||
|
"lon": "52.00977",
|
||||||
|
"id": 190467181,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_gravel": "gravel",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28674",
|
||||||
|
"lon": "52.00282",
|
||||||
|
"id": 1168411743,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "для клиентов",
|
||||||
|
"lat": "55.29116",
|
||||||
|
"lon": "51.99394",
|
||||||
|
"id": 821840897,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"access_customers": "customers"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29068",
|
||||||
|
"lon": "51.99490",
|
||||||
|
"id": 540238031,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28982",
|
||||||
|
"lon": "51.98911",
|
||||||
|
"id": 190489189,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29341",
|
||||||
|
"lon": "51.99072",
|
||||||
|
"id": 806562897,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28042",
|
||||||
|
"lon": "52.00155",
|
||||||
|
"id": 1159734951,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.30493",
|
||||||
|
"lon": "52.01007",
|
||||||
|
"id": 1172110357,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.30500",
|
||||||
|
"lon": "52.01108",
|
||||||
|
"id": 1172110359,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"capacity": "13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29816",
|
||||||
|
"lon": "51.99222",
|
||||||
|
"id": 1160388645,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29015",
|
||||||
|
"lon": "51.99366",
|
||||||
|
"id": 503278061,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.30624",
|
||||||
|
"lon": "52.00475",
|
||||||
|
"id": 691494051,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"operator": "ЗЗМК - Тимер"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "для регистрации в ГИБДД",
|
||||||
|
"lat": "55.30438",
|
||||||
|
"lon": "52.01483",
|
||||||
|
"id": 484385289,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29258",
|
||||||
|
"lon": "51.99188",
|
||||||
|
"id": 892959265,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.28050",
|
||||||
|
"lon": "52.00200",
|
||||||
|
"id": 1159662915,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface",
|
||||||
|
"capacity": "10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": "55.29845",
|
||||||
|
"lon": "51.99057",
|
||||||
|
"id": 881010015,
|
||||||
|
"subType": "parking",
|
||||||
|
"type": "transportation",
|
||||||
|
"additionalInfo": {
|
||||||
|
"fee_no": "no",
|
||||||
|
"surface_asphalt": "asphalt",
|
||||||
|
"supervised_no": "no",
|
||||||
|
"parking_surface": "surface"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2897
OsmAnd-java/src/test/resources/search/street_komsomolskaya.json
Normal file
2897
OsmAnd-java/src/test/resources/search/street_komsomolskaya.json
Normal file
File diff suppressed because it is too large
Load diff
8626
OsmAnd-java/src/test/resources/search/street_lenina_30.json
Normal file
8626
OsmAnd-java/src/test/resources/search/street_lenina_30.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -438,26 +438,6 @@ public class AndroidUtils {
|
||||||
return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
|
return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFileAsString(File file) {
|
|
||||||
try {
|
|
||||||
FileInputStream fin = new FileInputStream(file);
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(fin, "UTF-8"));
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
String line;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
sb.append("\n");
|
|
||||||
}
|
|
||||||
sb.append(line);
|
|
||||||
}
|
|
||||||
reader.close();
|
|
||||||
fin.close();
|
|
||||||
return sb.toString();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PointF centroidForPoly(PointF[] points) {
|
public static PointF centroidForPoly(PointF[] points) {
|
||||||
float centroidX = 0, centroidY = 0;
|
float centroidX = 0, centroidY = 0;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
|
||||||
import net.osmand.IndexConstants;
|
import net.osmand.IndexConstants;
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
@ -824,7 +823,7 @@ public class ExternalApiHelper {
|
||||||
// test show gpx (data)
|
// test show gpx (data)
|
||||||
uri = Uri.parse("osmand.api://show_gpx");
|
uri = Uri.parse("osmand.api://show_gpx");
|
||||||
intent = new Intent(Intent.ACTION_VIEW, uri);
|
intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
intent.putExtra("data", AndroidUtils.getFileAsString(
|
intent.putExtra("data", Algorithms.getFileAsString(
|
||||||
new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), gpxName)));
|
new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), gpxName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,7 +835,7 @@ public class ExternalApiHelper {
|
||||||
// test navigate gpx (data)
|
// test navigate gpx (data)
|
||||||
uri = Uri.parse("osmand.api://navigate_gpx?force=true");
|
uri = Uri.parse("osmand.api://navigate_gpx?force=true");
|
||||||
intent = new Intent(Intent.ACTION_VIEW, uri);
|
intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
intent.putExtra("data", AndroidUtils.getFileAsString(
|
intent.putExtra("data", Algorithms.getFileAsString(
|
||||||
new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), gpxName)));
|
new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), gpxName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue