Hi,
attached patch reorganizes the location-autofill parameter as discussed
before on this list.
* The location-autofill parameter has no longer the option bounds so
only the options nearest and is_in.
* If location-autofill is not set mkgmap does not try to find an
alternative location (so no city/region/country alternative)
* In case the city name of a POI or road is unknown the city name is
left empty (which means an empty string ""). For me this worked well but
Steve pointed out some doubts that it works. So please test carefully (a
good region for this to test is africa using precompiled bounds but no
location-autofill)
* The bounds and the location-autofill parameter have no longer a
default value
* It is now possible to set the bounds parameter but index not.
The help files need to be updated. I will do that before committing. But
please test first :-)
WanMil
Index: src/uk/me/parabola/mkgmap/build/MapBuilder.java
===================================================================
--- src/uk/me/parabola/mkgmap/build/MapBuilder.java (revision 2330)
+++ src/uk/me/parabola/mkgmap/build/MapBuilder.java (working copy)
@@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.Set;
import uk.me.parabola.imgfmt.ExitException;
import uk.me.parabola.imgfmt.app.Coord;
@@ -110,12 +111,16 @@
private final java.util.Map<String, Highway> highways = new HashMap<String, Highway>();
- private Country defaultCountry;
+ /** name that is used for cities which name are unknown */
+ private final static String UNKNOWN_CITY_NAME = "";
+ private Country defaultCountry;
private String countryName = "COUNTRY";
private String countryAbbr = "ABC";
private String regionName;
private String regionAbbr;
+
+ private Set<String> locationAutofill;
private int minSizePolygon;
private double reducePointError;
@@ -134,6 +139,7 @@
public MapBuilder() {
regionName = null;
+ locationAutofill = Collections.emptySet();
locator = new Locator();
}
@@ -159,7 +165,10 @@
licenseFileName = props.getProperty("license-file", null);
+ locationAutofill = LocatorUtil.parseAutofillOption(props);
+
locator = new Locator(props);
+ locator.setDefaultCountry(countryName, countryAbbr);
}
/**
@@ -184,6 +193,8 @@
}
}
+ normalizeCountries(src);
+
processCities(map, src);
processRoads(map,src);
processPOIs(map, src);
@@ -244,6 +255,41 @@
}
/**
+ * Process the country names of all elements and normalize them
+ * so that one consistent country name is used for the same country
+ * instead of different spellings.
+ * @param src the source of elements
+ */
+ private void normalizeCountries(MapDataSource src) {
+ for (MapPoint p : src.getPoints()) {
+ String countryStr = p.getCountry();
+ if (countryStr != null) {
+ countryStr = locator.normalizeCountry(countryStr);
+ p.setCountry(countryStr);
+ }
+ }
+
+ for (MapLine l : src.getLines()) {
+ String countryStr = l.getCountry();
+ if (countryStr != null) {
+ countryStr = locator.normalizeCountry(countryStr);
+ l.setCountry(countryStr);
+ }
+ }
+
+ // shapes do not have address information
+ // untag the following lines if this is wrong
+// for (MapShape s : src.getShapes()) {
+// String countryStr = s.getCountry();
+// if (countryStr != null) {
+// countryStr = locator.normalizeCountry(countryStr);
+// s.setCountry(countryStr);
+// }
+// }
+
+ }
+
+ /**
* Processing of Cities
*
* Fills the city list in lbl block that is required for find by name
@@ -255,28 +301,22 @@
*/
private void processCities(Map map, MapDataSource src) {
LBLFile lbl = map.getLblFile();
-
- locator.setDefaultCountry(countryName, countryAbbr);
- // collect the names of the cities
- for (MapPoint p : src.getPoints()) {
- if(p.isCity() && p.getName() != null)
- locator.addCityOrPlace(p); // Put the city info the map for missing info
- }
-
- locator.autofillCities(); // Try to fill missing information that include search of next city
+ if (locationAutofill.isEmpty() == false) {
+ // collect the names of the cities
+ for (MapPoint p : src.getPoints()) {
+ if(p.isCity() && p.getName() != null)
+ locator.addCityOrPlace(p); // Put the city info the map for missing info
+ }
+ locator.autofillCities(); // Try to fill missing information that include search of next city
+ }
+
for (MapPoint p : src.getPoints())
{
if(p.isCity() && p.getName() != null)
{
-
String countryStr = p.getCountry();
- if (countryStr != null) {
- countryStr = locator.normalizeCountry(countryStr);
- p.setCountry(countryStr);
- }
-
Country thisCountry;
if(countryStr != null) {
thisCountry = lbl.createCountry(countryStr, locator.getCountryISOCode(countryStr));
@@ -311,14 +351,10 @@
if(line.isRoad()) {
String cityName = line.getCity();
String cityCountryName = line.getCountry();
- if (cityCountryName != null) {
- cityCountryName = locator.normalizeCountry(cityCountryName);
- line.setCountry(cityCountryName);
- }
String cityRegionName = line.getRegion();
String zipStr = line.getZip();
- if(cityName == null) {
+ if(cityName == null && locationAutofill.contains("nearest")) {
// Get name of next city if untagged
searchPoint.setLocation(line.getLocation());
@@ -336,6 +372,12 @@
}
}
+ if (cityName == null && (cityCountryName != null || cityRegionName != null)) {
+ // if city name is unknown and region and/or country is known
+ // use empty name for the city
+ cityName = UNKNOWN_CITY_NAME;
+ }
+
if(cityName != null) {
Country cc = (cityCountryName == null)? getDefaultCountry() : lbl.createCountry(cityCountryName, locator.getCountryISOCode(cityCountryName));
@@ -380,10 +422,7 @@
String zipStr = p.getZip();
String cityStr = p.getCity();
- if(countryStr != null)
- countryStr = locator.normalizeCountry(countryStr);
-
- if(countryStr == null || regionStr == null || (zipStr == null && cityStr == null))
+ if(locationAutofill.contains("nearest") && (countryStr == null || regionStr == null || (zipStr == null && cityStr == null)))
{
MapPoint nextCity = locator.findNearbyCityByName(p);
@@ -429,6 +468,12 @@
POIRecord r = lbl.createPOI(p.getName());
+ if (cityStr == null && (countryStr != null || regionStr != null)) {
+ // if city name is unknown and region and/or country is known
+ // use empty name for the city
+ cityStr = UNKNOWN_CITY_NAME;
+ }
+
if(cityStr != null)
{
Country thisCountry;
@@ -500,14 +545,14 @@
if(hw == null)
hw = makeHighway(map, ref);
if(hw == null) {
- log.warn("Can't create exit " + mep.getName() + " (OSM id " + OSMId + ") on unknown highway " + ref);
+ log.warn("Can't create exit", mep.getName(), "(OSM id", OSMId, ") on unknown highway", ref);
return;
}
String exitName = mep.getName();
String exitTo = mep.getTo();
Exit exit = new Exit(hw);
String facilityDescription = mep.getFacilityDescription();
- log.info("Creating " + ref + " exit " + exitName + " (OSM id " + OSMId +") to " + exitTo + " with facility " + ((facilityDescription == null)? "(none)" : facilityDescription));
+ log.info("Creating", ref, "exit", exitName, "(OSM id", OSMId +") to", exitTo, "with facility", ((facilityDescription == null)? "(none)" : facilityDescription));
if(facilityDescription != null) {
// description is TYPE,DIR,FACILITIES,LABEL
// (same as Polish Format)
@@ -597,7 +642,7 @@
MapSplitter splitter = new MapSplitter(srcDivPair.getSource(), zoom);
MapArea[] areas = splitter.split();
- log.info("Map region " + srcDivPair.getSource().getBounds() + " split into " + areas.length + " areas at resolution " + zoom.getResolution());
+ log.info("Map region", srcDivPair.getSource().getBounds(), "split into", areas.length, "areas at resolution", zoom.getResolution());
for (MapArea area : areas) {
Subdivision parent = srcDivPair.getSubdiv();
Index: src/uk/me/parabola/mkgmap/build/LocatorUtil.java
===================================================================
--- src/uk/me/parabola/mkgmap/build/LocatorUtil.java (revision 2330)
+++ src/uk/me/parabola/mkgmap/build/LocatorUtil.java (working copy)
@@ -38,7 +38,7 @@
* @return the options
*/
public static Set<String> parseAutofillOption(EnhancedProperties props) {
- String optionStr = props.getProperty("location-autofill", "bounds");
+ String optionStr = props.getProperty("location-autofill", null);
if (optionStr == null) {
return Collections.emptySet();
}
Index: src/uk/me/parabola/mkgmap/reader/osm/LocationHook.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/LocationHook.java (revision 2330)
+++ src/uk/me/parabola/mkgmap/reader/osm/LocationHook.java (working copy)
@@ -15,11 +15,11 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
+
import uk.me.parabola.imgfmt.app.Coord;
import uk.me.parabola.log.Logger;
-import uk.me.parabola.mkgmap.build.LocatorUtil;
import uk.me.parabola.mkgmap.reader.osm.boundary.BoundaryGrid;
import uk.me.parabola.mkgmap.reader.osm.boundary.BoundaryQuadTree;
import uk.me.parabola.mkgmap.reader.osm.boundary.BoundaryUtil;
@@ -44,7 +44,6 @@
private String boundaryDirName;
- public static final String BOUNDS_OPTION = "bounds";
/** this static object is used to synchronize the check if the bounds directory contains any bounds */
private static final Object BOUNDS_CHECK_LOCK = new Object();
@@ -56,51 +55,41 @@
private EnhancedProperties props;
public boolean init(ElementSaver saver, EnhancedProperties props) {
- if (props.containsKey("index") == false) {
- log.info("Disable LocationHook because index option is not set.");
+ boundaryDirName = props.getProperty("bounds");
+
+ if (boundaryDirName == null) {
+ // bounds property not set
return false;
}
-
+
this.props = props;
this.saver = saver;
- autofillOptions.addAll(LocatorUtil.parseAutofillOption(props));
-
- if (autofillOptions.isEmpty()) {
- log.info("Disable LocationHook because no location-autofill option set.");
- return false;
- }
-
- if (autofillOptions.contains(BOUNDS_OPTION)) {
- boundaryDirName = props.getProperty("bounds", "bounds");
- long t1 = System.currentTimeMillis();
-
- synchronized (BOUNDS_CHECK_LOCK) {
- // checking of the boundary dir is expensive
- // check once only and reuse the result
- if (boundaryDirName.equals(checkedBoundaryDirName)) {
- if (checkBoundaryDirOk == false) {
- log.error("Disable LocationHook because boundary directory is unusable. Dir: "+boundaryDirName);
- return false;
- }
- } else {
- checkedBoundaryDirName = boundaryDirName;
- checkBoundaryDirOk = false;
+ long t1 = System.currentTimeMillis();
- // boundaryDir.list() is much quicker than boundaryDir.listFiles(FileFilter)
- List<String> boundaryFiles = BoundaryUtil.getBoundaryDirContent(boundaryDirName);
- if (boundaryFiles == null || boundaryFiles.size() == 0) {
- log.error("LocationHook is disabled because no boundary files are available. Dir: "
- + boundaryDirName);
- return false;
- }
+ synchronized (BOUNDS_CHECK_LOCK) {
+ // checking of the boundary dir is expensive
+ // check once only and reuse the result
+ if (boundaryDirName.equals(checkedBoundaryDirName)) {
+ if (checkBoundaryDirOk == false) {
+ log.error("Disable LocationHook because bounds directory is unusable. Dir: "+boundaryDirName);
+ return false;
+ }
+ } else {
+ checkedBoundaryDirName = boundaryDirName;
+ checkBoundaryDirOk = false;
- // passed all checks => boundaries are okay
- checkBoundaryDirOk = true;
+ List<String> boundaryFiles = BoundaryUtil.getBoundaryDirContent(boundaryDirName);
+ if (boundaryFiles == null || boundaryFiles.size() == 0) {
+ log.error("LocationHook is disabled because no bounds files are available. Dir: "
+ + boundaryDirName);
+ return false;
}
+ // passed all checks => boundaries are okay
+ checkBoundaryDirOk = true;
}
- log.info("Checking bounds dir took", (System.currentTimeMillis() - t1), "ms");
}
+ log.info("Checking bounds dir took", (System.currentTimeMillis() - t1), "ms");
return true;
}
@@ -108,10 +97,8 @@
long t1 = System.currentTimeMillis();
log.info("Starting with location hook");
- if (autofillOptions.contains(BOUNDS_OPTION)) {
- boundaryGrid = new BoundaryGrid(boundaryDirName, saver.getBoundingBox(), props);
- processLocationRelevantElements();
- }
+ boundaryGrid = new BoundaryGrid(boundaryDirName, saver.getBoundingBox(), props);
+ processLocationRelevantElements();
long dt = (System.currentTimeMillis() - t1);
log.info("======= LocationHook Stats =====");
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryPreparer.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryPreparer.java (revision 2330)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryPreparer.java (working copy)
@@ -109,9 +109,9 @@
if (workoutOnly)
return true;
this.boundaryFilename = props.getProperty("createboundsfile", null);
- this.inDir = props.getProperty("bounds", "bounds");
- this.outDir = props.getProperty("bounds", "bounds");
- return boundaryFilename != null;
+ this.inDir = props.getProperty("bounds", null);
+ this.outDir = props.getProperty("bounds", null);
+ return boundaryFilename != null && this.inDir != null && this.outDir != null;
}
public void run() {
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryUtil.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryUtil.java (revision 2330)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryUtil.java (working copy)
@@ -440,6 +440,7 @@
log.error("boundary directory/zip does not exist: " + dirName);
else{
if (boundaryDir.isDirectory()){
+ // boundaryDir.list() is much quicker than boundaryDir.listFiles(FileFilter)
String[] allNames = boundaryDir.list();
for (String name: allNames){
if (name.endsWith(".bnd"))
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev