Fix build and improve examples
This commit is contained in:
parent
e47c1c63de
commit
549b813e2e
10 changed files with 185 additions and 126 deletions
|
@ -385,24 +385,27 @@ public class BinaryMapIndexReader {
|
|||
return file;
|
||||
}
|
||||
|
||||
private List<String> getCountryAndRegionNames() {
|
||||
return new ArrayList<>(Arrays.asList(getRegionNames().get(0).split("_")));
|
||||
}
|
||||
|
||||
public String getCountryName() {
|
||||
return getCountryAndRegionNames().get(0);
|
||||
List<String> rg = getRegionNames();
|
||||
if(rg.size() > 0) {
|
||||
return rg.get(0).split("_")[0];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getRegionName() {
|
||||
List<String> rg = getRegionNames();
|
||||
if (rg.size() == 0) {
|
||||
rg.add(file.getName());
|
||||
}
|
||||
String ls = rg.get(0);
|
||||
if (ls.lastIndexOf('_') != -1) {
|
||||
return ls.substring(0, ls.lastIndexOf('_')).replace('_', ' ');
|
||||
}
|
||||
return ls;
|
||||
}
|
||||
|
||||
private String getRegionName() {
|
||||
List<String> names = getCountryAndRegionNames();
|
||||
if (names.size() >= 2) {
|
||||
String region = names.get(1);
|
||||
region = region.substring(0, 1).toUpperCase() + region.substring(1);
|
||||
return region;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int readByte() throws IOException {
|
||||
byte b = codedIS.readRawByte();
|
||||
|
|
|
@ -38,6 +38,7 @@ public class GeocodingUtilities {
|
|||
private static final Log log = PlatformUtil.getLog(GeocodingUtilities.class);
|
||||
|
||||
// Location to test parameters http://www.openstreetmap.org/#map=18/53.896473/27.540071 (hno 44)
|
||||
// BUG http://www.openstreetmap.org/#map=19/50.9356/13.35348 (hno 26) street is
|
||||
public static final float THRESHOLD_MULTIPLIER_SKIP_STREETS_AFTER = 5;
|
||||
public static final float STOP_SEARCHING_STREET_WITH_MULTIPLIER_RADIUS = 250;
|
||||
public static final float STOP_SEARCHING_STREET_WITHOUT_MULTIPLIER_RADIUS = 400;
|
||||
|
|
|
@ -2,22 +2,55 @@ package net.osmand.search.example;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.StringMatcher;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.search.example.core.SearchPhrase;
|
||||
import net.osmand.search.example.core.SearchResult;
|
||||
|
||||
public class SearchUIAdapter {
|
||||
|
||||
SearchPhrase p;
|
||||
List<SearchResult> currentSearchResults = new ArrayList<>();
|
||||
private SearchPhrase phrase = new SearchPhrase(null);
|
||||
private List<SearchResult> currentSearchResults = new ArrayList<>();
|
||||
|
||||
private final BinaryMapIndexReader[] searchIndexes;
|
||||
|
||||
private ThreadPoolExecutor singleThreadedExecutor;
|
||||
private LinkedBlockingQueue<Runnable> taskQueue;
|
||||
private Runnable onResultsComplete = null;
|
||||
private AtomicInteger requestNumber = new AtomicInteger();
|
||||
|
||||
public SearchUIAdapter(BinaryMapIndexReader[] searchIndexes) {
|
||||
this.searchIndexes = searchIndexes;
|
||||
taskQueue = new LinkedBlockingQueue<Runnable>();
|
||||
singleThreadedExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,taskQueue);
|
||||
}
|
||||
|
||||
public List<SearchResult> getCurrentSearchResults() {
|
||||
return currentSearchResults;
|
||||
}
|
||||
|
||||
public void setOnResultsComplete(Runnable onResultsComplete) {
|
||||
this.onResultsComplete = onResultsComplete;
|
||||
}
|
||||
|
||||
public void setSearchLocation(LatLon l) {
|
||||
phrase = new SearchPhrase(l);
|
||||
}
|
||||
|
||||
public void updateSearchPhrase(SearchPhrase p) {
|
||||
boolean hasSameConstantWords = p.hasSameConstantWords(this.p);
|
||||
this.p = p;
|
||||
// TODO update logic
|
||||
boolean hasSameConstantWords = p.hasSameConstantWords(this.phrase);
|
||||
this.phrase = p;
|
||||
if(hasSameConstantWords) {
|
||||
filterCurrentResults(currentSearchResults);
|
||||
filterCurrentResults(phrase);
|
||||
}
|
||||
boolean lastWordLooksLikeURLOrNumber = true;
|
||||
if(lastWordLooksLikeURLOrNumber) {
|
||||
|
@ -27,70 +60,80 @@ public class SearchUIAdapter {
|
|||
boolean poiTypeWasNotSelected = true;
|
||||
if(poiTypeWasNotSelected) {
|
||||
// add search result poi filters
|
||||
sortCurrentSearchResults();
|
||||
sortSearchResults(currentSearchResults);
|
||||
}
|
||||
|
||||
asyncCallToSearchCoreAPI(
|
||||
// final result
|
||||
new ResultMatcher<List<SearchResult<?>>>() {
|
||||
|
||||
@Override
|
||||
public boolean publish(List<SearchResult<?>> object) {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}, // visitor
|
||||
new ResultMatcher<SearchResult<?>>() {
|
||||
|
||||
@Override
|
||||
public boolean publish(SearchResult<?> object) {
|
||||
if(filterOneResult(object)) {
|
||||
currentSearchResults.add(object);
|
||||
sortCurrentSearchResults();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void asyncCallToSearchCoreAPI(
|
||||
ResultMatcher<List<SearchResult<?>>> publisher,
|
||||
ResultMatcher<SearchResult<?>> visitor) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void filterCurrentResults(List<SearchResult> currentSearchResults2) {
|
||||
// Filter current results based on name filters from
|
||||
this.currentSearchResults = currentSearchResults;
|
||||
// use
|
||||
// filterOneResult(null);
|
||||
private List<SearchResult> filterCurrentResults(SearchPhrase phrase) {
|
||||
List<SearchResult> rr = new ArrayList<>();
|
||||
List<SearchResult> l = currentSearchResults;
|
||||
for(SearchResult r : l) {
|
||||
if(filterOneResult(r, phrase)) {
|
||||
rr.add(r);
|
||||
}
|
||||
}
|
||||
return rr;
|
||||
}
|
||||
|
||||
private boolean filterOneResult(SearchResult object) {
|
||||
// TODO Auto-generated method stub
|
||||
return true;
|
||||
private boolean filterOneResult(SearchResult object, SearchPhrase phrase) {
|
||||
StringMatcher nameStringMatcher = phrase.getNameStringMatcher();
|
||||
if(phrase.getLastWord().length() <= 2 && phrase.isNoSelectedType()) {
|
||||
return true;
|
||||
}
|
||||
return nameStringMatcher.matches(object.mainName);
|
||||
}
|
||||
|
||||
public List<SearchResult> search(final String text) {
|
||||
List<SearchResult> list = new ArrayList<>();
|
||||
final int request = requestNumber.incrementAndGet();
|
||||
final SearchPhrase phrase = this.phrase.generateNewPhrase(text);
|
||||
this.phrase = phrase;
|
||||
list.addAll(filterCurrentResults(phrase));
|
||||
System.out.println("> Search phrase " + phrase + " " + list.size());
|
||||
singleThreadedExecutor.getQueue().drainTo(new ArrayList<>());
|
||||
singleThreadedExecutor.submit(new Runnable() {
|
||||
|
||||
private void sortCurrentSearchResults() {
|
||||
// sort SearchResult by 1. searchDistance 2. Name
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
List<SearchResult> rs = new ArrayList<>();
|
||||
for (BinaryMapIndexReader bmir : searchIndexes) {
|
||||
if (bmir.getRegionCenter() != null) {
|
||||
SearchResult sr = new SearchResult();
|
||||
sr.mainName = bmir.getRegionName();
|
||||
sr.location = bmir.getRegionCenter();
|
||||
sr.preferredZoom = 6;
|
||||
if(filterOneResult(sr, phrase)) {
|
||||
rs.add(sr);
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean cancelled = request != requestNumber.get();
|
||||
if (!cancelled) {
|
||||
sortSearchResults(rs);
|
||||
System.out.println(">> Search phrase " + phrase + " " + rs.size());
|
||||
currentSearchResults = rs;
|
||||
if (onResultsComplete != null) {
|
||||
onResultsComplete.run();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
private void sortSearchResults(List<SearchResult> searchResults) {
|
||||
// sort SearchResult by 1. searchDistance 2. Name
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package net.osmand.search.example.core;
|
|||
public enum ObjectType {
|
||||
CITY(true), VILLAGE(true), POSTCODE(true), STREET(true), HOUSE(true),
|
||||
POI_TYPE(false), POI(true), LOCATION(true), FAVORITE(true),
|
||||
RECENT_OBJ(true), WPT(true), NAME_FILTER(false);
|
||||
RECENT_OBJ(true), WPT(true), UNKNOWN_NAME_FILTER(false);
|
||||
private boolean hasLocation;
|
||||
private ObjectType(boolean location) {
|
||||
this.hasLocation = location;
|
||||
|
|
|
@ -180,8 +180,8 @@ public class SearchCore {
|
|||
|
||||
private void callToSearchCoreAPI(
|
||||
SearchPhrase p,
|
||||
ResultMatcher<List<SearchResult<?>>> publisher,
|
||||
ResultMatcher<SearchResult<?>> visitor) {
|
||||
ResultMatcher<List<SearchResult>> publisher,
|
||||
ResultMatcher<SearchResult> visitor) {
|
||||
// sort apis by prioirity to search phrase
|
||||
// call apis in for loop
|
||||
}
|
||||
|
|
|
@ -11,20 +11,49 @@ import net.osmand.data.LatLon;
|
|||
public class SearchPhrase {
|
||||
|
||||
private List<SearchWord> words = new ArrayList<>();
|
||||
private LatLon originalPhraseLocation;
|
||||
private LatLon originalLocation;
|
||||
private String text = "";
|
||||
private String lastWord = "";
|
||||
private CollatorStringMatcher sm;
|
||||
|
||||
public SearchPhrase(LatLon location) {
|
||||
this.originalPhraseLocation = location;
|
||||
this.originalLocation = location;
|
||||
}
|
||||
|
||||
public List<SearchWord> getWords() {
|
||||
return words;
|
||||
}
|
||||
|
||||
public SearchPhrase generateNewPhrase(String text) {
|
||||
SearchPhrase sp = new SearchPhrase(originalLocation);
|
||||
String atext = text;
|
||||
if (text.startsWith((this.text + this.lastWord).trim())) {
|
||||
// string is longer
|
||||
atext = text.substring(this.text.length());
|
||||
sp.text = this.text;
|
||||
sp.words = new ArrayList<>(this.words);
|
||||
} else {
|
||||
sp.text = "";
|
||||
}
|
||||
// TODO Reuse previous search words if it is shorter
|
||||
if (!atext.contains(",")) {
|
||||
sp.lastWord = atext;
|
||||
} else {
|
||||
String[] ws = atext.split(",");
|
||||
for (int i = 0; i < ws.length - 1; i++) {
|
||||
if (ws[i].trim().length() > 0) {
|
||||
sp.words.add(new SearchWord(ws[i].trim()));
|
||||
}
|
||||
sp.text += ws[i] + ",";
|
||||
}
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
public List<SearchWord> excludefilterWords() {
|
||||
List<SearchWord> w = new ArrayList<>();
|
||||
for(SearchWord s : words) {
|
||||
if(s.getType() != ObjectType.NAME_FILTER) {
|
||||
if(s.getResult() == null) {
|
||||
w.add(s);
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +65,7 @@ public class SearchPhrase {
|
|||
SearchWord sw = words.get(i);
|
||||
if(sw.getType() == ObjectType.POI) {
|
||||
return true;
|
||||
} else if(sw.getType() != ObjectType.NAME_FILTER) {
|
||||
} else if(sw.getType() != ObjectType.UNKNOWN_NAME_FILTER) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -44,8 +73,11 @@ public class SearchPhrase {
|
|||
}
|
||||
|
||||
public StringMatcher getNameStringMatcher() {
|
||||
// TODO
|
||||
return new CollatorStringMatcher("NameFitler", StringMatcherMode.CHECK_STARTS_FROM_SPACE);
|
||||
if(sm != null) {
|
||||
return sm;
|
||||
}
|
||||
sm = new CollatorStringMatcher(lastWord, StringMatcherMode.CHECK_STARTS_FROM_SPACE);
|
||||
return sm;
|
||||
}
|
||||
|
||||
public boolean hasSameConstantWords(SearchPhrase p) {
|
||||
|
@ -55,8 +87,9 @@ public class SearchPhrase {
|
|||
public String getStringRerpresentation() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(SearchWord s : words) {
|
||||
sb.append(s).append(", ");
|
||||
sb.append(s.getWord()).append(", ");
|
||||
}
|
||||
sb.append(lastWord);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
@ -66,11 +99,16 @@ public class SearchPhrase {
|
|||
}
|
||||
|
||||
public boolean isNoSelectedType() {
|
||||
return true;
|
||||
return words.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return words.isEmpty();
|
||||
return words.isEmpty() && lastWord.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
public String getLastWord() {
|
||||
return lastWord;
|
||||
}
|
||||
|
||||
public LatLon getLastTokenLocation() {
|
||||
|
@ -81,7 +119,9 @@ public class SearchPhrase {
|
|||
}
|
||||
}
|
||||
// last token or myLocationOrVisibleMap if not selected
|
||||
return originalPhraseLocation;
|
||||
return originalLocation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,15 +2,16 @@ package net.osmand.search.example.core;
|
|||
|
||||
import net.osmand.data.LatLon;
|
||||
|
||||
public class SearchResult<T> {
|
||||
public class SearchResult {
|
||||
|
||||
public T object;
|
||||
public Object object;
|
||||
public ObjectType objectType;
|
||||
|
||||
// calculated by formula priority - 1 / (1 + priorityDistance * distance)
|
||||
public double searchDistance;
|
||||
|
||||
public LatLon location;
|
||||
public int preferredZoom = 15;
|
||||
public String mainName;
|
||||
// search phrase that makes search result valid
|
||||
public SearchPhrase requiredSearchPhrase;
|
||||
|
|
|
@ -4,54 +4,29 @@ import net.osmand.data.LatLon;
|
|||
|
||||
public class SearchWord {
|
||||
private String word;
|
||||
private ObjectType type;
|
||||
private Object internalObject;
|
||||
private SearchResult result;
|
||||
private LatLon location;
|
||||
|
||||
public SearchWord(String word) {
|
||||
this.word = word;
|
||||
}
|
||||
|
||||
public ObjectType getType() {
|
||||
return type;
|
||||
return result == null ? ObjectType.UNKNOWN_NAME_FILTER : result.objectType;
|
||||
}
|
||||
|
||||
public String getWord() {
|
||||
return word;
|
||||
}
|
||||
|
||||
public Object getInternalObject() {
|
||||
return internalObject;
|
||||
public SearchResult getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public LatLon getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((word == null) ? 0 : word.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
SearchWord other = (SearchWord) obj;
|
||||
if (type != other.type)
|
||||
return false;
|
||||
if (word == null) {
|
||||
if (other.word != null)
|
||||
return false;
|
||||
} else if (!word.equals(other.word))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return word;
|
||||
|
|
|
@ -75,7 +75,7 @@ public class RouteTestingTest {
|
|||
|
||||
@Test
|
||||
public void testRouting() throws Exception {
|
||||
String fl = "../../resources/test-resources/Turn_lanes_test.obf";
|
||||
String fl = "../../resources/test-resources/Routing_test.obf";
|
||||
RandomAccessFile raf = new RandomAccessFile(fl, "r");
|
||||
RoutePlannerFrontEnd fe = new RoutePlannerFrontEnd(false);
|
||||
|
||||
|
|
|
@ -2175,11 +2175,7 @@ Für Hilfe mit der OsmAnd-App kontaktieren Sie bitte unser Support-Team unter su
|
|||
<string name="app_mode_train">Zug</string>
|
||||
<string name="coords_format">Koordinatenformat</string>
|
||||
<string name="coords_format_descr">Format der geographischen Koordinaten</string>
|
||||
<<<<<<< HEAD
|
||||
<string name="shared_string_is_open_24_7">Offen 7x24h</string>
|
||||
</resources>
|
||||
=======
|
||||
<string name="storage_directory_card">Speicherkarte</string>
|
||||
<string name="shared_string_open">Öffnen</string>
|
||||
</resources>
|
||||
>>>>>>> weblate/master
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue