Subversion Repositories mkgmap

Rev

Blame | Last modification | View Log | RSS feed

Index: doc/addresses/address.txt
===================================================================
--- doc/addresses/address.txt   (revision 3424)
+++ doc/addresses/address.txt   (working copy)
@@ -99,12 +99,14 @@
 
 mkgmap uses so called preprocessed bounds files to provide a quick method assign the lies-in relationship for some hard wired tags:
 * admin_level=2..11
+* place
+* place_name
 * postal_code
 
 TODO: Parameter, mkgmap tags
 
 === Creating preprocessed bounds ===
-Preprocessing bounds is a procedure to extract and prepare all boundary and zip code data with from a large
+Preprocessing bounds is a procedure to extract and prepare all boundary, zip code and place data with from a large
 OSM extract (like europe extract or asia extract). The data is prepared in such a format that mkgmap
 can read and process in a fast way while compiling maps.
 
@@ -115,7 +117,7 @@
 . Eventually merge multiple preprocessed extracts
 
 ==== Extracting data ====
-The boundary and zip code data must be extracted from a large OSM extract to avoid excessive memory
+The boundary, zip code and place data must be extracted from a large OSM extract to avoid excessive memory
 requirements in the preprocessing step.
 
 NOTE: This manual describes the usage of the two tools +osmconvert+ and +osmfilter+. The same can be achieved
@@ -135,12 +137,12 @@
 to o5m format. This o5m file is then filtered.
 
  osmconvert europe.osm.pbf --out-o5m >europe.o5m
- osmfilter europe.o5m --keep-nodes= --keep-ways-relations="boundary=administrative =postal_code postal_code=" --out-o5m > europe-boundaries.o5m
+ osmfilter europe.o5m --keep-nodes= --keep-ways-relations="boundary=administrative =postal_code postal_code= ( type=multipolygon and place= and name= ) " --out-o5m > europe-boundaries.o5m
 
 =================================
 
 ==== Preprocessing data ====
-The tool for preprocessing the boundary and zip code data is contained in the common mkgmap download.
+The tool for preprocessing the boundary, zip code and place data is contained in the common mkgmap download.
 
 .Preprocessing bounds data
 =================================
Index: doc/styles/internal-tags.txt
===================================================================
--- doc/styles/internal-tags.txt        (revision 3424)
+++ doc/styles/internal-tags.txt        (working copy)
@@ -110,7 +110,9 @@
 | +mkgmap:admin_level8+  | Name of the +boundary=administrative+ relation/polygon with +admin_level=8+ the element is located in | 'bounds'    
 | +mkgmap:admin_level9+  | Name of the +boundary=administrative+ relation/polygon with +admin_level=9+ the element is located in | 'bounds'    
 | +mkgmap:admin_level10+  | Name of the +boundary=administrative+ relation/polygon with +admin_level=10+ the element is located in | 'bounds'    
-| +mkgmap:admin_level11+  | Name of the +boundary=administrative+ relation/polygon with +admin_level=11+ the element is located in | 'bounds'    
+| +mkgmap:admin_level11+  | Name of the +boundary=administrative+ relation/polygon with +admin_level=11+ the element is located in | 'bounds'  
+| +mkgmap:place+  | Type of place (city, hamlet, ...) of the +type=multipolygon+ relation/polygon with +place=<type>+ the element is located in | 'bounds'
+| +mkgmap:place_name+  | Name of the +type=multipolygon+ relation/polygon with +place=<type>+ the element is located in | 'bounds'
 | +mkgmap:postcode+  | Name of the postal code relation/polygon the element is located in | 'bounds'    
 | +mkgmap:area2poi+  | The value is +true+ if the POI is derived from a polygon | 'add-poi-to-areas'    
 | +mkgmap:line2poi+  | The value is +true+ if the POI is derived from a line | 'add-poi-to-lines'    
Index: resources/LocatorConfig.xml
===================================================================
--- resources/LocatorConfig.xml (revision 3424)
+++ resources/LocatorConfig.xml (working copy)
@@ -849,7 +849,7 @@
                <variant>ROU</variant>
                <variant>Romania</variant>
        </country>
-       <country name="Russian Federation" abr="RUS" streetBeforeHousenumber="true">
+       <country name="Russian Federation" abr="RUS" streetBeforeHousenumber="true" postalcodeBeforeCity="true">
                <variant>RU</variant>
                <variant>RUS</variant>
                <variant>Russia</variant>
Index: resources/help/en/options
===================================================================
--- resources/help/en/options   (revision 3424)
+++ resources/help/en/options   (working copy)
@@ -139,7 +139,9 @@
               mkgmap:admin_level3 : Name of the admin_level=3 boundary
               ..
               mkgmap:admin_level11
-              mkgmap:postcode : the postal_code value
+              mkgmap:place : Place type (city, hamlet, ...) of the multipolygon with place tag
+              mkgmap:place_name : Name of the multipolygon with place tag
+              mkgmap:postcode : Postal_code value
               
     Preprocessed bounds can be created with the following command:
        java -cp mkgmap.jar
Index: resources/styles/default/inc/address
===================================================================
--- resources/styles/default/inc/address        (revision 3424)
+++ resources/styles/default/inc/address        (working copy)
@@ -96,6 +96,11 @@
 mkgmap:country=GRE & mkgmap:city!=* & mkgmap:admin_level7=* { set mkgmap:city='${mkgmap:admin_level7}' }
 mkgmap:country=GRE & mkgmap:city!=* & mkgmap:admin_level8=* { set mkgmap:city='${mkgmap:admin_level8}' }
 
+# Russia
+mkgmap:country=RUS & mkgmap:city!=* & mkgmap:admin_level8=* { set mkgmap:city='${mkgmap:admin_level8}' }
+mkgmap:country=RUS & mkgmap:city!=* & mkgmap:place=* { set mkgmap:city='${mkgmap:place_name}' }
+mkgmap:country=RUS & mkgmap:city!=* & mkgmap:admin_level6=* { set mkgmap:city='${mkgmap:admin_level6}' }
+
 # common rules for all the rest of countries
 mkgmap:region!=* & mkgmap:admin_level6=* { set mkgmap:region='${mkgmap:admin_level6}' }
 mkgmap:region!=* & mkgmap:admin_level5=* { set mkgmap:region='${mkgmap:admin_level5}' }
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryElementSaver.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryElementSaver.java     (revision 3424)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryElementSaver.java     (working copy)
@@ -47,9 +47,9 @@
 
        /**
         * Checks if the given element is an administrative boundary or a
-        * postal code area.
+        * postal code area or a multipoligon with tag "place".
         * @param element an element
-        * @return <code>true</code> administrative boundary or postal code;
+        * @return <code>true</code> administrative boundary or postal code or multipoligon with place tag;
         * <code>false</code> element cannot be used for precompiled bounds
         */
        public static boolean isBoundary(Element element) {
@@ -102,6 +102,8 @@
                                        return false;                                          
                                } else if (element.getTag("postal_code") != null){
                                        return true;
+                               } else if (element.getTag("place") != null){
+                                       return true;
                                } else {
                                        return false;
                                }
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryLocationInfo.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryLocationInfo.java     (revision 3424)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryLocationInfo.java     (working copy)
@@ -23,15 +23,17 @@
        private final String zip;
        private final String name;
        private final int admLevel;
+       private final String place;
        private boolean isISO;
 
-       BoundaryLocationInfo (int admLevel, String name, String zip, boolean isISO){
+       BoundaryLocationInfo (int admLevel, String name, String zip, String place, boolean isISO){
                this.admLevel = admLevel;
                if (admLevel > 0 && name == null)
                        this.name = "not_set"; // TODO: review
                else
                        this.name = name;
                this.zip = zip;
+               this.place = place;
                this.isISO = isISO;
        }
        public String getZip() {
@@ -46,6 +48,10 @@
                return admLevel;
        }
 
+       public String getPlace() {
+               return place;
+       }
+      
        public boolean isISOName(){
                return isISO;
        }
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryLocationPreparer.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryLocationPreparer.java (revision 3424)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryLocationPreparer.java (working copy)
@@ -69,6 +69,7 @@
                int admLevel = getAdminLevel(tags);
                boolean isISO = false;
                String name = getName(tags);
+               String place = getPlace(tags);
                if (locator != null){
                        if (admLevel == 2) {
                                String isoCode = locator.addCountry(tags);
@@ -81,7 +82,7 @@
                                log.debug("Coded:",name);
                        }
                }
-               return new BoundaryLocationInfo(admLevel, name, zip, isISO);
+               return new BoundaryLocationInfo(admLevel, name, zip, place, isISO);
        }
 
        /**
@@ -192,5 +193,16 @@
                        return UNSET_ADMIN_LEVEL;
                }
        }
+      
+       /**
+        * Try to extract a place type from the the tags of a boundary.
+        * @param tags the boundary tags
+        * @return null if no place type was found, else a String that should be a place type.
+        */
+       private String getPlace(Tags tags) {
+               String place = tags.get("place");
+              
+               return place;
+       }
 }
 
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryQuadTree.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryQuadTree.java (revision 3424)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryQuadTree.java (working copy)
@@ -87,10 +87,14 @@
                "mkgmap:admin_level9",
                "mkgmap:admin_level10",
                "mkgmap:admin_level11",
+               "mkgmap:place",
+               "mkgmap:place_name",
                "mkgmap:postcode"
        };
-       // 11: the position of "mkgmap:postcode" in the above array
-       public final static short POSTCODE_ONLY = 1 << 11;  
+       // 11: the position of "mkgmap:place" in the above array
+       public final static short PLACE_ONLY = 1 << 11;
+       // 13: the position of "mkgmap:postcode" in the above array
+       public final static short POSTCODE_ONLY = 1 << 13;  
       
        /**
         * Create a quadtree with the data in an open stream.
@@ -262,8 +266,8 @@
        }
 
        /**
-        * Sort the boundary-Tags-Map so that zip-code-only boundaries appear first, followed by
-        * admin_level-11,10,9,...2
+        * Sort the boundary-Tags-Map so that zip-code-only boundaries appear first, followed by place,
+        * followed by admin_level-11,10,9,...2
         */
        private void sortBoundaryTagsMap(){
                // make sure that the merged LinkedHashMap is sorted as mergeBoundaries() needs it
@@ -847,7 +851,7 @@
                                        toAdd.setArea(toAddMinusCurr);
                                        if (!isWritable(currMinusToAdd)){
                                            // curr is fully covered by toAdd
-                                               if (toAdd.tagMask != POSTCODE_ONLY){
+                                               if (toAdd.tagMask < PLACE_ONLY){
                                                        currElem.addLocInfo(toAdd);
                                                }
                                                continue; // no need to create new intersection area
@@ -863,7 +867,7 @@
                                        // remove intersection part also from curr
                                        currElem.setArea(currMinusToAdd);
                                       
-                                       if (toAdd.tagMask != POSTCODE_ONLY){
+                                       if (toAdd.tagMask < PLACE_ONLY){
                                                // combine tag info in intersection
                                                intersect.addLocInfo(toAdd);
                                                reworked.add(intersect);
@@ -920,7 +924,7 @@
                                NodeElem lastNode = nodes.get(nodes.size()-1);
                                NodeElem prevNode = nodes.get(nodes.size()-2);
                                // don't merge admin_level tags into zip-code only boundary
-                               if (prevNode.tagMask != POSTCODE_ONLY && lastNode.getArea().isRectangular() && prevNode.getArea().isRectangular()){
+                               if (prevNode.tagMask < PLACE_ONLY && lastNode.getArea().isRectangular() && prevNode.getArea().isRectangular()){
                                        // two areas are rectangles, it is likely that they are equal to the bounding box
                                        // In this case we add the tags to the existing area instead of creating a new one
                                        if (prevNode.getArea().equals(lastNode.getArea())){
@@ -1124,6 +1128,11 @@
                                locTags.put("mkgmap:postcode",bInfo.getZip());
                        }
                       
+                       if (bInfo.getPlace() != null){
+                               locTags.put("mkgmap:place", bInfo.getPlace());
+                               locTags.put("mkgmap:place_name", bInfo.getName());
+                       }
+                      
                        if (bInfo.getAdmLevel() != BoundaryLocationPreparer.UNSET_ADMIN_LEVEL){
                                locTags.put(BoundaryQuadTree.mkgmapTagsArray[bInfo.getAdmLevel()-1], bInfo.getName());
                        }
@@ -1148,12 +1157,22 @@
                                        if (addAdmLevel != BoundaryLocationPreparer.UNSET_ADMIN_LEVEL){
                                                addAdmName = addInfo.getName();
                                        }
+                                       String addPlace = addInfo.getPlace();
+                                       String addPlaceName = null;
+                                       if (addPlace != null)
+                                               addPlaceName = addInfo.getName();
                                        String addZip = addInfo.getZip();
 
                                        if (addAdmName != null){
                                                if (locTags.get(BoundaryQuadTree.mkgmapTagsArray[addAdmLevel-1]) == null)
                                                        locTags.put(BoundaryQuadTree.mkgmapTagsArray[addAdmLevel-1], addAdmName);
                                        }
+                                       if (addPlace != null){
+                                               if (locTags.get("mkgmap:place") == null)
+                                                       locTags.put("mkgmap:place", addPlace);
+                                               if (locTags.get("mkgmap:place_name") == null)
+                                                       locTags.put("mkgmap:place_name", addPlaceName);
+                                       }
                                        if (addZip != null){
                                                if (locTags.get("mkgmap:postcode") == null)
                                                        locTags.put("mkgmap:postcode", addZip);
@@ -1297,7 +1316,7 @@
                                                        break;
                                                }
                                        }
-                                       else{
+                                       else if (testMask < PLACE_ONLY){
                                                errAdmLevel = k+1;
                                                errMsg = new String ("same admin_level (" + errAdmLevel + ")");
                                                break;
@@ -1372,12 +1391,21 @@
                                if (i1.isISOName() == false && i2.isISOName() == true)
                                        return -1;
                        }
+                      
+                       boolean place1set = i1.getPlace() != null;
+                       boolean place2set = i2.getPlace() != null;
+                       if (place1set && !place2set)
+                               return 1;
+                       if (!place1set && place2set)
+                               return -1;
+                      
                        boolean post1set = i1.getZip() != null;
                        boolean post2set = i2.getZip() != null;
                        if (post1set && !post2set)
                                return 1;
                        if (!post1set && post2set)
                                return -1;
+                      
                        // if all is equal, prefer the lower boundaryId
                        return o1.compareTo(o2);
                }