[PATCH v2] - alpha patch to support road find by name

v2 - now generates correct sized city ref (wasn't being used yet anyway!) ----------- Hi, The attached patch is for the current SVN trunk (r979) and it generates the sorted road data that is required by the gps to find roads/intersections by name. For me, it's basically working on the etrex in that find now gives you and option for finding addresses (and intersections but that hasn't been tested). The number and city fields don't work yet, just the road name field can be used. The patch does include support for the city field but it's not yet working because roads currently do not have a city assigned to them (yes, I know the RNPs do but they are points). Bernhard, could you please look at setting MapRoad's city object to the most applicable city? As for the number field, I haven't thought yet how that would get its data. Please test this patch and report success/failure. If it doesn't break anything for anyone, I would like to commit it fairly soon as I think that quite a few people will be happy to have street finding added to the trunk. Cheers, Mark

Hi Mark, I have added city auto fill to your code. Unfortunately I was not able to test it on gps. Problem is that I don't know how to search for roads on my nuvi 360. Maybe this only works with NT cards on the nuvis ? The address / intersections search still asks to spell a US State. I also didn't found any effect in GPSMapEdit. Hints are welcome. I see the same problem with your HW Exit patch. Thanks Berni.
v2 - now generates correct sized city ref (wasn't being used yet anyway!)
-----------
Hi,
The attached patch is for the current SVN trunk (r979) and it generates the sorted road data that is required by the gps to find roads/intersections by name.
For me, it's basically working on the etrex in that find now gives you and option for finding addresses (and intersections but that hasn't been tested). The number and city fields don't work yet, just the road name field can be used.
The patch does include support for the city field but it's not yet working because roads currently do not have a city assigned to them (yes, I know the RNPs do but they are points). Bernhard, could you please look at setting MapRoad's city object to the most applicable city?
As for the number field, I haven't thought yet how that would get its data.
Please test this patch and report success/failure.
If it doesn't break anything for anyone, I would like to commit it fairly soon as I think that quite a few people will be happy to have street finding added to the trunk.
Cheers,
Mark
------------------------------------------------------------------------
_______________________________________________ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Index: src/uk/me/parabola/imgfmt/app/net/NETHeader.java =================================================================== --- src/uk/me/parabola/imgfmt/app/net/NETHeader.java (revision 328) +++ src/uk/me/parabola/imgfmt/app/net/NETHeader.java (working copy) @@ -95,4 +95,9 @@ roadDefinitions.setPosition(writer.position()); return new SectionWriter(writer, roadDefinitions); } + + ImgFileWriter makeSortedRoadWriter(ImgFileWriter writer) { + sortedRoads.setPosition(writer.position()); + return new SectionWriter(writer, sortedRoads); + } } Index: src/uk/me/parabola/imgfmt/app/net/RoadDef.java =================================================================== --- src/uk/me/parabola/imgfmt/app/net/RoadDef.java (revision 328) +++ src/uk/me/parabola/imgfmt/app/net/RoadDef.java (working copy) @@ -23,6 +23,7 @@ import uk.me.parabola.imgfmt.app.ImgFileWriter; import uk.me.parabola.imgfmt.app.Label; +import uk.me.parabola.imgfmt.app.lbl.City; import uk.me.parabola.imgfmt.app.trergn.Polyline; import uk.me.parabola.log.Logger; @@ -47,7 +48,7 @@ * @author Robert Vollmert */ -public class RoadDef { +public class RoadDef implements Comparable { private static final Logger log = Logger.getLogger(RoadDef.class); // the offset in Nod2 of our Nod2 record @@ -74,10 +75,10 @@ * Everything that's relevant for writing to NET1. */ - private static final int NET_FLAG_NODINFO = 0x40; - private static final int NET_FLAG_UNK1 = 0x04; - private static final int NET_FLAG_ONEWAY = 0x02; - private static final int NET_FLAG_ADDRINFO = 0x01; + private static final int NET_FLAG_NODINFO = 0x40; + private static final int NET_FLAG_ADDRINFO = 0x10; + private static final int NET_FLAG_UNK1 = 0x04; + private static final int NET_FLAG_ONEWAY = 0x02; private int netFlags = NET_FLAG_UNK1; @@ -93,11 +94,13 @@ private final SortedMap<Integer,List<RoadIndex>> roadIndexes = new TreeMap<Integer,List<RoadIndex>>(); + private City city; + /** * This is for writing to NET1. * @param writer A writer that is positioned within NET1. */ - void writeNet1(ImgFileWriter writer) { + void writeNet1(ImgFileWriter writer, int numCities) { if (numlabels == 0) return; assert numlabels > 0; @@ -112,6 +115,16 @@ writeLevelDivs(writer, maxlevel); + if(city != null) { + writer.put((byte)0); + writer.put((byte)0xec); + char cityIndex = (char)city.getIndex(); + if(numCities > 255) + writer.putChar(cityIndex); + else + writer.put((byte)cityIndex); + } + if (hasNodInfo()) { // This is the offset of an entry in NOD2 int val = offsetNod2; @@ -166,6 +179,10 @@ log.warn("discarding extra label", l); } + public int getNumLabels() { + return numlabels; + } + /** * Add a polyline to this road. * @@ -458,4 +475,18 @@ tabAInfo |= TABA_FLAG_ONEWAY; netFlags |= NET_FLAG_ONEWAY; } + + public void setCity(City city) { + this.city = city; + netFlags |= NET_FLAG_ADDRINFO; + } + + public int compareTo(Object other) { + RoadDef o = (RoadDef)other; + if(labels[0] != null && o.labels[0] != null) + return labels[0].compareTo(o.labels[0]); + if(labels[0] == null && o.labels[0] == null) + return 0; + return (labels[0] == null)? -1 : 1; + } } Index: src/uk/me/parabola/imgfmt/app/net/NETFile.java =================================================================== --- src/uk/me/parabola/imgfmt/app/net/NETFile.java (revision 328) +++ src/uk/me/parabola/imgfmt/app/net/NETFile.java (working copy) @@ -16,6 +16,8 @@ */ package uk.me.parabola.imgfmt.app.net; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import uk.me.parabola.imgfmt.Utils; @@ -47,12 +49,12 @@ } } - public void write() { + public void write(int numCities) { // Write out the actual file body. ImgFileWriter writer = netHeader.makeRoadWriter(getWriter()); try { for (RoadDef rd : roads) - rd.writeNet1(writer); + rd.writeNet1(writer, numCities); } finally { Utils.closeFile(writer); @@ -60,9 +62,23 @@ } public void writePost(ImgFileWriter rgn) { - for (RoadDef rd : roads) + List<RoadDef> sortedRoads = new ArrayList<RoadDef>(roads.size()); + + for (RoadDef rd : roads) { rd.writeRgnOffsets(rgn); + if(rd.getNumLabels() != 0) + sortedRoads.add(rd); + } + if(sortedRoads.size() > 0) { + Collections.sort(sortedRoads); + ImgFileWriter writer = netHeader.makeSortedRoadWriter(getWriter()); + for(RoadDef rd : sortedRoads) { + writer.put3(rd.getOffsetNet1()); + } + Utils.closeFile(writer); + } + getHeader().writeHeader(getWriter()); } Index: src/uk/me/parabola/imgfmt/app/Label.java =================================================================== --- src/uk/me/parabola/imgfmt/app/Label.java (revision 328) +++ src/uk/me/parabola/imgfmt/app/Label.java (working copy) @@ -32,7 +32,7 @@ * * @author Steve Ratcliffe */ -public class Label { +public class Label implements Comparable { private static final Logger log = Logger.getLogger(Label.class); // The compressed form of the label text. @@ -107,4 +107,18 @@ public int hashCode() { return offset; } + + public int compareTo(Object other) { + Label o = (Label)other; + if(this == other) + return 0; + for(int i = 0; i < length && i < o.length; ++i) { + int diff = (ctext[i] & 0xff) - (o.ctext[i] & 0xff); + if(diff != 0) + return diff; + } + if(length == o.length) + return 0; + return (length > o.length)? 1 : -1; + } } Index: src/uk/me/parabola/imgfmt/app/lbl/PlacesFile.java =================================================================== --- src/uk/me/parabola/imgfmt/app/lbl/PlacesFile.java (revision 328) +++ src/uk/me/parabola/imgfmt/app/lbl/PlacesFile.java (working copy) @@ -240,4 +240,8 @@ return city; } } + + public Map<String, City>getCities() { + return cities; + } } Index: src/uk/me/parabola/imgfmt/app/lbl/LBLFile.java =================================================================== --- src/uk/me/parabola/imgfmt/app/lbl/LBLFile.java (revision 328) +++ src/uk/me/parabola/imgfmt/app/lbl/LBLFile.java (working copy) @@ -155,6 +155,10 @@ return places.createCity(country, city, unique); } + public Map<String, City>getCities() { + return places.getCities(); + } + public Zip createZip(String code) { return places.createZip(code); } Index: src/uk/me/parabola/mkgmap/main/MapMaker.java =================================================================== --- src/uk/me/parabola/mkgmap/main/MapMaker.java (revision 328) +++ src/uk/me/parabola/mkgmap/main/MapMaker.java (working copy) @@ -207,12 +207,6 @@ } } - List<MapPoint> cities = new ArrayList<MapPoint>(); - for(MapPoint mp : src.getPoints()) { - if(mp.isCity()) - cities.add(mp); - } - // generate a POI for each named road for(List<MapLine> lr : findConnectedRoadsWithSameName(namedRoads)) { // connected roads are not ordered so just use first in list @@ -315,11 +309,12 @@ int i2 = numPoints / 2; int i1 = i2 - 1; coord = new Coord((points.get(i1).getLatitude() + - points.get(i2).getLatitude()) / 2, - (points.get(i1).getLongitude() + - points.get(i2).getLongitude()) / 2); - } else + points.get(i2).getLatitude()) / 2, + (points.get(i1).getLongitude() + + points.get(i2).getLongitude()) / 2); + } else { coord = points.get(numPoints / 2); + } String name = road.getName(); MapPoint rnp = new MapPoint(); Index: src/uk/me/parabola/mkgmap/build/MapBuilder.java =================================================================== --- src/uk/me/parabola/mkgmap/build/MapBuilder.java (revision 328) +++ src/uk/me/parabola/mkgmap/build/MapBuilder.java (working copy) @@ -177,7 +177,7 @@ nodFile.setNetwork(network.getCenters(), network.getRoadDefs(), network.getBoundary()); nodFile.write(); } - netFile.write(); + netFile.write(cityMap.size()); if (nodFile != null) { nodFile.writePost(); @@ -216,7 +216,7 @@ { Country thisCountry; Region thisRegion; - City thisCity; + City thisCity; String CountryStr = p.getCountry(); String RegionStr = p.getRegion(); @@ -693,10 +693,33 @@ filters.addFilter(new RemoveEmpty()); filters.addFilter(new LineAddFilter(div, map, doRoads)); + LBLFile lbl = map.getLblFile(); + + MapPoint tempPoint = new MapPoint(); + for (MapLine line : lines) { if (line.getMinResolution() > res || line.getMaxResolution() < res) continue; + if(line.isRoad()) { + String cityName = line.getCity(); + + if(cityName == null) + { + // Get name of next city if untagged + + tempPoint.setLocation(line.getLocation()); + MapPoint nextCity = locator.findNextPoint(tempPoint); + + if(nextCity != null) + cityName = nextCity.getCity(); + } + + if(cityName != null) { + ((MapRoad)line).setCity(lbl.getCities().get(cityName)); + } + } + filters.startFilter(line); } } Index: src/uk/me/parabola/mkgmap/general/MapRoad.java =================================================================== --- src/uk/me/parabola/mkgmap/general/MapRoad.java (revision 328) +++ src/uk/me/parabola/mkgmap/general/MapRoad.java (working copy) @@ -16,6 +16,7 @@ */ package uk.me.parabola.mkgmap.general; +import uk.me.parabola.imgfmt.app.lbl.City; import uk.me.parabola.imgfmt.app.net.RoadDef; /** @@ -101,4 +102,8 @@ public RoadDef getRoadDef() { return roadDef; } + + public void setCity(City c) { + this.roadDef.setCity(c); + } }

Hi Bernhard,
I have added city auto fill to your code. Unfortunately I was not able to test it on gps. Problem is that I don't know how to search for roads on my nuvi 360. Maybe this only works with NT cards on the nuvis ? The address / intersections search still asks to spell a US State. I also didn't found any effect in GPSMapEdit. Hints are welcome. I see the same problem with your HW Exit patch.
Thanks for the patch, it didn't really work but was a good starting place. I have just posted a revamped version which, for me, fills the city info as required. Obviously, it needs to be widely tested. As I don't know anything about the Nuvi, I can't help you. Sorry. GPSMapEdit, I think pays no attention to the address data. I have checked with maps produced by cgpsmapper, they don't seem to show it either. The HW exit stuff is sad. I have wasted so many hours on trying to make the OSM exits be shown in preference to the basemap exits that I don't want to look at that code any more! Cheers, Mark

Mark Burton escribió:
Hi Bernhard,
I have added city auto fill to your code. Unfortunately I was not able to test it on gps. Problem is that I don't know how to search for roads on my nuvi 360. Maybe this only works with NT cards on the nuvis ? The address / intersections search still asks to spell a US State. I also didn't found any effect in GPSMapEdit. Hints are welcome. I see the same problem with your HW Exit patch.
Thanks for the patch, it didn't really work but was a good starting place. I have just posted a revamped version which, for me, fills the city info as required. Obviously, it needs to be widely tested.
As I don't know anything about the Nuvi, I can't help you. Sorry.
Some time ago I read somewhere Address search in nuvi only works with nt maps. Your patch (v1) had no effect on my nuvi 300: it still asks for a State, but no one is listed.
GPSMapEdit, I think pays no attention to the address data. I have checked with maps produced by cgpsmapper, they don't seem to show it either.
The HW exit stuff is sad. I have wasted so many hours on trying to make the OSM exits be shown in preference to the basemap exits that I don't want to look at that code any more!
Well, I think you have improved routing performance quite a lot. Previous to your patch I only received "keep right" or just nothing for highway exits and now it says "leave right" which is much more convenient. I have City Navigator disabled in my nuvi and I can see exits on screen. So I think you didn't waste your time. Cheers Carlos

Hi Carlos,
Some time ago I read somewhere Address search in nuvi only works with nt maps. Your patch (v1) had no effect on my nuvi 300: it still asks for a State, but no one is listed.
Well, I think the patch is in its early days. Don't give up hope!
GPSMapEdit, I think pays no attention to the address data. I have checked with maps produced by cgpsmapper, they don't seem to show it either.
The HW exit stuff is sad. I have wasted so many hours on trying to make the OSM exits be shown in preference to the basemap exits that I don't want to look at that code any more!
Well, I think you have improved routing performance quite a lot. Previous to your patch I only received "keep right" or just nothing for highway exits and now it says "leave right" which is much more convenient. I have City Navigator disabled in my nuvi and I can see exits on screen. So I think you didn't waste your time.
Thanks, in that respect it's worth having. Perhaps, I shall commit it even though the exit search doesn't work 100%. Cheers, Mark
participants (3)
-
Bernhard Heibler
-
Carlos Dávila
-
Mark Burton