Add postcode search
git-svn-id: https://osmand.googlecode.com/svn/trunk@165 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
d9286a9c71
commit
42426f041f
8 changed files with 110 additions and 9 deletions
|
@ -1,13 +1,26 @@
|
||||||
package com.osmand.data;
|
package com.osmand.data;
|
||||||
|
|
||||||
import com.osmand.osm.Entity;
|
import com.osmand.osm.Entity;
|
||||||
|
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
|
|
||||||
public class Building extends MapObject {
|
public class Building extends MapObject {
|
||||||
|
|
||||||
|
private String postcode;
|
||||||
|
|
||||||
public Building(Entity e){
|
public Building(Entity e){
|
||||||
super(e);
|
super(e);
|
||||||
|
// try to extract postcode
|
||||||
|
postcode = e.getTag(OSMTagKey.ADDR_POSTCODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Building(){}
|
public Building(){}
|
||||||
|
|
||||||
|
public String getPostcode() {
|
||||||
|
return postcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPostcode(String postcode) {
|
||||||
|
this.postcode = postcode;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@ package com.osmand.data;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.SortedSet;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import com.osmand.Algoritms;
|
import com.osmand.Algoritms;
|
||||||
import com.osmand.osm.Entity;
|
import com.osmand.osm.Entity;
|
||||||
|
@ -46,6 +48,7 @@ public class City extends MapObject {
|
||||||
private CityType type = null;
|
private CityType type = null;
|
||||||
// Be attentive ! Working with street names ignoring case
|
// Be attentive ! Working with street names ignoring case
|
||||||
private Map<String, Street> streets = new TreeMap<String, Street>(Collator.getInstance());
|
private Map<String, Street> streets = new TreeMap<String, Street>(Collator.getInstance());
|
||||||
|
private SortedSet<String> postcodes = new TreeSet<String>();
|
||||||
|
|
||||||
public City(Node el){
|
public City(Node el){
|
||||||
super(el);
|
super(el);
|
||||||
|
@ -100,7 +103,10 @@ public class City extends MapObject {
|
||||||
String number = e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER);
|
String number = e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER);
|
||||||
String street = e.getTag(OSMTagKey.ADDR_STREET);
|
String street = e.getTag(OSMTagKey.ADDR_STREET);
|
||||||
if( street != null && number != null){
|
if( street != null && number != null){
|
||||||
registerStreet(street).registerBuilding(e);
|
Building building = registerStreet(street).registerBuilding(e);
|
||||||
|
if (building.getPostcode() != null) {
|
||||||
|
postcodes.add(building.getPostcode());
|
||||||
|
}
|
||||||
return streets.get(street.toLowerCase());
|
return streets.get(street.toLowerCase());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -110,6 +116,10 @@ public class City extends MapObject {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SortedSet<String> getPostcodes() {
|
||||||
|
return postcodes;
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<Street> getStreets(){
|
public Collection<Street> getStreets(){
|
||||||
return streets.values();
|
return streets.values();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.osmand.data;
|
||||||
|
|
||||||
|
public class PostcodeBasedStreet extends Street {
|
||||||
|
|
||||||
|
public PostcodeBasedStreet(City city, String postcode) {
|
||||||
|
super(city, postcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getId() {
|
||||||
|
return -1l;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,10 +28,11 @@ public class Street extends MapObject {
|
||||||
this.city = city;
|
this.city = city;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerBuilding(Entity e){
|
public Building registerBuilding(Entity e){
|
||||||
Building building = new Building(e);
|
Building building = new Building(e);
|
||||||
building.setName(e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER));
|
building.setName(e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER));
|
||||||
buildings.add(building);
|
buildings.add(building);
|
||||||
|
return building;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerBuilding(Building building){
|
public void registerBuilding(Building building){
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class DataIndexWriter {
|
||||||
PreparedStatement prepStreet = conn.prepareStatement(
|
PreparedStatement prepStreet = conn.prepareStatement(
|
||||||
IndexConstants.generatePrepareStatementToInsert(IndexStreetTable.getTable(), 6));
|
IndexConstants.generatePrepareStatementToInsert(IndexStreetTable.getTable(), 6));
|
||||||
PreparedStatement prepBuilding = conn.prepareStatement(
|
PreparedStatement prepBuilding = conn.prepareStatement(
|
||||||
IndexConstants.generatePrepareStatementToInsert(IndexBuildingTable.getTable(), 6));
|
IndexConstants.generatePrepareStatementToInsert(IndexBuildingTable.getTable(), 7));
|
||||||
PreparedStatement prepStreetNode = conn.prepareStatement(
|
PreparedStatement prepStreetNode = conn.prepareStatement(
|
||||||
IndexConstants.generatePrepareStatementToInsert(IndexStreetNodeTable.getTable(), 5));
|
IndexConstants.generatePrepareStatementToInsert(IndexStreetNodeTable.getTable(), 5));
|
||||||
Map<PreparedStatement, Integer> count = new HashMap<PreparedStatement, Integer>();
|
Map<PreparedStatement, Integer> count = new HashMap<PreparedStatement, Integer>();
|
||||||
|
@ -199,6 +199,8 @@ public class DataIndexWriter {
|
||||||
prepBuilding.setString(IndexBuildingTable.NAME.ordinal() + 1, building.getName());
|
prepBuilding.setString(IndexBuildingTable.NAME.ordinal() + 1, building.getName());
|
||||||
prepBuilding.setString(IndexBuildingTable.NAME_EN.ordinal() + 1, building.getEnName());
|
prepBuilding.setString(IndexBuildingTable.NAME_EN.ordinal() + 1, building.getEnName());
|
||||||
prepBuilding.setLong(IndexBuildingTable.STREET.ordinal() + 1, street.getId());
|
prepBuilding.setLong(IndexBuildingTable.STREET.ordinal() + 1, street.getId());
|
||||||
|
prepBuilding.setString(IndexBuildingTable.POSTCODE.ordinal()+1, building.getPostcode() == null ? null : building.getPostcode().toUpperCase());
|
||||||
|
|
||||||
addBatch(count, prepBuilding);
|
addBatch(count, prepBuilding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,7 @@ public class IndexConstants {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum IndexBuildingTable implements IndexColumn {
|
public enum IndexBuildingTable implements IndexColumn {
|
||||||
ID("long"), LATITUDE("double"), LONGITUDE("double"), NAME, NAME_EN, STREET("long", true);
|
ID("long"), LATITUDE("double"), LONGITUDE("double"), NAME, NAME_EN, STREET("long", true), POSTCODE;
|
||||||
boolean index = false;
|
boolean index = false;
|
||||||
String type = null;
|
String type = null;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ public class OSMSettings {
|
||||||
PLACE("place"),
|
PLACE("place"),
|
||||||
ADDR_HOUSE_NUMBER("addr:housenumber"),
|
ADDR_HOUSE_NUMBER("addr:housenumber"),
|
||||||
ADDR_STREET("addr:street"),
|
ADDR_STREET("addr:street"),
|
||||||
|
ADDR_POSTCODE("addr:postcode"),
|
||||||
|
|
||||||
// POI
|
// POI
|
||||||
AMENITY("amenity"),
|
AMENITY("amenity"),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.osmand;
|
package com.osmand;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -19,6 +20,7 @@ import android.database.sqlite.SQLiteDatabase;
|
||||||
|
|
||||||
import com.osmand.data.Building;
|
import com.osmand.data.Building;
|
||||||
import com.osmand.data.City;
|
import com.osmand.data.City;
|
||||||
|
import com.osmand.data.PostcodeBasedStreet;
|
||||||
import com.osmand.data.Region;
|
import com.osmand.data.Region;
|
||||||
import com.osmand.data.Street;
|
import com.osmand.data.Street;
|
||||||
import com.osmand.data.City.CityType;
|
import com.osmand.data.City.CityType;
|
||||||
|
@ -91,7 +93,14 @@ public class RegionAddressRepository {
|
||||||
if(city.isEmptyWithStreets()){
|
if(city.isEmptyWithStreets()){
|
||||||
preloadStreets(city);
|
preloadStreets(city);
|
||||||
}
|
}
|
||||||
return city.getStreet(name);
|
if (city.getPostcodes().isEmpty()) {
|
||||||
|
preloadPostcodes(city);
|
||||||
|
}
|
||||||
|
Street street = city.getStreet(name);
|
||||||
|
if (street == null) {
|
||||||
|
street = city.getPostcodes().contains(name.toUpperCase()) ? new PostcodeBasedStreet(city, name) : null;
|
||||||
|
}
|
||||||
|
return street;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Building getBuildingByName(Street street, String name){
|
public Building getBuildingByName(Street street, String name){
|
||||||
|
@ -180,12 +189,27 @@ public class RegionAddressRepository {
|
||||||
|
|
||||||
public void fillWithSuggestedStreets(City c, String name, List<Street> streetsToFill){
|
public void fillWithSuggestedStreets(City c, String name, List<Street> streetsToFill){
|
||||||
preloadStreets(c);
|
preloadStreets(c);
|
||||||
|
preloadPostcodes(c);
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
|
|
||||||
int ind = 0;
|
int ind = 0;
|
||||||
if(name.length() == 0){
|
if(name.length() == 0){
|
||||||
streetsToFill.addAll(c.getStreets());
|
streetsToFill.addAll(c.getStreets());
|
||||||
return;
|
return;
|
||||||
|
} else if (name.length() >= 2 &&
|
||||||
|
Character.isDigit(name.charAt(0)) &&
|
||||||
|
Character.isDigit(name.charAt(1))) {
|
||||||
|
// also try to identify postcodes
|
||||||
|
for (String code:c.getPostcodes()) {
|
||||||
|
code = code.toLowerCase();
|
||||||
|
if (code.startsWith(name)) {
|
||||||
|
streetsToFill.add(ind++,new PostcodeBasedStreet(c, code));
|
||||||
|
} else {
|
||||||
|
streetsToFill.add(new PostcodeBasedStreet(c, code));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ind = 0;
|
||||||
for (Street s : c.getStreets()) {
|
for (Street s : c.getStreets()) {
|
||||||
String sName = useEnglishNames ? s.getEnName() : s.getName();
|
String sName = useEnglishNames ? s.getEnName() : s.getName();
|
||||||
String lowerCase = sName.toLowerCase();
|
String lowerCase = sName.toLowerCase();
|
||||||
|
@ -204,7 +228,10 @@ public class RegionAddressRepository {
|
||||||
EnumSet<CityType> set = EnumSet.of(CityType.CITY, CityType.TOWN);
|
EnumSet<CityType> set = EnumSet.of(CityType.CITY, CityType.TOWN);
|
||||||
for(CityType t : set){
|
for(CityType t : set){
|
||||||
if(name.length() == 0){
|
if(name.length() == 0){
|
||||||
citiesToFill.addAll(cityTypes.get(t));
|
List<City> list = cityTypes.get(t);
|
||||||
|
if (list != null) {
|
||||||
|
citiesToFill.addAll(list);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
for (City c : cityTypes.get(t)) {
|
for (City c : cityTypes.get(t)) {
|
||||||
|
@ -282,10 +309,43 @@ public class RegionAddressRepository {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void preloadPostcodes(City city) {
|
||||||
|
if (city.getPostcodes().isEmpty()) {
|
||||||
|
// check if it possible to load postcodes
|
||||||
|
try {
|
||||||
|
Cursor query = db.query(true, IndexBuildingTable.getTable(), new String[]{IndexBuildingTable.POSTCODE.toString()},null,null,null,null,null,null);
|
||||||
|
log.debug("Start loading postcodes for " + city.getName());
|
||||||
|
if (query.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
String postcode = query.getString(0);
|
||||||
|
if (postcode != null) {
|
||||||
|
city.getPostcodes().add(postcode);
|
||||||
|
}
|
||||||
|
} while (query.moveToNext());
|
||||||
|
}
|
||||||
|
query.close();
|
||||||
|
log.debug("Loaded " + city.getPostcodes().size() + " buildings");
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.warn("Can't load postcodes information. It might be that you are using old version of index.", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void preloadBuildings(Street street){
|
public void preloadBuildings(Street street){
|
||||||
if (street.getBuildings().isEmpty()) {
|
if (street.getBuildings().isEmpty()) {
|
||||||
Cursor query = db.query(IndexBuildingTable.getTable(), IndexConstants.generateColumnNames(IndexBuildingTable.values()), "? = street",
|
Cursor query = null;
|
||||||
new String[] { street.getId() + "" }, null, null, null);
|
if (street instanceof PostcodeBasedStreet) {
|
||||||
|
// this is postcode
|
||||||
|
query = db.query(IndexBuildingTable.getTable(), IndexConstants.generateColumnNames(IndexBuildingTable.values()), "? = postcode",
|
||||||
|
new String[] { street.getName().toUpperCase()}, null, null, null);
|
||||||
|
} else {
|
||||||
|
IndexBuildingTable[] columns = IndexBuildingTable.values();
|
||||||
|
IndexBuildingTable[] columnsWithoutPostcode = new IndexBuildingTable[columns.length-1];
|
||||||
|
// we don't need postcode information here
|
||||||
|
System.arraycopy(columns, 0, columnsWithoutPostcode, 0, columnsWithoutPostcode.length);
|
||||||
|
query = db.query(IndexBuildingTable.getTable(), IndexConstants.generateColumnNames(columnsWithoutPostcode), "? = street",
|
||||||
|
new String[] { street.getId() + "" }, null, null, null);
|
||||||
|
}
|
||||||
log.debug("Start loading buildings for " + street.getName());
|
log.debug("Start loading buildings for " + street.getName());
|
||||||
if (query.moveToFirst()) {
|
if (query.moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
|
|
Loading…
Reference in a new issue