implement index functionality
git-svn-id: https://osmand.googlecode.com/svn/trunk@61 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
c845cd9175
commit
2060618cb8
13 changed files with 351 additions and 72 deletions
|
@ -24,6 +24,7 @@ public class ToDoConstants {
|
||||||
|
|
||||||
// TODO see all calculations x, y for layers & for MapView
|
// TODO see all calculations x, y for layers & for MapView
|
||||||
|
|
||||||
|
// 0. Minimize memory used for index & improve time for read index
|
||||||
//// TODO for releasing version
|
//// TODO for releasing version
|
||||||
// 1. POI SEARCH NEAR TO YOU
|
// 1. POI SEARCH NEAR TO YOU
|
||||||
// 2. FIX BACK TO your location & gps & point of view (may be compass)
|
// 2. FIX BACK TO your location & gps & point of view (may be compass)
|
||||||
|
@ -45,5 +46,6 @@ public class ToDoConstants {
|
||||||
// 4. Config file log & see log from file
|
// 4. Config file log & see log from file
|
||||||
// 6. Predefine what should be extracted from osm (building, poi or roads)
|
// 6. Predefine what should be extracted from osm (building, poi or roads)
|
||||||
// 7. Fix TODO in files (accept amenity - way)
|
// 7. Fix TODO in files (accept amenity - way)
|
||||||
|
// 8. add progress for data generation process
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,15 @@ public class Amenity extends MapObject<Node> {
|
||||||
SHOP, // convenience (product), clothes...
|
SHOP, // convenience (product), clothes...
|
||||||
LEISURE, // sport
|
LEISURE, // sport
|
||||||
OTHER, // grave-yard, police, post-office
|
OTHER, // grave-yard, police, post-office
|
||||||
|
;
|
||||||
|
|
||||||
|
public static AmenityType fromString(String s){
|
||||||
|
return AmenityType.valueOf(s.toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String valueToString(AmenityType t){
|
||||||
|
return t.toString().toLowerCase();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private static Map<String, AmenityType> prebuiltMap = new LinkedHashMap<String, AmenityType>();
|
private static Map<String, AmenityType> prebuiltMap = new LinkedHashMap<String, AmenityType>();
|
||||||
static {
|
static {
|
||||||
|
@ -78,12 +87,25 @@ public class Amenity extends MapObject<Node> {
|
||||||
|
|
||||||
|
|
||||||
private final Node node;
|
private final Node node;
|
||||||
|
private String subType;
|
||||||
|
private AmenityType type;
|
||||||
|
|
||||||
public Amenity(Node node){
|
public Amenity(Node node){
|
||||||
this.node = node;
|
this.node = node;
|
||||||
|
this.type = getType(node);
|
||||||
|
this.subType = getSubType(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSubType(){
|
public Amenity(){
|
||||||
|
this.node = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node getEntity() {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getSubType(Node node){
|
||||||
if(node.getTag(OSMTagKey.AMENITY) != null){
|
if(node.getTag(OSMTagKey.AMENITY) != null){
|
||||||
return node.getTag(OSMTagKey.AMENITY);
|
return node.getTag(OSMTagKey.AMENITY);
|
||||||
} else if(node.getTag(OSMTagKey.SHOP) != null){
|
} else if(node.getTag(OSMTagKey.SHOP) != null){
|
||||||
|
@ -96,7 +118,7 @@ public class Amenity extends MapObject<Node> {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public AmenityType getType(){
|
protected AmenityType getType(Node node){
|
||||||
if(node.getTag(OSMTagKey.SHOP) != null){
|
if(node.getTag(OSMTagKey.SHOP) != null){
|
||||||
return AmenityType.SHOP;
|
return AmenityType.SHOP;
|
||||||
} else if(node.getTag(OSMTagKey.TOURISM) != null){
|
} else if(node.getTag(OSMTagKey.TOURISM) != null){
|
||||||
|
@ -109,6 +131,22 @@ public class Amenity extends MapObject<Node> {
|
||||||
return AmenityType.OTHER;
|
return AmenityType.OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AmenityType getType(){
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubType(){
|
||||||
|
return subType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(AmenityType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubType(String subType) {
|
||||||
|
this.subType = subType;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isAmenity(Entity n){
|
public static boolean isAmenity(Entity n){
|
||||||
if(!(n instanceof Node)){
|
if(!(n instanceof Node)){
|
||||||
return false;
|
return false;
|
||||||
|
@ -125,20 +163,15 @@ public class Amenity extends MapObject<Node> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node getEntity() {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSimpleFormat(){
|
public String getSimpleFormat(){
|
||||||
String name = node.getTag(OSMTagKey.NAME);
|
String name = getName();
|
||||||
return Algoritms.capitalizeFirstLetterAndLowercase(getType().toString()) +
|
return Algoritms.capitalizeFirstLetterAndLowercase(getType().toString()) +
|
||||||
" : " + getSubType() + " " +(name == null ? node.getId() : name);
|
" : " + getSubType() + " " +(name == null ? node.getId() : name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringWithoutType(){
|
public String getStringWithoutType(){
|
||||||
String name = node.getTag(OSMTagKey.NAME);
|
return getSubType() + " " +getName();
|
||||||
return getSubType() + " " +(name == null ? node.getId() : name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,12 +4,14 @@ import com.osmand.osm.Entity;
|
||||||
|
|
||||||
public class Building extends MapObject<Entity> {
|
public class Building extends MapObject<Entity> {
|
||||||
|
|
||||||
private final Entity e;
|
private Entity e;
|
||||||
|
|
||||||
public Building(Entity e){
|
public Building(Entity e){
|
||||||
this.e = e;
|
this.e = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Building(){}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Entity getEntity() {
|
public Entity getEntity() {
|
||||||
return e;
|
return e;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import com.osmand.Algoritms;
|
||||||
import com.osmand.osm.Entity;
|
import com.osmand.osm.Entity;
|
||||||
import com.osmand.osm.Node;
|
import com.osmand.osm.Node;
|
||||||
import com.osmand.osm.OSMSettings.OSMTagKey;
|
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
|
@ -14,7 +15,8 @@ public class City extends MapObject<Node> {
|
||||||
CITY(10000), TOWN(5000), VILLAGE(1000), HAMLET(300), SUBURB(300);
|
CITY(10000), TOWN(5000), VILLAGE(1000), HAMLET(300), SUBURB(300);
|
||||||
|
|
||||||
private double radius;
|
private double radius;
|
||||||
private CityType(double radius){
|
|
||||||
|
private CityType(double radius) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,21 +24,34 @@ public class City extends MapObject<Node> {
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String valueToString(CityType t) {
|
||||||
|
return t.toString().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Node el;
|
public static CityType valueFromString(String place) {
|
||||||
|
if (place == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (CityType t : CityType.values()) {
|
||||||
|
if (t.name().equalsIgnoreCase(place)) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node el;
|
||||||
private CityType type = null;
|
private CityType type = null;
|
||||||
private Map<String, Street> streets = new TreeMap<String, Street>();
|
private Map<String, Street> streets = new TreeMap<String, Street>();
|
||||||
|
|
||||||
public City(Node el){
|
public City(Node el){
|
||||||
this.el = el;
|
this.el = el;
|
||||||
String place = el.getTag(OSMTagKey.PLACE);
|
type = CityType.valueFromString(el.getTag(OSMTagKey.PLACE));
|
||||||
for(CityType t : CityType.values()){
|
|
||||||
if(t.name().equalsIgnoreCase(place)){
|
|
||||||
type = t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public City(CityType type){
|
||||||
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Street registerStreet(String street){
|
public Street registerStreet(String street){
|
||||||
|
@ -46,6 +61,13 @@ public class City extends MapObject<Node> {
|
||||||
return streets.get(street);
|
return streets.get(street);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Street registerStreet(Street street){
|
||||||
|
if(!Algoritms.isEmpty(street.getName())){
|
||||||
|
return streets.put(street.getName(), street);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public Street registerBuilding(Entity e){
|
public Street registerBuilding(Entity e){
|
||||||
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);
|
||||||
|
|
|
@ -9,9 +9,26 @@ public abstract class MapObject<T extends Entity> implements Comparable<MapObjec
|
||||||
|
|
||||||
protected String name = null;
|
protected String name = null;
|
||||||
protected LatLon location = null;
|
protected LatLon location = null;
|
||||||
|
protected Long id = null;
|
||||||
|
|
||||||
|
// could be null
|
||||||
public abstract T getEntity();
|
public abstract T getEntity();
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
if(id != null){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
T e = getEntity();
|
||||||
|
if(e != null){
|
||||||
|
return e.getId();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
if (this.name != null) {
|
if (this.name != null) {
|
||||||
return this.name;
|
return this.name;
|
||||||
|
|
|
@ -133,6 +133,13 @@ public class Region {
|
||||||
amenities.registerObject(location.getLatitude(), location.getLongitude(), a);
|
amenities.registerObject(location.getLatitude(), location.getLongitude(), a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerCity(City city){
|
||||||
|
if(city.getType() != null && !Algoritms.isEmpty(city.getName()) && city.getLocation() != null){
|
||||||
|
LatLon l = city.getLocation();
|
||||||
|
cityManager.registerObject(l.getLatitude(), l.getLongitude(), city);
|
||||||
|
cities.get(city.getType()).add(city);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public City registerCity(Node c){
|
public City registerCity(Node c){
|
||||||
City city = new City(c);
|
City city = new City(c);
|
||||||
|
|
|
@ -12,7 +12,6 @@ import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
|
|
||||||
public class Street extends MapObject<Entity> {
|
public class Street extends MapObject<Entity> {
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private List<Building> buildings = new ArrayList<Building>();
|
private List<Building> buildings = new ArrayList<Building>();
|
||||||
private List<Node> wayNodes = new ArrayList<Node>();
|
private List<Node> wayNodes = new ArrayList<Node>();
|
||||||
private Node center = null;
|
private Node center = null;
|
||||||
|
@ -21,21 +20,22 @@ public class Street extends MapObject<Entity> {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Street(){}
|
||||||
|
|
||||||
public void registerBuilding(Entity e){
|
public void 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerBuilding(Building building){
|
||||||
|
buildings.add(building);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Building> getBuildings() {
|
public List<Building> getBuildings() {
|
||||||
return buildings;
|
return buildings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public LatLon getLocation(){
|
public LatLon getLocation(){
|
||||||
if(center == null){
|
if(center == null){
|
||||||
calculateCenter();
|
calculateCenter();
|
||||||
|
|
|
@ -115,7 +115,7 @@ public class DataExtraction {
|
||||||
// TODO add interested objects
|
// TODO add interested objects
|
||||||
List<Long> interestedObjects = new ArrayList<Long>();
|
List<Long> interestedObjects = new ArrayList<Long>();
|
||||||
if (writeTestOsmFile != null) {
|
if (writeTestOsmFile != null) {
|
||||||
OSMStorageWriter writer = new OSMStorageWriter(country.getStorage().getRegisteredEntities());
|
OSMStorageWriter writer = new OSMStorageWriter();
|
||||||
OutputStream output = new FileOutputStream(writeTestOsmFile);
|
OutputStream output = new FileOutputStream(writeTestOsmFile);
|
||||||
if (writeTestOsmFile.endsWith(".bz2")) {
|
if (writeTestOsmFile.endsWith(".bz2")) {
|
||||||
output.write('B');
|
output.write('B');
|
||||||
|
@ -123,7 +123,7 @@ public class DataExtraction {
|
||||||
output = new CBZip2OutputStream(output);
|
output = new CBZip2OutputStream(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.saveStorage(output, interestedObjects, false);
|
writer.saveStorage(output, country.getStorage(), interestedObjects, false);
|
||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,26 @@ public class DataIndexBuilder {
|
||||||
}
|
}
|
||||||
OutputStream output = checkFile("POI/"+region.getName()+".osm");
|
OutputStream output = checkFile("POI/"+region.getName()+".osm");
|
||||||
try {
|
try {
|
||||||
OSMStorageWriter writer = new OSMStorageWriter(region.getStorage().getRegisteredEntities());
|
OSMStorageWriter writer = new OSMStorageWriter();
|
||||||
writer.saveStorage(output, interestedObjects, false);
|
writer.saveStorage(output, region.getStorage(), interestedObjects, false);
|
||||||
|
} finally {
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
|
output = checkFile("POI/"+region.getName()+".osmand");
|
||||||
|
try {
|
||||||
|
OSMStorageWriter writer = new OSMStorageWriter();
|
||||||
|
writer.savePOIIndex(output, region);
|
||||||
|
} finally {
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataIndexBuilder buildAddress() throws XMLStreamException, IOException{
|
||||||
|
OutputStream output = checkFile("Address/"+region.getName()+".osmand");
|
||||||
|
try {
|
||||||
|
OSMStorageWriter writer = new OSMStorageWriter();
|
||||||
|
writer.saveAddressIndex(output, region);
|
||||||
} finally {
|
} finally {
|
||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,15 @@ package com.osmand.osm.io;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.osmand.data.Amenity;
|
||||||
|
import com.osmand.data.Building;
|
||||||
|
import com.osmand.data.City;
|
||||||
|
import com.osmand.data.MapObject;
|
||||||
import com.osmand.data.Region;
|
import com.osmand.data.Region;
|
||||||
|
import com.osmand.data.Street;
|
||||||
|
import com.osmand.data.Amenity.AmenityType;
|
||||||
|
import com.osmand.data.City.CityType;
|
||||||
|
import com.osmand.osm.Entity;
|
||||||
|
|
||||||
public class OSMIndexStorage extends OsmBaseStorage {
|
public class OSMIndexStorage extends OsmBaseStorage {
|
||||||
protected static final String ELEM_OSMAND = "osmand";
|
protected static final String ELEM_OSMAND = "osmand";
|
||||||
|
@ -11,6 +19,12 @@ public class OSMIndexStorage extends OsmBaseStorage {
|
||||||
protected static final String ELEM_CITY = "city";
|
protected static final String ELEM_CITY = "city";
|
||||||
protected static final String ELEM_STREET = "street";
|
protected static final String ELEM_STREET = "street";
|
||||||
protected static final String ELEM_BUILDING = "building";
|
protected static final String ELEM_BUILDING = "building";
|
||||||
|
protected static final String ELEM_AMENITY = "amenity";
|
||||||
|
|
||||||
|
protected static final String ATTR_CITYTYPE = "citytype";
|
||||||
|
protected static final String ATTR_TYPE = "type";
|
||||||
|
protected static final String ATTR_SUBTYPE = "subtype";
|
||||||
|
protected static final String ATTR_NAME = "name";
|
||||||
|
|
||||||
public static final String OSMAND_VERSION = "0.1";
|
public static final String OSMAND_VERSION = "0.1";
|
||||||
|
|
||||||
|
@ -21,6 +35,9 @@ public class OSMIndexStorage extends OsmBaseStorage {
|
||||||
this.region = region;
|
this.region = region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected City currentParsedCity = null;
|
||||||
|
protected Street currentParsedStreet = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initRootElement(String uri, String localName, String name, Attributes attributes) throws OsmVersionNotSupported {
|
protected void initRootElement(String uri, String localName, String name, Attributes attributes) throws OsmVersionNotSupported {
|
||||||
if(ELEM_OSM.equals(name)){
|
if(ELEM_OSM.equals(name)){
|
||||||
|
@ -37,6 +54,17 @@ public class OSMIndexStorage extends OsmBaseStorage {
|
||||||
parseStarted = true;
|
parseStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void parseMapObject(MapObject<? extends Entity> c, Attributes attributes){
|
||||||
|
double lat = parseDouble(attributes, ATTR_LAT, 0);
|
||||||
|
double lon = parseDouble(attributes, ATTR_LON, 0);
|
||||||
|
long id = parseId(attributes, ATTR_ID, -1);
|
||||||
|
c.setId(id);
|
||||||
|
if(lat != 0 || lon != 0){
|
||||||
|
c.setLocation(lat, lon);
|
||||||
|
}
|
||||||
|
c.setName(attributes.getValue(ATTR_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
|
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
|
||||||
name = saxParser.isNamespaceAware() ? localName : name;
|
name = saxParser.isNamespaceAware() ? localName : name;
|
||||||
|
@ -44,6 +72,28 @@ public class OSMIndexStorage extends OsmBaseStorage {
|
||||||
initRootElement(uri, localName, name, attributes);
|
initRootElement(uri, localName, name, attributes);
|
||||||
} else if(ELEM_INDEX.equals(name)){
|
} else if(ELEM_INDEX.equals(name)){
|
||||||
} else if(ELEM_CITY.equals(name)){
|
} else if(ELEM_CITY.equals(name)){
|
||||||
|
CityType t = CityType.valueOf(attributes.getValue(ATTR_CITYTYPE));
|
||||||
|
City c = new City(t);
|
||||||
|
parseMapObject(c, attributes);
|
||||||
|
region.registerCity(c);
|
||||||
|
currentParsedCity = c;
|
||||||
|
} else if(ELEM_STREET.equals(name)){
|
||||||
|
assert currentParsedCity != null;
|
||||||
|
Street street = new Street();
|
||||||
|
parseMapObject(street, attributes);
|
||||||
|
currentParsedCity.registerStreet(street);
|
||||||
|
currentParsedStreet = street;
|
||||||
|
} else if(ELEM_BUILDING.equals(name)){
|
||||||
|
assert currentParsedStreet != null;
|
||||||
|
Building building = new Building();
|
||||||
|
parseMapObject(building, attributes);
|
||||||
|
currentParsedStreet.registerBuilding(building);
|
||||||
|
} else if(ELEM_AMENITY.equals(name)){
|
||||||
|
Amenity a = new Amenity();
|
||||||
|
a.setType(AmenityType.fromString(attributes.getValue(ATTR_TYPE)));
|
||||||
|
a.setSubType(attributes.getValue(ATTR_SUBTYPE));
|
||||||
|
parseMapObject(a, attributes);
|
||||||
|
region.registerAmenity(a);
|
||||||
} else {
|
} else {
|
||||||
super.startElement(uri, localName, name, attributes);
|
super.startElement(uri, localName, name, attributes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import static com.osmand.osm.io.OsmBaseStorage.ELEM_OSM;
|
||||||
import static com.osmand.osm.io.OsmBaseStorage.ELEM_RELATION;
|
import static com.osmand.osm.io.OsmBaseStorage.ELEM_RELATION;
|
||||||
import static com.osmand.osm.io.OsmBaseStorage.ELEM_TAG;
|
import static com.osmand.osm.io.OsmBaseStorage.ELEM_TAG;
|
||||||
import static com.osmand.osm.io.OsmBaseStorage.ELEM_WAY;
|
import static com.osmand.osm.io.OsmBaseStorage.ELEM_WAY;
|
||||||
|
import static com.osmand.osm.io.OSMIndexStorage.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -29,7 +30,17 @@ import java.util.Map.Entry;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.XMLStreamWriter;
|
import javax.xml.stream.XMLStreamWriter;
|
||||||
|
|
||||||
|
import com.osmand.Algoritms;
|
||||||
|
import com.osmand.data.Amenity;
|
||||||
|
import com.osmand.data.Building;
|
||||||
|
import com.osmand.data.City;
|
||||||
|
import com.osmand.data.MapObject;
|
||||||
|
import com.osmand.data.Region;
|
||||||
|
import com.osmand.data.Street;
|
||||||
|
import com.osmand.data.Amenity.AmenityType;
|
||||||
|
import com.osmand.data.City.CityType;
|
||||||
import com.osmand.osm.Entity;
|
import com.osmand.osm.Entity;
|
||||||
|
import com.osmand.osm.LatLon;
|
||||||
import com.osmand.osm.Node;
|
import com.osmand.osm.Node;
|
||||||
import com.osmand.osm.Relation;
|
import com.osmand.osm.Relation;
|
||||||
import com.osmand.osm.Way;
|
import com.osmand.osm.Way;
|
||||||
|
@ -38,17 +49,17 @@ import com.sun.xml.internal.stream.writers.XMLStreamWriterImpl;
|
||||||
|
|
||||||
public class OSMStorageWriter {
|
public class OSMStorageWriter {
|
||||||
|
|
||||||
private final Map<Long, Entity> entities;
|
|
||||||
private final String INDENT = " ";
|
private final String INDENT = " ";
|
||||||
private final String INDENT2 = INDENT + INDENT;
|
private final String INDENT2 = INDENT + INDENT;
|
||||||
|
private final String INDENT3 = INDENT + INDENT + INDENT;
|
||||||
|
|
||||||
|
|
||||||
public OSMStorageWriter(Map<Long, Entity> entities){
|
public OSMStorageWriter(){
|
||||||
this.entities = entities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void saveStorage(OutputStream output, Collection<Long> interestedObjects, boolean includeLinks) throws XMLStreamException, IOException {
|
public void saveStorage(OutputStream output, OsmBaseStorage storage, Collection<Long> interestedObjects, boolean includeLinks) throws XMLStreamException, IOException {
|
||||||
|
Map<Long, Entity> entities = storage.getRegisteredEntities();
|
||||||
PropertyManager propertyManager = new PropertyManager(PropertyManager.CONTEXT_WRITER);
|
PropertyManager propertyManager = new PropertyManager(PropertyManager.CONTEXT_WRITER);
|
||||||
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
// String indent = "{http://xml.apache.org/xslt}indent-amount";
|
// String indent = "{http://xml.apache.org/xslt}indent-amount";
|
||||||
|
@ -92,7 +103,7 @@ public class OSMStorageWriter {
|
||||||
streamWriter.writeAttribute(ATTR_LON, n.getLongitude()+"");
|
streamWriter.writeAttribute(ATTR_LON, n.getLongitude()+"");
|
||||||
streamWriter.writeAttribute(ATTR_ID, n.getId()+"");
|
streamWriter.writeAttribute(ATTR_ID, n.getId()+"");
|
||||||
writeTags(streamWriter, n);
|
writeTags(streamWriter, n);
|
||||||
streamWriter.writeEndElement();
|
writeEndElement(streamWriter, INDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Way w : ways){
|
for(Way w : ways){
|
||||||
|
@ -101,10 +112,10 @@ public class OSMStorageWriter {
|
||||||
for(Long r : w.getNodeIds()){
|
for(Long r : w.getNodeIds()){
|
||||||
writeStartElement(streamWriter, ELEM_ND, INDENT2);
|
writeStartElement(streamWriter, ELEM_ND, INDENT2);
|
||||||
streamWriter.writeAttribute(ATTR_REF, r+"");
|
streamWriter.writeAttribute(ATTR_REF, r+"");
|
||||||
streamWriter.writeEndElement();
|
writeEndElement(streamWriter, INDENT2);
|
||||||
}
|
}
|
||||||
writeTags(streamWriter, w);
|
writeTags(streamWriter, w);
|
||||||
streamWriter.writeEndElement();
|
writeEndElement(streamWriter, INDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Relation r : relations){
|
for(Relation r : relations){
|
||||||
|
@ -118,19 +129,19 @@ public class OSMStorageWriter {
|
||||||
s = "";
|
s = "";
|
||||||
}
|
}
|
||||||
streamWriter.writeAttribute(ATTR_ROLE, s);
|
streamWriter.writeAttribute(ATTR_ROLE, s);
|
||||||
streamWriter.writeAttribute(ATTR_TYPE, getEntityType(e.getKey()));
|
streamWriter.writeAttribute(ATTR_TYPE, getEntityType(entities, e.getKey()));
|
||||||
streamWriter.writeEndElement();
|
writeEndElement(streamWriter, INDENT2);
|
||||||
}
|
}
|
||||||
writeTags(streamWriter, r);
|
writeTags(streamWriter, r);
|
||||||
streamWriter.writeEndElement();
|
writeEndElement(streamWriter, INDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
streamWriter.writeEndElement(); // osm
|
writeEndElement(streamWriter, ""); // osm
|
||||||
streamWriter.writeEndDocument();
|
streamWriter.writeEndDocument();
|
||||||
streamWriter.flush();
|
streamWriter.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEntityType(Long id){
|
private String getEntityType(Map<Long, Entity> entities , Long id){
|
||||||
Entity e = entities.get(id);
|
Entity e = entities.get(id);
|
||||||
if(e instanceof Way){
|
if(e instanceof Way){
|
||||||
return "way";
|
return "way";
|
||||||
|
@ -140,11 +151,96 @@ public class OSMStorageWriter {
|
||||||
return "node";
|
return "node";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void savePOIIndex(OutputStream output, Region region) throws XMLStreamException, IOException {
|
||||||
|
PropertyManager propertyManager = new PropertyManager(PropertyManager.CONTEXT_WRITER);
|
||||||
|
XMLStreamWriter streamWriter = new XMLStreamWriterImpl(output, propertyManager);
|
||||||
|
|
||||||
|
writeStartElement(streamWriter, ELEM_OSMAND, "");
|
||||||
|
streamWriter.writeAttribute(ATTR_VERSION, OSMAND_VERSION);
|
||||||
|
List<Amenity> amenities = region.getAmenityManager().getAllObjects();
|
||||||
|
for(Amenity n : amenities){
|
||||||
|
if (couldBeWrited(n)) {
|
||||||
|
writeStartElement(streamWriter, ELEM_AMENITY, INDENT);
|
||||||
|
writeAttributesMapObject(streamWriter, n);
|
||||||
|
streamWriter.writeAttribute(ATTR_TYPE, AmenityType.valueToString(n.getType()));
|
||||||
|
streamWriter.writeAttribute(ATTR_SUBTYPE, n.getSubType());
|
||||||
|
writeEndElement(streamWriter, INDENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeEndElement(streamWriter, ""); // osmand
|
||||||
|
streamWriter.writeEndDocument();
|
||||||
|
streamWriter.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeCity(XMLStreamWriter streamWriter, City c) throws XMLStreamException{
|
||||||
|
writeStartElement(streamWriter, ELEM_CITY, INDENT);
|
||||||
|
writeAttributesMapObject(streamWriter, c);
|
||||||
|
streamWriter.writeAttribute(ATTR_CITYTYPE, CityType.valueToString(c.getType()));
|
||||||
|
for(Street s : c.getStreets()){
|
||||||
|
if (couldBeWrited(s)) {
|
||||||
|
writeStartElement(streamWriter, ELEM_STREET, INDENT2);
|
||||||
|
writeAttributesMapObject(streamWriter, s);
|
||||||
|
for(Building b : s.getBuildings()) {
|
||||||
|
if (couldBeWrited(b)) {
|
||||||
|
writeStartElement(streamWriter, ELEM_BUILDING, INDENT3);
|
||||||
|
writeAttributesMapObject(streamWriter, b);
|
||||||
|
writeEndElement(streamWriter, INDENT3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeEndElement(streamWriter, INDENT2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeEndElement(streamWriter, INDENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveAddressIndex(OutputStream output, Region region) throws XMLStreamException, IOException {
|
||||||
|
PropertyManager propertyManager = new PropertyManager(PropertyManager.CONTEXT_WRITER);
|
||||||
|
XMLStreamWriter streamWriter = new XMLStreamWriterImpl(output, propertyManager);
|
||||||
|
|
||||||
|
writeStartElement(streamWriter, ELEM_OSMAND, "");
|
||||||
|
streamWriter.writeAttribute(ATTR_VERSION, OSMAND_VERSION);
|
||||||
|
for(CityType t : CityType.values()){
|
||||||
|
Collection<City> cities = region.getCitiesByType(t);
|
||||||
|
if(cities != null){
|
||||||
|
for(City c : cities){
|
||||||
|
if (couldBeWrited(c)) {
|
||||||
|
writeCity(streamWriter, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeEndElement(streamWriter, ""); // osmand
|
||||||
|
streamWriter.writeEndDocument();
|
||||||
|
streamWriter.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean couldBeWrited(MapObject<? extends Entity> e){
|
||||||
|
if(!Algoritms.isEmpty(e.getName()) && e.getLocation() != null){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeAttributesMapObject(XMLStreamWriter streamWriter, MapObject<? extends Entity> e) throws XMLStreamException{
|
||||||
|
LatLon location = e.getLocation();
|
||||||
|
streamWriter.writeAttribute(ATTR_LAT, location.getLatitude()+"");
|
||||||
|
streamWriter.writeAttribute(ATTR_LON, location.getLongitude()+"");
|
||||||
|
streamWriter.writeAttribute(ATTR_NAME, e.getName());
|
||||||
|
streamWriter.writeAttribute(ATTR_ID, e.getId()+"");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void writeStartElement(XMLStreamWriter writer, String name, String indent) throws XMLStreamException{
|
private void writeStartElement(XMLStreamWriter writer, String name, String indent) throws XMLStreamException{
|
||||||
writer.writeCharacters("\n"+indent);
|
writer.writeCharacters("\n"+indent);
|
||||||
writer.writeStartElement(name);
|
writer.writeStartElement(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeEndElement(XMLStreamWriter writer, String indent) throws XMLStreamException{
|
||||||
|
writer.writeCharacters("\n"+indent);
|
||||||
|
writer.writeEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
private void writeTags(XMLStreamWriter writer, Entity e) throws XMLStreamException{
|
private void writeTags(XMLStreamWriter writer, Entity e) throws XMLStreamException{
|
||||||
for(Entry<String, String> en : e.getTags().entrySet()){
|
for(Entry<String, String> en : e.getTags().entrySet()){
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
||||||
public static final int divNonLoadedImage = 16;
|
public static final int divNonLoadedImage = 16;
|
||||||
|
|
||||||
public static JMenu getMenuToChooseSource(final MapPanel panel){
|
public static JMenu getMenuToChooseSource(final MapPanel panel){
|
||||||
final JMenu tiles = new JMenu("Source tile");
|
final JMenu tiles = new JMenu("Source of tiles");
|
||||||
final List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
final List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
||||||
for(final TileSourceTemplate l : list){
|
for(final TileSourceTemplate l : list){
|
||||||
JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(l.getName());
|
JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(l.getName());
|
||||||
|
|
|
@ -110,6 +110,7 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
private JCheckBox buildPoiIndex;
|
private JCheckBox buildPoiIndex;
|
||||||
private JCheckBox buildAddressIndex;
|
private JCheckBox buildAddressIndex;
|
||||||
private TreeModelListener treeModelListener;
|
private TreeModelListener treeModelListener;
|
||||||
|
private JCheckBox zipIndexFiles;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -279,6 +280,7 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
generateDataButton.setEnabled(region != null);
|
generateDataButton.setEnabled(region != null);
|
||||||
buildAddressIndex.setEnabled(generateDataButton.isEnabled() && region.getCitiesCount(null) > 0);
|
buildAddressIndex.setEnabled(generateDataButton.isEnabled() && region.getCitiesCount(null) > 0);
|
||||||
buildPoiIndex.setEnabled(generateDataButton.isEnabled() && !region.getAmenityManager().isEmpty());
|
buildPoiIndex.setEnabled(generateDataButton.isEnabled() && !region.getAmenityManager().isEmpty());
|
||||||
|
zipIndexFiles.setEnabled(generateDataButton.isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createButtonsBar(Container content){
|
public void createButtonsBar(Container content){
|
||||||
|
@ -295,26 +297,8 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
DataIndexBuilder builder = new DataIndexBuilder(DataExtractionSettings.getSettings().getDefaultWorkingDir(), region);
|
generateData();
|
||||||
StringBuilder msg = new StringBuilder();
|
|
||||||
try {
|
|
||||||
msg.append("Indices checked for ").append(region.getName());
|
|
||||||
if(buildPoiIndex.isEnabled()){
|
|
||||||
builder.buildPOI();
|
|
||||||
msg.append(", POI index ").append("successfully created");
|
|
||||||
}
|
}
|
||||||
msg.append(".");
|
|
||||||
JOptionPane pane = new JOptionPane(msg);
|
|
||||||
JDialog dialog = pane.createDialog(frame, "Generation data");
|
|
||||||
dialog.setVisible(true);
|
|
||||||
} catch (XMLStreamException e1) {
|
|
||||||
ExceptionHandler.handle(e1);
|
|
||||||
} catch (IOException e1) {
|
|
||||||
ExceptionHandler.handle(e1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
buildPoiIndex = new JCheckBox();
|
buildPoiIndex = new JCheckBox();
|
||||||
|
@ -327,9 +311,57 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
panel.add(buildAddressIndex);
|
panel.add(buildAddressIndex);
|
||||||
buildAddressIndex.setSelected(true);
|
buildAddressIndex.setSelected(true);
|
||||||
|
|
||||||
|
zipIndexFiles = new JCheckBox();
|
||||||
|
zipIndexFiles.setText("Zip index files");
|
||||||
|
panel.add(zipIndexFiles);
|
||||||
|
zipIndexFiles.setSelected(true);
|
||||||
|
|
||||||
updateButtonsBar();
|
updateButtonsBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void generateData() {
|
||||||
|
try {
|
||||||
|
final ProgressDialog dlg = new ProgressDialog(frame, "Generating data");
|
||||||
|
dlg.setRunnable(new Runnable(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
dlg.startTask("Generating indices...", -1);
|
||||||
|
DataIndexBuilder builder = new DataIndexBuilder(DataExtractionSettings.getSettings().getDefaultWorkingDir(), region);
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
try {
|
||||||
|
builder.setZipped(zipIndexFiles.isSelected());
|
||||||
|
msg.append("Indices checked for ").append(region.getName());
|
||||||
|
if(buildPoiIndex.isEnabled()){
|
||||||
|
dlg.startTask("Generating POI index...", -1);
|
||||||
|
builder.buildPOI();
|
||||||
|
msg.append(", POI index ").append("successfully created");
|
||||||
|
}
|
||||||
|
if(buildAddressIndex.isEnabled()){
|
||||||
|
dlg.startTask("Generating address index...", -1);
|
||||||
|
builder.buildAddress();
|
||||||
|
msg.append(", Address index ").append("successfully created");
|
||||||
|
}
|
||||||
|
msg.append(".");
|
||||||
|
JOptionPane pane = new JOptionPane(msg);
|
||||||
|
JDialog dialog = pane.createDialog(frame, "Generation data");
|
||||||
|
dialog.setVisible(true);
|
||||||
|
} catch (XMLStreamException e1) {
|
||||||
|
throw new IllegalArgumentException(e1);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
throw new IllegalArgumentException(e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dlg.run();
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
log.error("Interrupted", e1);
|
||||||
|
} catch (InvocationTargetException e1) {
|
||||||
|
ExceptionHandler.handle((Exception) e1.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void createCitySearchPanel(Container content){
|
public void createCitySearchPanel(Container content){
|
||||||
JPanel panel = new JPanel(new BorderLayout());
|
JPanel panel = new JPanel(new BorderLayout());
|
||||||
searchTextField = new JTextField();
|
searchTextField = new JTextField();
|
||||||
|
@ -564,7 +596,7 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveCountry(final File f){
|
public void saveCountry(final File f){
|
||||||
final OSMStorageWriter writer = new OSMStorageWriter(region.getStorage().getRegisteredEntities());
|
final OSMStorageWriter writer = new OSMStorageWriter();
|
||||||
try {
|
try {
|
||||||
final ProgressDialog dlg = new ProgressDialog(frame, "Saving osm file");
|
final ProgressDialog dlg = new ProgressDialog(frame, "Saving osm file");
|
||||||
dlg.setRunnable(new Runnable() {
|
dlg.setRunnable(new Runnable() {
|
||||||
|
@ -578,7 +610,7 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
output.write('Z');
|
output.write('Z');
|
||||||
output = new CBZip2OutputStream(output);
|
output = new CBZip2OutputStream(output);
|
||||||
}
|
}
|
||||||
writer.saveStorage(output, null, false);
|
writer.saveStorage(output, region.getStorage(), null, false);
|
||||||
} finally {
|
} finally {
|
||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue