Rev 4894 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2007 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* Author: Steve Ratcliffe
* Create date: Jan 1, 2008
*/
package uk.me.parabola.imgfmt.app.lbl;
import uk.me.parabola.imgfmt.app.ImgFileReader;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
import uk.me.parabola.imgfmt.app.Section;
/**
* This is not a separate header, but rather part of the LBL header. It is just
* separated out for convenience. All the records that have some kind of
* meaning associated with a place are put here.
*
* @author Steve Ratcliffe
*/
public class PlacesHeader {
private static final char COUNTRY_REC_LEN = 3;
private static final char REGION_REC_LEN = 5;
private static final char CITY_REC_LEN = 5;
private static final char POI_INDEX_REC_LEN = 4;
private static final char POI_TYPE_INDEX_REC_LEN = 4;
private static final char ZIP_REC_LEN = 3;
private static final char HIGHWAY_REC_LEN = 6;
private static final char EXIT_REC_LEN = 5;
private static final char HIGHWAYDATA_REC_LEN = 3;
private final Section country = new Section(COUNTRY_REC_LEN);
private final Section region = new Section(country, REGION_REC_LEN);
private final Section city = new Section(region, CITY_REC_LEN);
private final Section poiIndex = new Section(city, POI_INDEX_REC_LEN);
private final Section poiProperties = new Section(poiIndex);
private final Section poiTypeIndex = new Section(poiProperties, POI_TYPE_INDEX_REC_LEN);
private final Section zip = new Section(poiTypeIndex, ZIP_REC_LEN);
private final Section highway = new Section(zip, HIGHWAY_REC_LEN);
private final Section exitFacility = new Section(highway, EXIT_REC_LEN);
private final Section highwayData = new Section(exitFacility, HIGHWAYDATA_REC_LEN);
private int POIGlobalFlags ;
void setPOIGlobalFlags(int flags) {
this.POIGlobalFlags = flags;
}
int getPOIGlobalFlags() {
return POIGlobalFlags;
}
void writeFileHeader(ImgFileWriter writer) {
writer.put4(country.getPosition());
writer.put4(country.getSize());
writer.put2u(country.getItemSize());
writer.put4(0);
writer.put4(region.getPosition());
writer.put4(region.getSize());
writer.put2u(region.getItemSize());
writer.put4(0);
writer.put4(city.getPosition());
writer.put4(city.getSize());
writer.put2u(city.getItemSize());
writer.put4(0);
writer.put4(poiIndex.getPosition());
writer.put4(poiIndex.getSize());
writer.put2u(poiIndex.getItemSize());
writer.put4(0);
writer.put4(poiProperties.getPosition());
writer.put4(poiProperties.getSize());
writer.put1u(0); // offset multiplier
// mb 5/9/2009 - discovered that Garmin maps can contain more
// than 8 bits of POI global flags - have seen the 9th bit set
// to indicate the presence of some extra POI info (purpose
// unknown but it starts with a byte that contains the number
// of further bytes to read << 1) - therefore, this group
// should probably be: 16 bits of POI global flags followed by
// 16 zero bits rather than 8 bits of flags and 24 zero bits
writer.put1u(POIGlobalFlags); // properties global mask
writer.put2u(0);
writer.put1u(0);
writer.put4(poiTypeIndex.getPosition());
writer.put4(poiTypeIndex.getSize());
writer.put2u(poiTypeIndex.getItemSize());
writer.put4(0);
writer.put4(zip.getPosition());
writer.put4(zip.getSize());
writer.put2u(zip.getItemSize());
writer.put4(0);
writer.put4(highway.getPosition());
writer.put4(highway.getSize());
writer.put2u(highway.getItemSize());
writer.put4(0);
writer.put4(exitFacility.getPosition());
writer.put4(exitFacility.getSize());
writer.put2u(exitFacility.getItemSize());
writer.put4(0);
writer.put4(highwayData.getPosition());
writer.put4(highwayData.getSize());
writer.put2u(highwayData.getItemSize());
writer.put4(0);
}
void readFileHeader(ImgFileReader reader) {
reader.position(reader.getGMPOffset() + 0x1fL);
country.readSectionInfo(reader, true, true);
region.readSectionInfo(reader, true, true);
city.readSectionInfo(reader, true, true);
poiIndex.readSectionInfo(reader, true, true);
poiProperties.readSectionInfo(reader, false);
reader.get(); // offset multiplier
POIGlobalFlags = reader.get1u();
reader.get2u();
reader.get();
poiTypeIndex.readSectionInfo(reader, true, true);
zip.readSectionInfo(reader, true, true);
highway.readSectionInfo(reader, true, true);
exitFacility.readSectionInfo(reader, true, true);
highwayData.readSectionInfo(reader, true, true);
}
int getLastPos() {
// Beware this is not really valid until all is written.
return highwayData.getEndPos();
}
void setLabelEnd(int pos) {
country.setPosition(pos);
}
void endCountries(int pos) {
country.setSize(pos - country.getPosition());
}
void endRegions(int pos) {
region.setSize(pos - region.getPosition());
}
void endCity(int pos) {
city.setSize(pos - city.getPosition());
}
void endPOI(int pos) {
poiProperties.setSize(pos - poiProperties.getPosition());
}
void endPOIIndex(int pos) {
poiIndex.setSize(pos - poiIndex.getPosition());
}
void endPOITypeIndex(int pos) {
poiTypeIndex.setSize(pos - poiTypeIndex.getPosition());
}
void endZip(int pos) {
zip.setSize(pos - zip.getPosition());
}
void endHighway(int pos) {
highway.setSize(pos - highway.getPosition());
}
void endExitFacility(int pos) {
exitFacility.setSize(pos - exitFacility.getPosition());
}
void endHighwayData(int pos) {
highwayData.setSize(pos - highwayData.getPosition());
}
public int getNumCities() {
return city.getNumItems();
}
public int getNumZips() {
return zip.getNumItems();
}
public int getPoiPropertiesStart() {
return poiProperties.getPosition();
}
public int getPoiPropertiesEnd() {
return poiProperties.getEndPos();
}
public Section getCitySection() {
return city;
}
public int getNumExits() {
return exitFacility.getNumItems();
}
public Section getCountrySection() {
return country;
}
public Section getRegionSection() {
return region;
}
public int getNumHighways() {
return highway.getNumItems();
}
public Section getZipSection() {
return zip;
}
}