add basic implementation for normalizing street
git-svn-id: https://osmand.googlecode.com/svn/trunk@67 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
31a56b670a
commit
79c03f09b4
14 changed files with 293 additions and 56 deletions
|
@ -38,6 +38,18 @@ public class Algoritms {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int extractFirstIntegerNumber(String s) {
|
||||||
|
int i = 0;
|
||||||
|
for (int k = 0; k < s.length(); k++) {
|
||||||
|
if (Character.isDigit(s.charAt(k))) {
|
||||||
|
i = i * 10 + (s.charAt(k) - '0');
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void streamCopy(InputStream in, OutputStream out) throws IOException{
|
public static void streamCopy(InputStream in, OutputStream out) throws IOException{
|
||||||
byte[] b = new byte[BUFFER_SIZE];
|
byte[] b = new byte[BUFFER_SIZE];
|
||||||
|
|
|
@ -23,5 +23,6 @@ public interface IProgress {
|
||||||
|
|
||||||
public boolean isIndeterminate();
|
public boolean isIndeterminate();
|
||||||
|
|
||||||
|
public boolean isInterrupted();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class ToDoConstants {
|
||||||
// 10. Specify auto-rotating map (compass).
|
// 10. Specify auto-rotating map (compass).
|
||||||
// 11. Print out additional info speed, altitude, number of satellites
|
// 11. Print out additional info speed, altitude, number of satellites
|
||||||
// 12. Show point where are you going (the arrow not the point)
|
// 12. Show point where are you going (the arrow not the point)
|
||||||
// 13. Save point as favourite
|
// 13. Save point as favourit
|
||||||
// 14. Show zoom level directly on map
|
// 14. Show zoom level directly on map
|
||||||
// -------------------
|
// -------------------
|
||||||
|
|
||||||
|
@ -48,7 +48,6 @@ public class ToDoConstants {
|
||||||
/// SWING version :
|
/// SWING version :
|
||||||
// TODO :
|
// TODO :
|
||||||
// 1. Add preferences dialog (use internet, )
|
// 1. Add preferences dialog (use internet, )
|
||||||
// 2. implement bundle downloading tiles ()
|
|
||||||
// 3. download tiles without using dir tiles
|
// 3. download tiles without using dir tiles
|
||||||
// 4. Config file log & see log from file
|
// 4. Config file log & see log from file
|
||||||
// 6. Predefine before file loading what should be extracted from osm (building, poi or roads)
|
// 6. Predefine before file loading what should be extracted from osm (building, poi or roads)
|
||||||
|
|
|
@ -86,23 +86,16 @@ public class Amenity extends MapObject<Node> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private final Node node;
|
|
||||||
private String subType;
|
private String subType;
|
||||||
private AmenityType type;
|
private AmenityType type;
|
||||||
|
|
||||||
public Amenity(Node node){
|
public Amenity(Node node){
|
||||||
this.node = node;
|
this.entity = node;
|
||||||
this.type = getType(node);
|
this.type = getType(node);
|
||||||
this.subType = getSubType(node);
|
this.subType = getSubType(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Amenity(){
|
public Amenity(){
|
||||||
this.node = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node getEntity() {
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getSubType(Node node){
|
protected String getSubType(Node node){
|
||||||
|
@ -148,6 +141,7 @@ public class Amenity extends MapObject<Node> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAmenity(Entity n){
|
public static boolean isAmenity(Entity n){
|
||||||
|
// TODO allow ways to be amenity!
|
||||||
if(!(n instanceof Node)){
|
if(!(n instanceof Node)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -165,9 +159,8 @@ public class Amenity extends MapObject<Node> {
|
||||||
|
|
||||||
|
|
||||||
public String getSimpleFormat(){
|
public String getSimpleFormat(){
|
||||||
String name = getName();
|
|
||||||
return Algoritms.capitalizeFirstLetterAndLowercase(getType().toString()) +
|
return Algoritms.capitalizeFirstLetterAndLowercase(getType().toString()) +
|
||||||
" : " + getSubType() + " " +(name == null ? node.getId() : name);
|
" : " + getSubType() + " " +getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringWithoutType(){
|
public String getStringWithoutType(){
|
||||||
|
|
|
@ -12,7 +12,8 @@ import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
public class City extends MapObject<Node> {
|
public class City extends MapObject<Node> {
|
||||||
|
|
||||||
public enum CityType {
|
public enum CityType {
|
||||||
CITY(10000), TOWN(5000), VILLAGE(1000), HAMLET(300), SUBURB(300);
|
// that's tricky way to play with that numbers (to avoid including suburbs in city & vice verse)
|
||||||
|
CITY(10000), TOWN(5000), VILLAGE(1300), HAMLET(1000), SUBURB(300);
|
||||||
|
|
||||||
private double radius;
|
private double radius;
|
||||||
|
|
||||||
|
@ -42,6 +43,7 @@ public class City extends MapObject<Node> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private CityType type = null;
|
private CityType type = null;
|
||||||
|
// Be attentive ! Working with street names ignoring case
|
||||||
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){
|
||||||
|
@ -53,16 +55,30 @@ public class City extends MapObject<Node> {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Street registerStreet(String street){
|
public Street registerStreet(String street){
|
||||||
if(!streets.containsKey(street)){
|
if(!streets.containsKey(street.toLowerCase())){
|
||||||
streets.put(street, new Street(street));
|
streets.put(street.toLowerCase(), new Street(this, street));
|
||||||
}
|
}
|
||||||
return streets.get(street);
|
return streets.get(street.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Street unregisterStreet(String name){
|
||||||
|
return streets.remove(name.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Street registerStreet(Street street){
|
public Street registerStreet(Street street){
|
||||||
if(!Algoritms.isEmpty(street.getName())){
|
String name = street.getName().toLowerCase();
|
||||||
return streets.put(street.getName(), street);
|
if(!Algoritms.isEmpty(name)){
|
||||||
|
if(!streets.containsKey(name)){
|
||||||
|
return streets.put(name, street);
|
||||||
|
} else {
|
||||||
|
// try to merge streets
|
||||||
|
Street prev = streets.get(name);
|
||||||
|
prev.getWayNodes().addAll(street.getWayNodes());
|
||||||
|
prev.getBuildings().addAll(street.getBuildings());
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -72,12 +88,11 @@ public class City extends MapObject<Node> {
|
||||||
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);
|
registerStreet(street).registerBuilding(e);
|
||||||
return streets.get(street);
|
return streets.get(street.toLowerCase());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CityType getType(){
|
public CityType getType(){
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +101,10 @@ public class City extends MapObject<Node> {
|
||||||
return streets.values();
|
return streets.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Street getStreet(String name){
|
||||||
|
return streets.get(name.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "City [" +type+"] " + getName();
|
return "City [" +type+"] " + getName();
|
||||||
|
|
|
@ -120,8 +120,10 @@ public class Region extends MapObject<Entity> {
|
||||||
|
|
||||||
public void registerAmenity(Amenity a){
|
public void registerAmenity(Amenity a){
|
||||||
LatLon location = a.getLocation();
|
LatLon location = a.getLocation();
|
||||||
|
if(location != null){
|
||||||
amenities.registerObject(location.getLatitude(), location.getLongitude(), a);
|
amenities.registerObject(location.getLatitude(), location.getLongitude(), a);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void registerCity(City city){
|
public void registerCity(City city){
|
||||||
if(city.getType() != null && !Algoritms.isEmpty(city.getName()) && city.getLocation() != null){
|
if(city.getType() != null && !Algoritms.isEmpty(city.getName()) && city.getLocation() != null){
|
||||||
|
|
|
@ -2,24 +2,31 @@ package com.osmand.data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.osmand.Algoritms;
|
||||||
import com.osmand.osm.Entity;
|
import com.osmand.osm.Entity;
|
||||||
import com.osmand.osm.LatLon;
|
import com.osmand.osm.LatLon;
|
||||||
import com.osmand.osm.MapUtils;
|
import com.osmand.osm.MapUtils;
|
||||||
import com.osmand.osm.Node;
|
import com.osmand.osm.Node;
|
||||||
|
import com.osmand.osm.Way;
|
||||||
import com.osmand.osm.OSMSettings.OSMTagKey;
|
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
|
|
||||||
public class Street extends MapObject<Entity> {
|
public class Street extends MapObject<Entity> {
|
||||||
|
|
||||||
private List<Building> buildings = new ArrayList<Building>();
|
private List<Building> buildings = new ArrayList<Building>();
|
||||||
private List<Node> wayNodes = new ArrayList<Node>();
|
private List<Way> wayNodes = new ArrayList<Way>();
|
||||||
|
private final City city;
|
||||||
|
|
||||||
public Street(String name){
|
public Street(City city, String name){
|
||||||
|
this.city = city;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Street(){}
|
public Street(City city) {
|
||||||
|
this.city = city;
|
||||||
|
}
|
||||||
|
|
||||||
public void registerBuilding(Entity e){
|
public void registerBuilding(Entity e){
|
||||||
Building building = new Building(e);
|
Building building = new Building(e);
|
||||||
|
@ -47,9 +54,14 @@ public class Street extends MapObject<Entity> {
|
||||||
entity = wayNodes.get(0);
|
entity = wayNodes.get(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LatLon c = MapUtils.getWeightCenterForNodes(wayNodes);
|
List<Node> nodes = new ArrayList<Node>();
|
||||||
|
for(Way w : wayNodes){
|
||||||
|
nodes.addAll(w.getNodes());
|
||||||
|
}
|
||||||
|
|
||||||
|
LatLon c = MapUtils.getWeightCenterForNodes(nodes);
|
||||||
double dist = Double.POSITIVE_INFINITY;
|
double dist = Double.POSITIVE_INFINITY;
|
||||||
for(Node n : wayNodes){
|
for(Node n : nodes){
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
double nd = MapUtils.getDistance(n, c);
|
double nd = MapUtils.getDistance(n, c);
|
||||||
if (nd < dist) {
|
if (nd < dist) {
|
||||||
|
@ -60,14 +72,34 @@ public class Street extends MapObject<Entity> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setName(String name) {
|
||||||
|
if(name.equals(getName())){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Street unregisterStreet = city.unregisterStreet(getName());
|
||||||
|
assert unregisterStreet == this;
|
||||||
|
super.setName(name);
|
||||||
|
city.registerStreet(this);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Node> getWayNodes() {
|
|
||||||
|
public List<Way> getWayNodes() {
|
||||||
return wayNodes;
|
return wayNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doDataPreparation() {
|
public void doDataPreparation() {
|
||||||
calculateCenter();
|
calculateCenter();
|
||||||
Collections.sort(buildings);
|
Collections.sort(buildings, new Comparator<Building>(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Building o1, Building o2) {
|
||||||
|
int i1 = Algoritms.extractFirstIntegerNumber(o1.getName());
|
||||||
|
int i2 = Algoritms.extractFirstIntegerNumber(o2.getName());
|
||||||
|
return i1 - i2;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,8 @@ import com.osmand.osm.OSMSettings;
|
||||||
import com.osmand.osm.Way;
|
import com.osmand.osm.Way;
|
||||||
import com.osmand.osm.OSMSettings.OSMTagKey;
|
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
import com.osmand.osm.io.IOsmStorageFilter;
|
import com.osmand.osm.io.IOsmStorageFilter;
|
||||||
import com.osmand.osm.io.OsmStorageWriter;
|
|
||||||
import com.osmand.osm.io.OsmBaseStorage;
|
import com.osmand.osm.io.OsmBaseStorage;
|
||||||
|
import com.osmand.osm.io.OsmStorageWriter;
|
||||||
|
|
||||||
|
|
||||||
// TO implement
|
// TO implement
|
||||||
|
@ -210,6 +210,9 @@ public class DataExtraction {
|
||||||
// 5. reading buildings
|
// 5. reading buildings
|
||||||
readingBuildings(progress, buildings, country);
|
readingBuildings(progress, buildings, country);
|
||||||
|
|
||||||
|
// 6. normalizing streets
|
||||||
|
normalizingStreets(progress, country);
|
||||||
|
|
||||||
country.doDataPreparation();
|
country.doDataPreparation();
|
||||||
return country;
|
return country;
|
||||||
}
|
}
|
||||||
|
@ -262,9 +265,7 @@ public class DataExtraction {
|
||||||
|
|
||||||
if (city != null) {
|
if (city != null) {
|
||||||
Street str = city.registerStreet(street);
|
Street str = city.registerStreet(street);
|
||||||
for (Node n : w.getNodes()) {
|
str.getWayNodes().add(w);
|
||||||
str.getWayNodes().add(n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
waysManager.registerObject(center.getLatitude(), center.getLongitude(), w);
|
waysManager.registerObject(center.getLatitude(), center.getLongitude(), w);
|
||||||
}
|
}
|
||||||
|
@ -291,5 +292,87 @@ public class DataExtraction {
|
||||||
country.registerCity(s);
|
country.registerCity(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
String[] SUFFIXES = new String[] {"просп.", "пер.", "пр.","заул.", "проспект", "переул.", "бул.", "бульвар"};
|
||||||
|
String[] DEFAUTL_SUFFIXES = new String[] {"улица", "ул."};
|
||||||
|
|
||||||
|
private int checkSuffix(String name, String suffix){
|
||||||
|
int i = -1;
|
||||||
|
boolean searchAgain = false;
|
||||||
|
do {
|
||||||
|
i = name.indexOf(suffix, i);
|
||||||
|
searchAgain = false;
|
||||||
|
if (i > 0) {
|
||||||
|
if (Character.isLetterOrDigit(name.charAt(i -1))) {
|
||||||
|
i ++;
|
||||||
|
searchAgain = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (searchAgain);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cutSuffix(String name, int ind, int suffixLength){
|
||||||
|
String newName = name.substring(0, ind);
|
||||||
|
if (name.length() > ind + suffixLength + 1) {
|
||||||
|
newName += name.substring(ind + suffixLength + 1);
|
||||||
|
}
|
||||||
|
return newName.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String putSuffixToEnd(String name, int ind, int suffixLength) {
|
||||||
|
if (name.length() <= ind + suffixLength) {
|
||||||
|
return name;
|
||||||
|
|
||||||
|
}
|
||||||
|
String newName;
|
||||||
|
if(ind > 0){
|
||||||
|
newName = name.substring(0, ind);
|
||||||
|
newName += name.substring(ind + suffixLength);
|
||||||
|
newName += name.substring(ind - 1, ind + suffixLength );
|
||||||
|
} else {
|
||||||
|
newName = name.substring(suffixLength + 1) + name.charAt(suffixLength) + name.substring(0, suffixLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newName.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void normalizingStreets(IProgress progress, Region region){
|
||||||
|
progress.startTask("Normalizing name streets...", -1);
|
||||||
|
for(CityType t : CityType.values()){
|
||||||
|
for(City c : region.getCitiesByType(t)){
|
||||||
|
ArrayList<Street> list = new ArrayList<Street>(c.getStreets());
|
||||||
|
for (Street s : list) {
|
||||||
|
String name = s.getName();
|
||||||
|
String newName = name.trim();
|
||||||
|
boolean processed = newName.length() != name.length();
|
||||||
|
for (String ch : DEFAUTL_SUFFIXES) {
|
||||||
|
int ind = checkSuffix(newName, ch);
|
||||||
|
if (ind != -1) {
|
||||||
|
newName = cutSuffix(newName, ind, ch.length());
|
||||||
|
processed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!processed) {
|
||||||
|
for (String ch : SUFFIXES) {
|
||||||
|
int ind = checkSuffix(newName, ch);
|
||||||
|
if (ind != -1) {
|
||||||
|
newName = putSuffixToEnd(newName, ind, ch.length());
|
||||||
|
processed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (processed) {
|
||||||
|
if(c.getStreet(name) != s){
|
||||||
|
System.out.println(name);
|
||||||
|
}
|
||||||
|
s.setName(newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,4 +69,9 @@ public class ConsoleProgressImplementation implements IProgress {
|
||||||
this.lastPercentPrint = 0;
|
this.lastPercentPrint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInterrupted() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class OsmIndexStorage extends OsmBaseStorage {
|
||||||
currentParsedCity = c;
|
currentParsedCity = c;
|
||||||
} else if(ELEM_STREET.equals(name)){
|
} else if(ELEM_STREET.equals(name)){
|
||||||
assert currentParsedCity != null;
|
assert currentParsedCity != null;
|
||||||
Street street = new Street();
|
Street street = new Street(currentParsedCity);
|
||||||
parseMapObject(street, attributes);
|
parseMapObject(street, attributes);
|
||||||
currentParsedCity.registerStreet(street);
|
currentParsedCity.registerStreet(street);
|
||||||
currentParsedStreet = street;
|
currentParsedStreet = street;
|
||||||
|
|
|
@ -18,6 +18,9 @@ import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseWheelEvent;
|
import java.awt.event.MouseWheelEvent;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -54,8 +57,11 @@ import com.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback;
|
||||||
import com.osmand.map.ITileSource;
|
import com.osmand.map.ITileSource;
|
||||||
import com.osmand.map.TileSourceManager;
|
import com.osmand.map.TileSourceManager;
|
||||||
import com.osmand.map.TileSourceManager.TileSourceTemplate;
|
import com.osmand.map.TileSourceManager.TileSourceTemplate;
|
||||||
|
import com.osmand.osm.Entity;
|
||||||
import com.osmand.osm.LatLon;
|
import com.osmand.osm.LatLon;
|
||||||
import com.osmand.osm.MapUtils;
|
import com.osmand.osm.MapUtils;
|
||||||
|
import com.osmand.osm.Node;
|
||||||
|
import com.osmand.osm.Way;
|
||||||
|
|
||||||
public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
||||||
|
|
||||||
|
@ -130,7 +136,7 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
||||||
|
|
||||||
|
|
||||||
// special points to draw
|
// special points to draw
|
||||||
private DataTileManager<LatLon> points;
|
private DataTileManager<? extends Entity> points;
|
||||||
|
|
||||||
// zoom level
|
// zoom level
|
||||||
private int zoom = 1;
|
private int zoom = 1;
|
||||||
|
@ -152,6 +158,7 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
||||||
private int xStartingImage = 0;
|
private int xStartingImage = 0;
|
||||||
private int yStartingImage = 0;
|
private int yStartingImage = 0;
|
||||||
private List<Point> pointsToDraw = new ArrayList<Point>();
|
private List<Point> pointsToDraw = new ArrayList<Point>();
|
||||||
|
private List<Line2D> linesToDraw = new ArrayList<Line2D>();
|
||||||
|
|
||||||
private MapTileDownloader downloader = MapTileDownloader.getInstance();
|
private MapTileDownloader downloader = MapTileDownloader.getInstance();
|
||||||
Map<String, Image> cache = new HashMap<String, Image>();
|
Map<String, Image> cache = new HashMap<String, Image>();
|
||||||
|
@ -235,6 +242,30 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
||||||
g.fillOval(p.x, p.y, 3, 3);
|
g.fillOval(p.x, p.y, 3, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g.setColor(Color.orange);
|
||||||
|
// draw user points
|
||||||
|
int[] xPoints = new int[4];
|
||||||
|
int[] yPoints = new int[4];
|
||||||
|
for (Line2D p : linesToDraw) {
|
||||||
|
AffineTransform transform = new AffineTransform();
|
||||||
|
|
||||||
|
transform.translate(p.getX1(), p.getY1());
|
||||||
|
// transform.scale(p.getX2() - p.getX1(), p.getY2() - p.getY1());
|
||||||
|
transform.rotate(p.getX2() - p.getX1(), p.getY2() - p.getY1());
|
||||||
|
xPoints[1] = xPoints[0] = 0;
|
||||||
|
xPoints[2] = xPoints[3] = (int) Math.sqrt((p.getX2() - p.getX1())*(p.getX2() - p.getX1()) +
|
||||||
|
(p.getY2() - p.getY1())*(p.getY2() - p.getY1())) +1;
|
||||||
|
yPoints[3] = yPoints[0] = 0;
|
||||||
|
yPoints[2] = yPoints[1] = 2;
|
||||||
|
for(int i=0; i< 4; i++){
|
||||||
|
Point2D po = transform.transform(new Point(xPoints[i], yPoints[i]), null);
|
||||||
|
xPoints[i] = (int) po.getX();
|
||||||
|
yPoints[i] = (int) po.getY();
|
||||||
|
}
|
||||||
|
g.drawPolygon(xPoints, yPoints, 4);
|
||||||
|
g.fillPolygon(xPoints, yPoints, 4);
|
||||||
|
}
|
||||||
|
|
||||||
if(selectionArea.isVisible()){
|
if(selectionArea.isVisible()){
|
||||||
g.setColor(new Color(0, 0, 230, 50));
|
g.setColor(new Color(0, 0, 230, 50));
|
||||||
Rectangle r = selectionArea.getSelectedArea();
|
Rectangle r = selectionArea.getSelectedArea();
|
||||||
|
@ -374,14 +405,36 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
||||||
double longDown = MapUtils.getLongitudeFromTile(zoom, xTileRight);
|
double longDown = MapUtils.getLongitudeFromTile(zoom, xTileRight);
|
||||||
double latUp = MapUtils.getLatitudeFromTile(zoom, yTileUp);
|
double latUp = MapUtils.getLatitudeFromTile(zoom, yTileUp);
|
||||||
double longUp = MapUtils.getLongitudeFromTile(zoom, xTileLeft);
|
double longUp = MapUtils.getLongitudeFromTile(zoom, xTileLeft);
|
||||||
List<LatLon> objects = points.getObjects(latUp, longUp, latDown, longDown);
|
List<? extends Entity> objects = points.getObjects(latUp, longUp, latDown, longDown);
|
||||||
pointsToDraw.clear();
|
pointsToDraw.clear();
|
||||||
for (LatLon n : objects) {
|
linesToDraw.clear();
|
||||||
|
for (Entity e : objects) {
|
||||||
|
if(e instanceof Way){
|
||||||
|
List<Node> nodes = ((Way)e).getNodes();
|
||||||
|
if (nodes.size() > 1) {
|
||||||
|
int prevPixX = 0;
|
||||||
|
int prevPixY = 0;
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
Node n = nodes.get(i);
|
||||||
|
int pixX = MapUtils.getPixelShiftX(zoom, n.getLongitude(), this.longitude, tileSize) + getWidth() / 2;
|
||||||
|
int pixY = MapUtils.getPixelShiftY(zoom, n.getLatitude(), this.latitude, tileSize) + getHeight() / 2;
|
||||||
|
if (i > 0) {
|
||||||
|
linesToDraw.add(new Line2D.Float(pixX, pixY, prevPixX, prevPixY));
|
||||||
|
}
|
||||||
|
prevPixX = pixX;
|
||||||
|
prevPixY = pixY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(e instanceof Node){
|
||||||
|
Node n = (Node) e;
|
||||||
int pixX = MapUtils.getPixelShiftX(zoom, n.getLongitude(), this.longitude, tileSize) + getWidth() / 2;
|
int pixX = MapUtils.getPixelShiftX(zoom, n.getLongitude(), this.longitude, tileSize) + getWidth() / 2;
|
||||||
int pixY = MapUtils.getPixelShiftY(zoom, n.getLatitude(), this.latitude, tileSize) + getHeight() / 2;
|
int pixY = MapUtils.getPixelShiftY(zoom, n.getLatitude(), this.latitude, tileSize) + getHeight() / 2;
|
||||||
if (pixX >= 0 && pixY >= 0) {
|
if (pixX >= 0 && pixY >= 0) {
|
||||||
pointsToDraw.add(new Point(pixX, pixY));
|
pointsToDraw.add(new Point(pixX, pixY));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,11 +557,11 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
||||||
super.processKeyEvent(e);
|
super.processKeyEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTileManager<LatLon> getPoints() {
|
public DataTileManager<? extends Entity> getPoints() {
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPoints(DataTileManager<LatLon> points) {
|
public void setPoints(DataTileManager<? extends Entity> points) {
|
||||||
this.points = points;
|
this.points = points;
|
||||||
prepareImage();
|
prepareImage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ import com.osmand.IMapLocationListener;
|
||||||
import com.osmand.data.Amenity;
|
import com.osmand.data.Amenity;
|
||||||
import com.osmand.data.Building;
|
import com.osmand.data.Building;
|
||||||
import com.osmand.data.City;
|
import com.osmand.data.City;
|
||||||
|
import com.osmand.data.DataTileManager;
|
||||||
import com.osmand.data.MapObject;
|
import com.osmand.data.MapObject;
|
||||||
import com.osmand.data.Region;
|
import com.osmand.data.Region;
|
||||||
import com.osmand.data.Street;
|
import com.osmand.data.Street;
|
||||||
|
@ -79,6 +80,7 @@ import com.osmand.osm.Entity;
|
||||||
import com.osmand.osm.LatLon;
|
import com.osmand.osm.LatLon;
|
||||||
import com.osmand.osm.MapUtils;
|
import com.osmand.osm.MapUtils;
|
||||||
import com.osmand.osm.Node;
|
import com.osmand.osm.Node;
|
||||||
|
import com.osmand.osm.Way;
|
||||||
import com.osmand.osm.io.IOsmStorageFilter;
|
import com.osmand.osm.io.IOsmStorageFilter;
|
||||||
import com.osmand.osm.io.OsmStorageWriter;
|
import com.osmand.osm.io.OsmStorageWriter;
|
||||||
import com.osmand.osm.io.OsmBoundsFilter;
|
import com.osmand.osm.io.OsmBoundsFilter;
|
||||||
|
@ -109,11 +111,13 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
private JButton generateDataButton;
|
private JButton generateDataButton;
|
||||||
private JCheckBox buildPoiIndex;
|
private JCheckBox buildPoiIndex;
|
||||||
private JCheckBox buildAddressIndex;
|
private JCheckBox buildAddressIndex;
|
||||||
|
private JCheckBox normalizingStreets;
|
||||||
private TreeModelListener treeModelListener;
|
private TreeModelListener treeModelListener;
|
||||||
private JCheckBox zipIndexFiles;
|
private JCheckBox zipIndexFiles;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public OsmExtractionUI(final Region r){
|
public OsmExtractionUI(final Region r){
|
||||||
this.region = r;
|
this.region = r;
|
||||||
createUI();
|
createUI();
|
||||||
|
@ -127,14 +131,14 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
}
|
}
|
||||||
this.region = region;
|
this.region = region;
|
||||||
DefaultMutableTreeNode root = new DataExtractionTreeNode(name, region);
|
DefaultMutableTreeNode root = new DataExtractionTreeNode(name, region);
|
||||||
|
if (region != null) {
|
||||||
amenitiesTree = new DataExtractionTreeNode("Closest amenities", region);
|
amenitiesTree = new DataExtractionTreeNode("Closest amenities", region);
|
||||||
amenitiesTree.add(new DataExtractionTreeNode("First 15", region));
|
amenitiesTree.add(new DataExtractionTreeNode("First 15", region));
|
||||||
for(AmenityType type : AmenityType.values()){
|
for (AmenityType type : AmenityType.values()) {
|
||||||
amenitiesTree.add(new DataExtractionTreeNode(Algoritms.capitalizeFirstLetterAndLowercase(type.toString()), type));
|
amenitiesTree.add(new DataExtractionTreeNode(Algoritms.capitalizeFirstLetterAndLowercase(type.toString()), type));
|
||||||
}
|
}
|
||||||
root.add(amenitiesTree);
|
root.add(amenitiesTree);
|
||||||
|
|
||||||
if (region != null) {
|
|
||||||
for (CityType t : CityType.values()) {
|
for (CityType t : CityType.values()) {
|
||||||
DefaultMutableTreeNode cityTree = new DataExtractionTreeNode(Algoritms.capitalizeFirstLetterAndLowercase(t.toString()), t);
|
DefaultMutableTreeNode cityTree = new DataExtractionTreeNode(Algoritms.capitalizeFirstLetterAndLowercase(t.toString()), t);
|
||||||
root.add(cityTree);
|
root.add(cityTree);
|
||||||
|
@ -169,7 +173,9 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
DefaultTreeModel newModel = new DefaultTreeModel(root, false);
|
DefaultTreeModel newModel = new DefaultTreeModel(root, false);
|
||||||
newModel.addTreeModelListener(treeModelListener);
|
newModel.addTreeModelListener(treeModelListener);
|
||||||
treePlaces.setModel(newModel);
|
treePlaces.setModel(newModel);
|
||||||
|
|
||||||
updateButtonsBar();
|
updateButtonsBar();
|
||||||
|
locationChanged(mapPanel.getLatitude(), mapPanel.getLongitude(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,6 +243,15 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
MapObject<Entity> c = (MapObject<Entity>) o;
|
MapObject<Entity> c = (MapObject<Entity>) o;
|
||||||
LatLon location = c.getLocation();
|
LatLon location = c.getLocation();
|
||||||
if(location != null){
|
if(location != null){
|
||||||
|
if(o instanceof Street){
|
||||||
|
DataTileManager<Way> ways = new DataTileManager<Way>();
|
||||||
|
for(Way w : ((Street)o).getWayNodes()){
|
||||||
|
LatLon l = w.getLatLon();
|
||||||
|
ways.registerObject(l.getLatitude(), l.getLongitude(), w);
|
||||||
|
}
|
||||||
|
mapPanel.setPoints(ways);
|
||||||
|
mapPanel.requestFocus();
|
||||||
|
}
|
||||||
mapPanel.setLatLon(location.getLatitude(), location.getLongitude());
|
mapPanel.setLatLon(location.getLatitude(), location.getLongitude());
|
||||||
mapPanel.requestFocus();
|
mapPanel.requestFocus();
|
||||||
}
|
}
|
||||||
|
@ -283,9 +298,10 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
|
|
||||||
protected void updateButtonsBar() {
|
protected void updateButtonsBar() {
|
||||||
generateDataButton.setEnabled(region != null);
|
generateDataButton.setEnabled(region != null);
|
||||||
buildAddressIndex.setEnabled(generateDataButton.isEnabled() && region.getCitiesCount(null) > 0);
|
normalizingStreets.setVisible(region == null);
|
||||||
buildPoiIndex.setEnabled(generateDataButton.isEnabled() && !region.getAmenityManager().isEmpty());
|
buildAddressIndex.setEnabled(region == null || region.getCitiesCount(null) > 0);
|
||||||
zipIndexFiles.setEnabled(generateDataButton.isEnabled());
|
buildPoiIndex.setEnabled(region == null || !region.getAmenityManager().isEmpty());
|
||||||
|
zipIndexFiles.setVisible(region != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createButtonsBar(Container content){
|
public void createButtonsBar(Container content){
|
||||||
|
@ -293,13 +309,11 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
content.add(panel, BorderLayout.NORTH);
|
content.add(panel, BorderLayout.NORTH);
|
||||||
|
|
||||||
generateDataButton = new JButton();
|
generateDataButton = new JButton();
|
||||||
generateDataButton.setText("Generate data ");
|
generateDataButton.setText("Generate data");
|
||||||
generateDataButton.setToolTipText("Data with selected preferences will be generated in working directory." +
|
generateDataButton.setToolTipText("Data with selected preferences will be generated in working directory." +
|
||||||
" The index files will be named as region in tree. All existing data will be overwritten.");
|
" The index files will be named as region in tree. All existing data will be overwritten.");
|
||||||
panel.add(generateDataButton);
|
panel.add(generateDataButton);
|
||||||
|
|
||||||
generateDataButton.addActionListener(new ActionListener(){
|
generateDataButton.addActionListener(new ActionListener(){
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
generateData();
|
generateData();
|
||||||
|
@ -316,6 +330,11 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
panel.add(buildAddressIndex);
|
panel.add(buildAddressIndex);
|
||||||
buildAddressIndex.setSelected(true);
|
buildAddressIndex.setSelected(true);
|
||||||
|
|
||||||
|
normalizingStreets = new JCheckBox();
|
||||||
|
normalizingStreets.setText("Normalizing streets");
|
||||||
|
panel.add(normalizingStreets);
|
||||||
|
normalizingStreets.setSelected(true);
|
||||||
|
|
||||||
zipIndexFiles = new JCheckBox();
|
zipIndexFiles = new JCheckBox();
|
||||||
zipIndexFiles.setText("Zip index files");
|
zipIndexFiles.setText("Zip index files");
|
||||||
panel.add(zipIndexFiles);
|
panel.add(zipIndexFiles);
|
||||||
|
@ -438,6 +457,8 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
menu.add(loadFile);
|
menu.add(loadFile);
|
||||||
JMenuItem loadSpecifiedAreaFile = new JMenuItem("Load osm file for specifed area...");
|
JMenuItem loadSpecifiedAreaFile = new JMenuItem("Load osm file for specifed area...");
|
||||||
menu.add(loadSpecifiedAreaFile);
|
menu.add(loadSpecifiedAreaFile);
|
||||||
|
JMenuItem closeCurrentFile = new JMenuItem("Close current file");
|
||||||
|
menu.add(closeCurrentFile);
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
JMenuItem saveOsmFile = new JMenuItem("Save data to osm file...");
|
JMenuItem saveOsmFile = new JMenuItem("Save data to osm file...");
|
||||||
menu.add(saveOsmFile);
|
menu.add(saveOsmFile);
|
||||||
|
@ -455,6 +476,15 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
frame.setVisible(false);
|
frame.setVisible(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
closeCurrentFile.addActionListener(new ActionListener(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
setRegion(null, "Region");
|
||||||
|
frame.setTitle("OsmAnd Map Creator");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
specifyWorkingDir.addActionListener(new ActionListener(){
|
specifyWorkingDir.addActionListener(new ActionListener(){
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -39,6 +39,10 @@ public class ProgressDialog extends JDialog implements IProgress {
|
||||||
initDialog();
|
initDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInterrupted(){
|
||||||
|
return !isVisible();
|
||||||
|
}
|
||||||
|
|
||||||
public Object run() throws InvocationTargetException, InterruptedException {
|
public Object run() throws InvocationTargetException, InterruptedException {
|
||||||
result = null;
|
result = null;
|
||||||
new WorkerThread().start();
|
new WorkerThread().start();
|
||||||
|
|
|
@ -81,6 +81,10 @@ public class ProgressDialogImplementation implements IProgress {
|
||||||
work = -1;
|
work = -1;
|
||||||
progress = 0;
|
progress = 0;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public boolean isInterrupted() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue