use of uk.me.parabola.imgfmt.app.lbl.City in project mkgmap by openstreetmap.
the class MapBuilder method processCities.
/**
* Processing of Cities
*
* Fills the city list in lbl block that is required for find by name
* It also builds up information that is required to get address info
* for the POIs
*
* @param map The map.
* @param src The map data.
*/
private void processCities(Map map, MapDataSource src) {
LBLFile lbl = map.getLblFile();
if (locationAutofill.isEmpty() == false) {
// collect the names of the cities
for (MapPoint p : src.getPoints()) {
if (p.isCity() && p.getName() != null)
// Put the city info the map for missing info
locator.addCityOrPlace(p);
}
// Try to fill missing information that include search of next city
locator.autofillCities();
}
for (MapPoint p : src.getPoints()) {
if (p.isCity() && p.getName() != null) {
String countryStr = p.getCountry();
Country thisCountry;
if (countryStr != null) {
thisCountry = lbl.createCountry(countryStr, locator.getCountryISOCode(countryStr));
} else
thisCountry = getDefaultCountry();
String regionStr = p.getRegion();
Region thisRegion;
if (regionStr != null) {
thisRegion = lbl.createRegion(thisCountry, regionStr, null);
} else
thisRegion = getDefaultRegion(thisCountry);
City thisCity;
if (thisRegion != null)
thisCity = lbl.createCity(thisRegion, p.getName(), true);
else
thisCity = lbl.createCity(thisCountry, p.getName(), true);
cityMap.put(p, thisCity);
}
}
}
use of uk.me.parabola.imgfmt.app.lbl.City in project mkgmap by openstreetmap.
the class MapBuilder method processRoads.
private void processRoads(Map map, MapDataSource src) {
LBLFile lbl = map.getLblFile();
MapPoint searchPoint = new MapPoint();
for (MapLine line : src.getLines()) {
if (line.isRoad()) {
String cityName = line.getCity();
String cityCountryName = line.getCountry();
String cityRegionName = line.getRegion();
String zipStr = line.getZip();
if (cityName == null && locationAutofill.contains("nearest")) {
// Get name of next city if untagged
searchPoint.setLocation(line.getLocation());
MapPoint nextCity = locator.findNextPoint(searchPoint);
if (nextCity != null) {
cityName = nextCity.getCity();
// city/region/country fields should match to the found city
cityCountryName = nextCity.getCountry();
cityRegionName = nextCity.getRegion();
// use the zip code only if no zip code is known
if (zipStr == null)
zipStr = nextCity.getZip();
}
}
MapRoad road = (MapRoad) line;
road.resetImgData();
City roadCity = calcCity(lbl, cityName, cityRegionName, cityCountryName);
if (roadCity != null)
road.addRoadCity(roadCity);
if (zipStr != null) {
road.addRoadZip(lbl.createZip(zipStr));
}
List<Numbers> numbers = road.getRoadDef().getNumbersList();
if (numbers != null) {
for (Numbers num : numbers) {
for (int i = 0; i < 2; i++) {
boolean left = (i == 0);
ZipCodeInfo zipInfo = num.getZipCodeInfo(left);
if (zipInfo != null && zipInfo.getZipCode() != null) {
Zip zip = zipInfo.getImgZip();
if (zipInfo.getImgZip() == null) {
zip = lbl.createZip(zipInfo.getZipCode());
zipInfo.setImgZip(zip);
}
if (zip != null)
road.addRoadZip(zip);
}
CityInfo cityInfo = num.getCityInfo(left);
if (cityInfo != null) {
City city = cityInfo.getImgCity();
if (city == null) {
city = calcCity(lbl, cityInfo.getCity(), cityInfo.getRegion(), cityInfo.getCountry());
cityInfo.setImgCity(city);
}
if (city != null)
road.addRoadCity(city);
}
}
}
}
}
}
}
use of uk.me.parabola.imgfmt.app.lbl.City in project mkgmap by openstreetmap.
the class MdrBuilder method addPoints.
/**
* Read points from this map and add them to the index.
* @param mr The currently open map.
* @param maps Maps of regions, cities countries etc.
*/
private void addPoints(MapReader mr, AreaMaps maps) {
List<Point> list = mr.pointsForLevel(0, MapReader.WITHOUT_EXT_TYPE_DATA);
for (Point p : list) {
Label label = p.getLabel();
if (p.getNumber() > 256) {
continue;
}
Mdr5Record mdrCity = null;
boolean isCity;
if (p.getType() >= 0x1 && p.getType() <= 0x11) {
// This is itself a city, it gets a reference to its own MDR 5 record.
// and we also use it to set the name of the city.
mdrCity = maps.cities.get((p.getSubdiv().getNumber() << 8) + p.getNumber());
if (mdrCity != null) {
mdrCity.setLblOffset(label.getOffset());
mdrCity.setName(label.getText());
}
isCity = true;
} else {
// This is not a city, but we have information about which city
// it is in. If so then add the mdr5 record number of the city.
POIRecord poi = p.getPOIRecord();
City c = poi.getCity();
if (c != null)
mdrCity = getMdr5FromCity(maps, c);
isCity = false;
}
if (label != null && !label.getText().trim().isEmpty())
mdrFile.addPoint(p, mdrCity, isCity);
}
}
use of uk.me.parabola.imgfmt.app.lbl.City in project mkgmap by openstreetmap.
the class RoadDef method writeNet1.
/**
* This is for writing to NET1.
* @param writer A writer that is positioned within NET1.
*/
void writeNet1(ImgFileWriter writer, int numCities, int numZips) {
if (numlabels == 0)
return;
assert numlabels > 0;
Zip zip = getZips().isEmpty() ? null : getZips().get(0);
City city = getCities().isEmpty() ? null : getCities().get(0);
offsetNet1 = writer.position();
NumberPreparer numbers = null;
if (numbersList != null) {
numbers = new NumberPreparer(numbersList, zip, city, numCities, numZips);
if (!numbers.prepare()) {
numbers = null;
log.warn("Invalid housenumbers in", this.toString());
}
}
writeLabels(writer);
if (numbers != null && numbers.getSwapped()) {
// swapped default; left=even, right=odd
netFlags |= 0x20;
}
writer.put((byte) netFlags);
writer.put3(roadLength);
int maxlevel = writeLevelCount(writer);
writeLevelDivs(writer, maxlevel);
if ((netFlags & NET_FLAG_ADDRINFO) != 0) {
nodeCount--;
if (nodeCount + 2 != nnodes) {
log.error("internal error? The nodeCount doesn't match value calculated by RoadNetWork:", this);
}
// lo bits of node count
writer.put((byte) (nodeCount & 0xff));
// top bits of node count
int code = ((nodeCount >> 8) & 0x3);
int len, flag;
ByteArrayOutputStream zipBuf = null, cityBuf = null;
len = (numbers == null) ? 0 : numbers.zipWriter.getBuffer().size();
if (len > 0) {
zipBuf = numbers.zipWriter.getBuffer();
flag = Utils.numberToPointerSize(len) - 1;
} else
flag = (zip == null) ? 3 : 2;
code |= flag << 2;
len = (numbers == null) ? 0 : numbers.cityWriter.getBuffer().size();
if (len > 0) {
cityBuf = numbers.cityWriter.getBuffer();
flag = Utils.numberToPointerSize(len) - 1;
} else
flag = (city == null) ? 3 : 2;
code |= flag << 4;
len = (numbers == null) ? 0 : numbers.fetchBitStream().getLength();
if (len > 0) {
flag = Utils.numberToPointerSize(len) - 1;
} else
flag = 3;
code |= flag << 6;
writer.put((byte) code);
if (zipBuf != null) {
len = zipBuf.size();
writer.putN(Utils.numberToPointerSize(len), len);
writer.put(zipBuf.toByteArray());
} else {
if (zip != null) {
char zipIndex = (char) zip.getIndex();
writer.putN(Utils.numberToPointerSize(numZips), zipIndex);
}
}
if (cityBuf != null) {
len = cityBuf.size();
writer.putN(Utils.numberToPointerSize(len), len);
writer.put(cityBuf.toByteArray());
} else {
if (city != null) {
char cityIndex = (char) city.getIndex();
writer.putN(Utils.numberToPointerSize(numCities), cityIndex);
}
}
if (numbers != null) {
BitWriter bw = numbers.fetchBitStream();
writer.putN(Utils.numberToPointerSize(bw.getLength()), bw.getLength());
writer.put(bw.getBytes(), 0, bw.getLength());
}
}
if (hasNodInfo()) {
// This is the offset of an entry in NOD2
int val = offsetNod2;
if (val < 0x7fff) {
writer.put((byte) 1);
writer.putChar((char) val);
} else {
writer.put((byte) 2);
writer.put3(val);
}
}
}
use of uk.me.parabola.imgfmt.app.lbl.City in project mkgmap by openstreetmap.
the class NETFile method sortRoads.
/**
* Sort the roads by name and remove duplicates.
*
* We want a list of roads such that every entry in the list is a different road. Since in osm
* roads are frequently chopped into small pieces we have to remove the duplicates.
* This doesn't have to be perfect, it needs to be useful when searching for roads.
*
* So we have a separate entry if the road is in a different city. This would probably be enough
* except that associating streets with cities is not always very good in OSM. So I also create an
* extra entry for each subdivision. Finally there a search for disconnected roads within the subdivision
* with the same name.
*
* Performance note: The previous implementation was very, very slow when there were a large number
* of roads with the same name. Although this was an unusual situation, when it happened it appears
* that mkgmap has hung. This implementation takes a fraction of a second even for large numbers of
* same named roads.
*
* @return A sorted list of road labels that identify all the different roads.
*/
private List<LabeledRoadDef> sortRoads() {
List<SortKey<LabeledRoadDef>> sortKeys = new ArrayList<>(roads.size());
Map<Label, byte[]> cache = new HashMap<>();
for (RoadDef rd : roads) {
Label[] labels = rd.getLabels();
for (int i = 0; i < labels.length && labels[i] != null; ++i) {
Label label = labels[i];
if (label.getLength() == 0)
continue;
// Sort by name, city, region/country and subdivision number.
LabeledRoadDef lrd = new LabeledRoadDef(label, rd);
SortKey<LabeledRoadDef> nameKey = new IntegerSortKey<NETFile.LabeledRoadDef>(lrd, label.getOffset(), 0);
// If there is a city add it to the sort.
// what if we more than one?
City city = (rd.getCities().isEmpty() ? null : rd.getCities().get(0));
SortKey<LabeledRoadDef> cityKey;
if (city != null) {
int region = city.getRegionNumber();
int country = city.getCountryNumber();
cityKey = sort.createSortKey(null, city.getLabel(), (region & 0xffff) << 16 | (country & 0xffff), cache);
} else {
cityKey = sort.createSortKey(null, Label.NULL_OUT_LABEL, 0, cache);
}
SortKey<LabeledRoadDef> sortKey = new MultiSortKey<>(nameKey, cityKey, new IntegerSortKey<LabeledRoadDef>(null, rd.getStartSubdivNumber(), 0));
sortKeys.add(sortKey);
}
}
Collections.sort(sortKeys);
List<LabeledRoadDef> out = new ArrayList<>(sortKeys.size());
Label lastName = null;
City lastCity = null;
List<LabeledRoadDef> dupes = new ArrayList<>();
// The duplicates are saved to the dupes list.
for (SortKey<LabeledRoadDef> key : sortKeys) {
LabeledRoadDef lrd = key.getObject();
Label name = lrd.label;
RoadDef road = lrd.roadDef;
// what if we more than one?
City city = (road.getCities().isEmpty() ? null : road.getCities().get(0));
if (road.hasHouseNumbers() || !name.equals(lastName) || city != lastCity) {
// process any previously collected duplicate road names and reset.
addDisconnected(dupes, out);
dupes = new ArrayList<>();
lastName = name;
lastCity = city;
}
dupes.add(lrd);
}
// Finish off the final set of duplicates.
addDisconnected(dupes, out);
sortByName(out);
return out;
}
Aggregations