implement search intersected street

git-svn-id: https://osmand.googlecode.com/svn/trunk@114 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-06-02 07:25:06 +00:00
parent 12f5d23bc1
commit 85d16a6bf9
14 changed files with 260 additions and 18 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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));
}
}

View file

@ -4,6 +4,7 @@ public class OSMSettings {
public enum OSMTagKey {
NAME("name"),
NAME_EN("name:en"),
// ways
HIGHWAY("highway"),
BUILDING("building"),

View file

@ -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;

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -191,6 +191,11 @@ public class OsmandSettings {
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
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();
}
}

View file

@ -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",

View file

@ -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);
}
});

View file

@ -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) {
startActivity(new Intent(SearchAddressActivity.this, SearchBuildingByNameActivity.class));
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,8 +240,14 @@ public class SearchAddressActivity extends Activity {
if (city != null) {
street = region.getStreetByName(city, OsmandSettings.getLastSearchedStreet(SearchAddressActivity.this));
if (street != null) {
building = region.getBuildingByName(street, OsmandSettings
.getLastSearchedBuilding(SearchAddressActivity.this));
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));
}
}
}
}

View file

@ -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();
}
}