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) {
|
||||
from "../../resources/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;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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 com.google.protobuf.CodedInputStream;
|
||||
import com.google.protobuf.CodedOutputStream;
|
||||
import com.google.protobuf.WireFormat;
|
||||
|
||||
import net.osmand.Collator;
|
||||
import net.osmand.CollatorStringMatcher;
|
||||
|
@ -72,9 +44,37 @@ import org.w3c.dom.NodeList;
|
|||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.google.protobuf.CodedInputStream;
|
||||
import com.google.protobuf.CodedOutputStream;
|
||||
import com.google.protobuf.WireFormat;
|
||||
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 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 {
|
||||
|
||||
|
@ -130,7 +130,7 @@ public class BinaryMapIndexReader {
|
|||
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.file = file;
|
||||
codedIS = CodedInputStream.newInstance(raf);
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
package net.osmand.data;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.edit.Node;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
@ -317,4 +320,49 @@ public class Amenity extends MapObject {
|
|||
public boolean isClosed() {
|
||||
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;
|
||||
|
||||
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class Building extends MapObject {
|
||||
|
||||
private String postcode;
|
||||
|
@ -216,4 +219,43 @@ public class Building extends MapObject {
|
|||
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;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
@ -55,7 +58,6 @@ public class City extends MapObject {
|
|||
return new City(postcode, POSTCODE_INTERNAL_ID--);
|
||||
}
|
||||
|
||||
|
||||
public City(CityType type) {
|
||||
if (type == null) {
|
||||
throw new NullPointerException();
|
||||
|
@ -156,4 +158,43 @@ public class City extends MapObject {
|
|||
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;
|
||||
|
||||
|
||||
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.OsmAndCollator;
|
||||
import net.osmand.util.Algorithms;
|
||||
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> {
|
||||
|
||||
|
@ -289,4 +293,48 @@ public abstract class MapObject implements Comparable<MapObject> {
|
|||
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;
|
||||
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
|
||||
public class Street extends MapObject {
|
||||
|
||||
|
@ -86,4 +89,53 @@ public class Street extends MapObject {
|
|||
}
|
||||
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.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.City;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.MapObject;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.search.core.CustomSearchPoiFilter;
|
||||
|
@ -25,14 +27,18 @@ import net.osmand.util.Algorithms;
|
|||
import net.osmand.util.MapUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -480,7 +486,7 @@ public class SearchUICore {
|
|||
}
|
||||
return;
|
||||
}
|
||||
searchInBackground(phrase, rm);
|
||||
searchInternal(phrase, rm);
|
||||
if (!rm.isCancelled()) {
|
||||
SearchResultCollection collection = new SearchResultCollection(
|
||||
phrase);
|
||||
|
@ -492,6 +498,9 @@ public class SearchUICore {
|
|||
LOG.info("Finishing search <" + phrase + "> Results=" + rm.getRequestResults().size());
|
||||
}
|
||||
currentSearchResult = collection;
|
||||
if (phrase.getSettings().isExportObjects()) {
|
||||
rm.createTestJSON(collection);
|
||||
}
|
||||
rm.searchFinished(phrase);
|
||||
if (onResultsComplete != null) {
|
||||
onResultsComplete.run();
|
||||
|
@ -548,7 +557,7 @@ public class SearchUICore {
|
|||
return radius;
|
||||
}
|
||||
|
||||
private void searchInBackground(final SearchPhrase phrase, SearchResultMatcher matcher) {
|
||||
void searchInternal(final SearchPhrase phrase, SearchResultMatcher matcher) {
|
||||
preparePhrase(phrase);
|
||||
ArrayList<SearchCoreAPI> lst = new ArrayList<>(apis);
|
||||
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 ResultMatcher<SearchResult> matcher;
|
||||
private final int request;
|
||||
|
@ -612,7 +618,8 @@ public class SearchUICore {
|
|||
private final AtomicInteger requestNumber;
|
||||
int count = 0;
|
||||
private SearchPhrase phrase;
|
||||
|
||||
private List<MapObject> exportedObjects;
|
||||
private List<City> exportedCities;
|
||||
|
||||
public SearchResultMatcher(ResultMatcher<SearchResult> matcher, SearchPhrase phrase, int request,
|
||||
AtomicInteger requestNumber, int totalLimit) {
|
||||
|
@ -714,6 +721,111 @@ public class SearchUICore {
|
|||
boolean cancelled = request != requestNumber.get();
|
||||
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> {
|
||||
|
|
|
@ -226,8 +226,6 @@ public class SearchCoreFactory {
|
|||
return retName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class SearchAddressByNameAPI extends SearchBaseAPI {
|
||||
|
||||
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100 * 1000;
|
||||
|
@ -322,6 +320,9 @@ public class SearchCoreFactory {
|
|||
resArray = townCitiesQR.queryInBox(bbox, resArray);
|
||||
int limit = 0;
|
||||
for (City c : resArray) {
|
||||
if (phrase.getSettings().isExportObjects()) {
|
||||
resultMatcher.exportCity(c);
|
||||
}
|
||||
SearchResult res = new SearchResult(phrase);
|
||||
res.object = c;
|
||||
res.file = (BinaryMapIndexReader) c.getReferenceFile();
|
||||
|
@ -347,7 +348,6 @@ public class SearchCoreFactory {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void searchByName(final SearchPhrase phrase, final SearchResultMatcher resultMatcher)
|
||||
throws IOException {
|
||||
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;
|
||||
final BinaryMapIndexReader[] currentFile = new BinaryMapIndexReader[1];
|
||||
|
||||
|
||||
ResultMatcher<MapObject> rm = new ResultMatcher<MapObject>() {
|
||||
int limit = 0;
|
||||
@Override
|
||||
public boolean publish(MapObject object) {
|
||||
if (phrase.getSettings().isExportObjects()) {
|
||||
resultMatcher.exportObject(object);
|
||||
}
|
||||
if (isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -408,7 +410,6 @@ public class SearchCoreFactory {
|
|||
|| !phrase.isSearchTypeAllowed(ObjectType.CITY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sr.objectType = ObjectType.CITY;
|
||||
sr.priorityDistance = 0.1;
|
||||
} else if (((City)object).isPostcode()) {
|
||||
|
@ -418,7 +419,7 @@ public class SearchCoreFactory {
|
|||
}
|
||||
sr.objectType = ObjectType.POSTCODE;
|
||||
sr.priorityDistance = 0;
|
||||
} else {
|
||||
} else {
|
||||
if ((locSpecified && !villagesBbox.contains(x, y, x, y))
|
||||
|| !phrase.isSearchTypeAllowed(ObjectType.VILLAGE)) {
|
||||
return false;
|
||||
|
@ -453,8 +454,6 @@ public class SearchCoreFactory {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return limit > LIMIT * phrase.getRadiusLevel() ||
|
||||
|
@ -497,8 +496,6 @@ public class SearchCoreFactory {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class SearchAmenityByNameAPI extends SearchBaseAPI {
|
||||
private static final int LIMIT = 10000;
|
||||
private static final int BBOX_RADIUS = 500 * 1000;
|
||||
|
@ -543,6 +540,9 @@ public class SearchCoreFactory {
|
|||
int limit = 0;
|
||||
@Override
|
||||
public boolean publish(Amenity object) {
|
||||
if (phrase.getSettings().isExportObjects()) {
|
||||
resultMatcher.exportObject(object);
|
||||
}
|
||||
if (limit ++ > LIMIT) {
|
||||
return false;
|
||||
}
|
||||
|
@ -630,8 +630,6 @@ public class SearchCoreFactory {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class SearchAmenityTypesAPI extends SearchBaseAPI {
|
||||
|
||||
private Map<String, PoiType> translatedNames = new LinkedHashMap<>();
|
||||
|
@ -762,8 +760,6 @@ public class SearchCoreFactory {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class SearchAmenityByTypeAPI extends SearchBaseAPI {
|
||||
private static final int BBOX_RADIUS = 10000;
|
||||
private SearchAmenityTypesAPI searchAmenityTypesAPI;
|
||||
|
@ -884,6 +880,9 @@ public class SearchCoreFactory {
|
|||
|
||||
@Override
|
||||
public boolean publish(Amenity object) {
|
||||
if (phrase.getSettings().isExportObjects()) {
|
||||
resultMatcher.exportObject(object);
|
||||
}
|
||||
SearchResult res = new SearchResult(phrase);
|
||||
String poiID = object.getType().getKeyName() + "_" + object.getId();
|
||||
if(!searchedPois.add(poiID)) {
|
||||
|
@ -977,8 +976,6 @@ public class SearchCoreFactory {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class SearchStreetByCityAPI extends SearchBaseAPI {
|
||||
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100 * 1000;
|
||||
|
||||
|
@ -1076,8 +1073,6 @@ public class SearchCoreFactory {
|
|||
p.isLastWord(ObjectType.VILLAGE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class SearchBuildingAndIntersectionsByStreetAPI extends SearchBaseAPI {
|
||||
Street cacheBuilding;
|
||||
|
||||
|
@ -1219,8 +1214,6 @@ public class SearchCoreFactory {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class SearchLocationAndUrlAPI extends SearchBaseAPI {
|
||||
|
||||
public SearchLocationAndUrlAPI() {
|
||||
|
@ -1345,6 +1338,4 @@ public class SearchCoreFactory {
|
|||
return SEARCH_LOCATION_PRIORITY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
package net.osmand.search.core;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.City;
|
||||
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 java.util.Collection;
|
||||
|
||||
public class SearchResult {
|
||||
// search phrase that makes search result valid
|
||||
public SearchPhrase requiredSearchPhrase;
|
||||
|
@ -75,10 +83,63 @@ public class SearchResult {
|
|||
public Object relatedObject;
|
||||
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.data.LatLon;
|
||||
import net.osmand.data.MapObject;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
// immutable object
|
||||
public class SearchSettings {
|
||||
|
@ -19,21 +27,24 @@ public class SearchSettings {
|
|||
private ObjectType[] searchTypes;
|
||||
private boolean emptyQueryAllowed;
|
||||
private boolean sortByName;
|
||||
private boolean exportObjects = true;
|
||||
|
||||
public SearchSettings(SearchSettings s) {
|
||||
if(s != null) {
|
||||
this.radiusLevel = s.radiusLevel;
|
||||
this.lang = s.lang;
|
||||
this.transliterateIfMissing = s.transliterateIfMissing;
|
||||
this.totalLimit = s.totalLimit;
|
||||
this.offlineIndexes = s.offlineIndexes;
|
||||
this.originalLocation = s.originalLocation;
|
||||
this.searchTypes = s.searchTypes;
|
||||
this.emptyQueryAllowed = s.emptyQueryAllowed;
|
||||
this.sortByName = s.sortByName;
|
||||
this.exportObjects = s.exportObjects;
|
||||
}
|
||||
}
|
||||
|
||||
public SearchSettings(List<BinaryMapIndexReader> offlineIndexes) {
|
||||
public SearchSettings(List<? extends BinaryMapIndexReader> offlineIndexes) {
|
||||
this.offlineIndexes = Collections.unmodifiableList(offlineIndexes);
|
||||
}
|
||||
|
||||
|
@ -42,7 +53,7 @@ public class SearchSettings {
|
|||
return offlineIndexes;
|
||||
}
|
||||
|
||||
public void setOfflineIndexes(List<BinaryMapIndexReader> offlineIndexes) {
|
||||
public void setOfflineIndexes(List<? extends BinaryMapIndexReader> offlineIndexes) {
|
||||
this.offlineIndexes = Collections.unmodifiableList(offlineIndexes);
|
||||
}
|
||||
|
||||
|
@ -131,6 +142,16 @@ public class SearchSettings {
|
|||
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) {
|
||||
if (searchTypes != null) {
|
||||
for (ObjectType t : searchTypes) {
|
||||
|
@ -141,4 +162,52 @@ public class SearchSettings {
|
|||
}
|
||||
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.PlatformUtil;
|
||||
import net.osmand.router.GeneralRouter;
|
||||
import net.osmand.router.RoutingConfiguration;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
@ -27,6 +31,7 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
|
||||
|
@ -691,4 +696,54 @@ public class Algorithms {
|
|||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.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.SearchResultMatcher;
|
||||
import net.osmand.search.core.SearchPhrase;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.search.core.SearchSettings;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Assert;
|
||||
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 {
|
||||
|
||||
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
|
||||
public void testDuplicates() throws IOException {
|
||||
SearchSettings ss = new SearchSettings((SearchSettings)null);
|
||||
|
@ -100,4 +211,220 @@ public class SearchCoreUITest {
|
|||
rs.add(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
|
||||
*.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();
|
||||
}
|
||||
|
||||
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) {
|
||||
float centroidX = 0, centroidY = 0;
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ import android.support.annotation.NonNull;
|
|||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
|
@ -824,7 +823,7 @@ public class ExternalApiHelper {
|
|||
// test show gpx (data)
|
||||
uri = Uri.parse("osmand.api://show_gpx");
|
||||
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)));
|
||||
}
|
||||
|
||||
|
@ -836,7 +835,7 @@ public class ExternalApiHelper {
|
|||
// test navigate gpx (data)
|
||||
uri = Uri.parse("osmand.api://navigate_gpx?force=true");
|
||||
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)));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue