implement search intersected street
git-svn-id: https://osmand.googlecode.com/svn/trunk@114 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
12f5d23bc1
commit
85d16a6bf9
14 changed files with 260 additions and 18 deletions
|
@ -17,11 +17,9 @@ public class ToDoConstants {
|
|||
// 29. Show opened/closed amenities (in search poi).
|
||||
// 13. Save point as favorite & introduce favorite points dialog
|
||||
|
||||
|
||||
// 3. Revise osmand UI. Preparing new icons (revise UI 18, 2, ). Main application icon, back to location icon.
|
||||
// 14. Show zoom level on map
|
||||
|
||||
// 27. Search intersection of streets (+)
|
||||
|
||||
// NOT in release 0.1
|
||||
// 8. Enable change POI directly on map (requires OSM login)
|
||||
|
@ -32,6 +30,7 @@ public class ToDoConstants {
|
|||
|
||||
|
||||
// FIXME Bugs Android :
|
||||
// Investigate good transliterate
|
||||
// 6. Understand concept of application where to save/restore global setting.
|
||||
// (for example reset navigate to point, reset link map with location). It should be reset after user call exit.
|
||||
// Call ResourceManager.close when it is needed.
|
||||
|
@ -52,6 +51,7 @@ public class ToDoConstants {
|
|||
|
||||
|
||||
// DONE ANDROID :
|
||||
// 27. Search intersection of streets
|
||||
// 24. Implement ResourceManager, load cities/streets/buildings on Low memory (clear previous all addresses cities).
|
||||
// 28. Implement transliteration search for android version
|
||||
// 5. Search for city/streets/buildings
|
||||
|
|
|
@ -26,6 +26,9 @@ public abstract class MapObject implements Comparable<MapObject> {
|
|||
if(this.name == null){
|
||||
this.name = e.getTag(OSMTagKey.NAME);
|
||||
}
|
||||
if(this.enName == null){
|
||||
this.enName = e.getTag(OSMTagKey.NAME_EN);
|
||||
}
|
||||
if(this.location == null){
|
||||
this.location = MapUtils.getCenter(e);
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@ public class IndexConstants {
|
|||
}
|
||||
|
||||
public enum IndexStreetNodeTable implements IndexColumn {
|
||||
ID("long"), LATITUDE("double"), LONGITUDE("double"), STREET("long", true), WAY("long", true);
|
||||
ID("long", true), LATITUDE("double"), LONGITUDE("double"), STREET("long", true), WAY("long", true);
|
||||
boolean index = false;
|
||||
String type = null;
|
||||
|
||||
|
|
|
@ -329,7 +329,7 @@ public class DataExtraction {
|
|||
|
||||
private void convertEnglishName(MapObject o, Transliterator transliterator){
|
||||
String name = o.getName();
|
||||
if(name != null){
|
||||
if(name != null && o.getEnName() == null){
|
||||
o.setEnName(transliterator.transliterate(name));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ public class OSMSettings {
|
|||
|
||||
public enum OSMTagKey {
|
||||
NAME("name"),
|
||||
NAME_EN("name:en"),
|
||||
// ways
|
||||
HIGHWAY("highway"),
|
||||
BUILDING("building"),
|
||||
|
|
|
@ -22,6 +22,17 @@ public class Way extends Entity {
|
|||
nodeIds.add(id);
|
||||
}
|
||||
|
||||
public void addNode(Node n){
|
||||
if(nodeIds == null){
|
||||
nodeIds = new ArrayList<Long>();
|
||||
}
|
||||
if(nodes == null){
|
||||
nodes = new ArrayList<Node>();
|
||||
}
|
||||
nodeIds.add(n.getId());
|
||||
nodes.add(n);
|
||||
}
|
||||
|
||||
public Long removeNodeByIndex(int i){
|
||||
if(nodeIds == null){
|
||||
return null;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<activity android:name=".activities.search.SearchCityByNameActivity"></activity>
|
||||
<activity android:name=".activities.search.SearchRegionByNameActivity"></activity>
|
||||
<activity android:name=".activities.search.SearchStreetByNameActivity"></activity>
|
||||
<activity android:name=".activities.search.SearchStreet2ByNameActivity"></activity>
|
||||
<activity android:name=".activities.search.SearchBuildingByNameActivity"></activity>
|
||||
|
||||
</application>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
</ImageButton>
|
||||
</TableRow>
|
||||
<TableRow android:id="@+id/TableRow" android:layout_marginLeft = "5dp">
|
||||
<TextView android:text="Bulding" android:id="@+id/TextView">
|
||||
<TextView android:text="Bulding" android:id="@+id/BuildingText">
|
||||
</TextView>
|
||||
<Button android:id="@+id/BuildingButton" android:text="@string/choose_building">
|
||||
</Button>
|
||||
|
@ -43,7 +43,7 @@
|
|||
</ImageButton>
|
||||
</TableRow>
|
||||
<TableRow android:id="@+id/TableRow" android:layout_marginLeft = "5dp" >
|
||||
<RadioGroup android:orientation="horizontal" android:layout_span="3">
|
||||
<RadioGroup android:orientation="horizontal" android:layout_span="3" android:id="@+id/RadioGroup" >
|
||||
<RadioButton android:text="Building" android:id="@+id/RadioBuilding" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton>
|
||||
<RadioButton android:text="Intersected street" android:id="@+id/RadioIntersStreet" android:layout_width="wrap_content" android:layout_marginLeft = "5dp" android:layout_height="wrap_content"></RadioButton>
|
||||
|
||||
|
|
|
@ -38,13 +38,14 @@
|
|||
<string name="settings_Button">Settings</string>
|
||||
<string name="search_button">Search</string>
|
||||
<color name="menu_background">#CFFACD</color>
|
||||
<string name="search_activity">search</string>
|
||||
<string name="search_activity">Search</string>
|
||||
<color name="color_white">#FFFFFF</color>
|
||||
<color name="color_red">#FF0000</color>
|
||||
<string name="searchpoi_activity">searchpoi_activity</string>
|
||||
<string name="searchpoi_activity">Choose poi</string>
|
||||
<string name="search_POI_level_btn">Find more</string>
|
||||
<string name="incremental_search_city">Search city incrementally. In order to find villages input more than 3 first symbols.</string>
|
||||
<string name="incremental_search_street">Search street incrementally</string>
|
||||
<string name="incremental_search_building">Search building incrementally</string>
|
||||
<string name="choose_available_region">Choose region</string>
|
||||
<string name="choose_intersected_street">Choose intersected street</string>
|
||||
</resources>
|
||||
|
|
|
@ -192,5 +192,10 @@ public class OsmandSettings {
|
|||
return prefs.edit().putString(LAST_SEARCHED_INTERSECTED_STREET, street).commit();
|
||||
}
|
||||
|
||||
public static boolean removeLastSearchedIntersectedStreet(Context ctx){
|
||||
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
||||
return prefs.edit().remove(LAST_SEARCHED_INTERSECTED_STREET).commit();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import java.util.HashMap;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -23,7 +25,10 @@ import com.osmand.data.City.CityType;
|
|||
import com.osmand.data.index.IndexConstants;
|
||||
import com.osmand.data.index.IndexConstants.IndexBuildingTable;
|
||||
import com.osmand.data.index.IndexConstants.IndexCityTable;
|
||||
import com.osmand.data.index.IndexConstants.IndexStreetNodeTable;
|
||||
import com.osmand.data.index.IndexConstants.IndexStreetTable;
|
||||
import com.osmand.osm.Node;
|
||||
import com.osmand.osm.Way;
|
||||
|
||||
|
||||
public class RegionAddressRepository {
|
||||
|
@ -143,6 +148,31 @@ public class RegionAddressRepository {
|
|||
}
|
||||
}
|
||||
|
||||
public void fillWithSuggestedStreetsIntersectStreets(City city, Street st, List<Street> streetsToFill) {
|
||||
if (st != null) {
|
||||
Set<Long> strIds = new TreeSet<Long>();
|
||||
log.debug("Start loading instersection streets for " + city.getName());
|
||||
Cursor query = db.rawQuery("SELECT B.STREET FROM street_node A JOIN street_node B ON A.ID = B.ID WHERE A.STREET = ?",
|
||||
new String[] { st.getId() + "" });
|
||||
if (query.moveToFirst()) {
|
||||
do {
|
||||
if (st.getId() != query.getLong(0)) {
|
||||
strIds.add(query.getLong(0));
|
||||
}
|
||||
} while (query.moveToNext());
|
||||
}
|
||||
query.close();
|
||||
for (Street s : city.getStreets()) {
|
||||
if (strIds.contains(s.getId())) {
|
||||
streetsToFill.add(s);
|
||||
}
|
||||
}
|
||||
log.debug("Loaded " + strIds.size() + " streets");
|
||||
preloadWayNodes(st);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void fillWithSuggestedStreets(City c, String name, List<Street> streetsToFill){
|
||||
preloadStreets(c);
|
||||
name = name.toLowerCase();
|
||||
|
@ -220,6 +250,33 @@ public class RegionAddressRepository {
|
|||
}
|
||||
}
|
||||
|
||||
public void preloadWayNodes(Street street){
|
||||
if(street.getWayNodes().isEmpty()){
|
||||
Cursor query = db.query(IndexStreetNodeTable.getTable(), IndexConstants.generateColumnNames(IndexStreetNodeTable.values()), "? = street",
|
||||
new String[] { street.getId() + "" }, null, null, null);
|
||||
log.debug("Start loading waynodes for " + street.getName());
|
||||
Map<Long, Way> ways = new LinkedHashMap<Long, Way>();
|
||||
if (query.moveToFirst()) {
|
||||
do {
|
||||
Node n = new Node(query.getDouble(IndexStreetNodeTable.LATITUDE.ordinal()),
|
||||
query.getDouble(IndexBuildingTable.LONGITUDE.ordinal()),
|
||||
query.getLong(IndexStreetNodeTable.ID.ordinal()));
|
||||
long way = query.getLong(IndexStreetNodeTable.WAY.ordinal());
|
||||
if(!ways.containsKey(way)){
|
||||
ways.put(way, new Way(way));
|
||||
}
|
||||
ways.get(way).addNode(n);
|
||||
} while (query.moveToNext());
|
||||
}
|
||||
query.close();
|
||||
for(Way w : ways.values()){
|
||||
street.getWayNodes().add(w);
|
||||
}
|
||||
log.debug("Loaded " + ways.size() + " ways");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void preloadBuildings(Street street){
|
||||
if (street.getBuildings().isEmpty()) {
|
||||
Cursor query = db.query(IndexBuildingTable.getTable(), IndexConstants.generateColumnNames(IndexBuildingTable.values()), "? = street",
|
||||
|
|
|
@ -139,7 +139,6 @@ public class MainMenuActivity extends Activity {
|
|||
public void onClick(View v) {
|
||||
mNotificationManager.cancel(APP_NOTIFICATION_ID);
|
||||
MainMenuActivity.this.finish();
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ import android.os.Bundle;
|
|||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.widget.Button;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.osmand.OsmandSettings;
|
||||
import com.osmand.R;
|
||||
|
@ -18,6 +21,8 @@ import com.osmand.data.Building;
|
|||
import com.osmand.data.City;
|
||||
import com.osmand.data.Street;
|
||||
import com.osmand.osm.LatLon;
|
||||
import com.osmand.osm.Node;
|
||||
import com.osmand.osm.Way;
|
||||
|
||||
public class SearchAddressActivity extends Activity {
|
||||
|
||||
|
@ -31,6 +36,8 @@ public class SearchAddressActivity extends Activity {
|
|||
private City city = null;
|
||||
private Street street = null;
|
||||
private Building building = null;
|
||||
private Street street2 = null;
|
||||
private boolean radioBuilding = true;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -68,7 +75,13 @@ public class SearchAddressActivity extends Activity {
|
|||
buildingButton.setOnClickListener(new View.OnClickListener(){
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(radioBuilding){
|
||||
OsmandSettings.removeLastSearchedIntersectedStreet(SearchAddressActivity.this);
|
||||
startActivity(new Intent(SearchAddressActivity.this, SearchBuildingByNameActivity.class));
|
||||
} else {
|
||||
OsmandSettings.setLastSearchedIntersectedStreet(SearchAddressActivity.this, "");
|
||||
startActivity(new Intent(SearchAddressActivity.this, SearchStreet2ByNameActivity.class));
|
||||
}
|
||||
}
|
||||
});
|
||||
showOnMap.setOnClickListener(new View.OnClickListener() {
|
||||
|
@ -76,7 +89,27 @@ public class SearchAddressActivity extends Activity {
|
|||
public void onClick(View v) {
|
||||
LatLon l = null;
|
||||
int zoom = 12;
|
||||
if (building != null) {
|
||||
if (street2 != null && street != null) {
|
||||
region.preloadWayNodes(street2);
|
||||
region.preloadWayNodes(street);
|
||||
Node inters = null;
|
||||
for(Way w : street2.getWayNodes()){
|
||||
for(Way w2 : street.getWayNodes()){
|
||||
for(Node n : w.getNodes()){
|
||||
for(Node n2 : w2.getNodes()){
|
||||
if(n.getId() == n2.getId()){
|
||||
inters = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(inters != null){
|
||||
l = inters.getLatLon();
|
||||
zoom = 16;
|
||||
}
|
||||
} else if (building != null) {
|
||||
l = building.getLocation();
|
||||
zoom = 16;
|
||||
} else if (street != null) {
|
||||
|
@ -128,7 +161,39 @@ public class SearchAddressActivity extends Activity {
|
|||
updateUI();
|
||||
}
|
||||
});
|
||||
((RadioGroup)findViewById(R.id.RadioGroup)).setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup group, int checkedId) {
|
||||
SearchAddressActivity.this.radioBuilding = checkedId == R.id.RadioBuilding;
|
||||
if(radioBuilding){
|
||||
SearchAddressActivity.this.street2 = null;
|
||||
} else {
|
||||
SearchAddressActivity.this.building = null;
|
||||
}
|
||||
updateBuildingSection();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected void updateBuildingSection(){
|
||||
if(radioBuilding){
|
||||
((TextView)findViewById(R.id.BuildingText)).setText("Building");
|
||||
if(building == null){
|
||||
((TextView)findViewById(R.id.BuildingButton)).setText(R.string.choose_building);
|
||||
} else {
|
||||
((TextView)findViewById(R.id.BuildingButton)).setText(building.getName(region.useEnglishNames()));
|
||||
}
|
||||
} else {
|
||||
((TextView)findViewById(R.id.BuildingText)).setText("Street 2");
|
||||
if(street2 == null){
|
||||
((TextView)findViewById(R.id.BuildingButton)).setText(R.string.choose_intersected_street);
|
||||
} else {
|
||||
((TextView)findViewById(R.id.BuildingButton)).setText(street2.getName(region.useEnglishNames()));
|
||||
}
|
||||
}
|
||||
findViewById(R.id.ResetBuilding).setEnabled(building != null || street2 != null);
|
||||
}
|
||||
|
||||
protected void updateUI(){
|
||||
|
@ -154,13 +219,15 @@ public class SearchAddressActivity extends Activity {
|
|||
}
|
||||
streetButton.setEnabled(city != null);
|
||||
|
||||
findViewById(R.id.ResetBuilding).setEnabled(building != null);
|
||||
if(building == null){
|
||||
buildingButton.setText(R.string.choose_building);
|
||||
if(radioBuilding){
|
||||
((RadioButton)findViewById(R.id.RadioBuilding)).setChecked(true);
|
||||
} else {
|
||||
buildingButton.setText(building.getName(region.useEnglishNames()));
|
||||
((RadioButton)findViewById(R.id.RadioIntersStreet)).setChecked(true);
|
||||
}
|
||||
updateBuildingSection();
|
||||
|
||||
buildingButton.setEnabled(street != null);
|
||||
|
||||
showOnMap.setEnabled(building != null || city != null || street != null);
|
||||
}
|
||||
|
||||
|
@ -173,12 +240,18 @@ public class SearchAddressActivity extends Activity {
|
|||
if (city != null) {
|
||||
street = region.getStreetByName(city, OsmandSettings.getLastSearchedStreet(SearchAddressActivity.this));
|
||||
if (street != null) {
|
||||
String str = OsmandSettings.getLastSearchedIntersectedStreet(SearchAddressActivity.this);
|
||||
radioBuilding = str == null;
|
||||
if(str != null){
|
||||
street2 = region.getStreetByName(city, str);
|
||||
} else {
|
||||
building = region.getBuildingByName(street, OsmandSettings
|
||||
.getLastSearchedBuilding(SearchAddressActivity.this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void startLoadDataInThread(String progressMsg){
|
||||
final ProgressDialog dlg = ProgressDialog.show(this, "Loading", progressMsg, true);
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package com.osmand.activities.search;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.osmand.OsmandSettings;
|
||||
import com.osmand.R;
|
||||
import com.osmand.RegionAddressRepository;
|
||||
import com.osmand.ResourceManager;
|
||||
import com.osmand.data.City;
|
||||
import com.osmand.data.Street;
|
||||
|
||||
public class SearchStreet2ByNameActivity extends SearchByNameAbstractActivity<Street> {
|
||||
private RegionAddressRepository region;
|
||||
private City city;
|
||||
private Street street1;
|
||||
volatile private List<Street> initialList = new ArrayList<Street>();
|
||||
private List<Street> filterList = new ArrayList<Street>();
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
region = ResourceManager.getResourceManager().getRegionRepository(OsmandSettings.getLastSearchedRegion(this));
|
||||
if(region != null){
|
||||
city = region.getCityById(OsmandSettings.getLastSearchedCity(this));
|
||||
if(city != null){
|
||||
street1 = region.getStreetByName(city, (OsmandSettings.getLastSearchedStreet(this)));
|
||||
startLoadDataInThread("Finding streets...");
|
||||
}
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
((TextView)findViewById(R.id.Label)).setText(R.string.incremental_search_street);
|
||||
}
|
||||
|
||||
|
||||
protected void startLoadDataInThread(String progressMsg){
|
||||
final ProgressDialog dlg = ProgressDialog.show(this, "Loading", progressMsg, true);
|
||||
new Thread("Loader search data") {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
List<Street> t = new ArrayList<Street>();
|
||||
region.fillWithSuggestedStreetsIntersectStreets(city, street1, t);
|
||||
initialList = t;
|
||||
} finally {
|
||||
dlg.dismiss();
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setText(getFilter().toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
@Override
|
||||
public List<Street> getObjects(String filter) {
|
||||
int ind = 0;
|
||||
filter = filter.toLowerCase();
|
||||
if(filter.length() == 0){
|
||||
return initialList;
|
||||
}
|
||||
filterList.clear();
|
||||
for (Street s : initialList) {
|
||||
String lowerCase = s.getName(region.useEnglishNames()).toLowerCase();
|
||||
if (lowerCase.startsWith(filter)) {
|
||||
filterList.add(ind, s);
|
||||
ind++;
|
||||
} else if (lowerCase.contains(filter)) {
|
||||
filterList.add(s);
|
||||
}
|
||||
}
|
||||
return filterList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTextView(Street obj, TextView txt) {
|
||||
txt.setText(obj.getName(region.useEnglishNames()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemSelected(Street obj) {
|
||||
OsmandSettings.setLastSearchedIntersectedStreet(this, obj.getName(region.useEnglishNames()));
|
||||
finish();
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue