Rev 3408 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2009.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 or
* 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.
*/
package uk.me.parabola.imgfmt.app.mdr;
import java.util.ArrayList;
import java.util.List;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
import uk.me.parabola.imgfmt.app.srt.SortKey;
import uk.me.parabola.imgfmt.app.trergn.Point;
/**
* Holds all the POIs, including cities. Arranged alphabetically by
* the name.
*
* @author Steve Ratcliffe
*/
public class Mdr11
extends MdrMapSection
{
private List<Mdr11Record
> pois =
new ArrayList<>();
private Mdr10 mdr10
;
public Mdr11
(MdrConfig config
) {
setConfig
(config
);
}
public Mdr11Record addPoi
(int mapIndex,
Point point,
String name,
int strOff
) {
Mdr11Record poi =
new Mdr11Record
();
poi.
setMapIndex(mapIndex
);
poi.
setPointIndex(point.
getNumber());
poi.
setSubdiv(point.
getSubdiv().
getNumber());
poi.
setLblOffset(point.
getLabel().
getOffset());
poi.
setName(name
);
poi.
setStrOffset(strOff
);
pois.
add(poi
);
return poi
;
}
/**
* Sort and fill in the mdr10 information.
*
* The POI index contains individual references to POI by subdiv and index, so they are not
* de-duplicated in the index in the same way that streets and cities are.
*/
protected void preWriteImpl
() {
List<SortKey<Mdr11Record
>> keys = MdrUtils.
sortList(getConfig
().
getSort(), pois
);
pois.
clear();
for (SortKey<Mdr11Record
> sk : keys
) {
Mdr11Record poi = sk.
getObject();
mdr10.
addPoiType(poi
);
pois.
add(poi
);
}
}
public void writeSectData
(ImgFileWriter writer
) {
int count =
1;
boolean hasStrings = hasFlag
(2);
for (Mdr11Record poi : pois
) {
addIndexPointer
(poi.
getMapIndex(), count
);
poi.
setRecordNumber(count++
);
putMapIndex
(writer, poi.
getMapIndex());
writer.
put((byte) poi.
getPointIndex());
writer.
putChar((char) poi.
getSubdiv());
writer.
put3(poi.
getLblOffset());
if (poi.
isCity())
putRegionIndex
(writer, poi.
getRegionIndex());
else
putCityIndex
(writer, poi.
getCityIndex(),
true);
if (hasStrings
)
putStringOffset
(writer, poi.
getStrOffset());
}
}
public int getItemSize
() {
PointerSizes sizes = getSizes
();
int size = sizes.
getMapSize() +
6 + sizes.
getCitySizeFlagged();
if (hasFlag
(0x2
))
size += sizes.
getStrOffSize();
return size
;
}
protected int numberOfItems
() {
return pois.
size();
}
public int getNumberOfPois
() {
return getNumberOfItems
();
}
public int getExtraValue
() {
int mdr11flags = 0x11
;
PointerSizes sizes = getSizes
();
// two bit field for city bytes. minimum size of 2
int citySize = sizes.
getCitySizeFlagged();
if (citySize
> 2)
mdr11flags |=
(citySize-
2) << 2;
if (isForDevice
())
mdr11flags |= 0x80
;
else
mdr11flags |= 0x2
;
return mdr11flags
;
}
public List<Mdr8Record
> getIndex
() {
List<Mdr8Record
> list =
new ArrayList<>();
for (int number =
1; number
<= pois.
size(); number +=
10240) {
String prefix = getPrefixForRecord
(number
);
// need to step back to find the first...
int rec = number
;
while (rec
> 1) {
String p = getPrefixForRecord
(rec
);
if (!p.
equals(prefix
)) {
rec++
;
break;
}
rec--
;
}
Mdr12Record indexRecord =
new Mdr12Record
();
indexRecord.
setPrefix(prefix
);
indexRecord.
setRecordNumber(rec
);
list.
add(indexRecord
);
}
return list
;
}
/**
* Get the prefix of the name at the given record.
* @param number The record number.
* @return The first 4 (or whatever value is set) characters of the street
* name.
*/
private String getPrefixForRecord
(int number
) {
Mdr11Record record = pois.
get(number-
1);
int endIndex = MdrUtils.
POI_INDEX_PREFIX_LEN;
String name = record.
getName();
if (endIndex
> name.
length()) {
StringBuilder sb =
new StringBuilder(name
);
while (sb.
length() < endIndex
)
sb.
append('\0');
name = sb.
toString();
}
return name.
substring(0, endIndex
);
}
public void setMdr10
(Mdr10 mdr10
) {
this.
mdr10 = mdr10
;
}
public void releaseMemory
() {
pois =
null;
mdr10 =
null;
}
public List<Mdr11Record
> getPois
() {
return new ArrayList<>(pois
);
}
public void relabelMaps
(Mdr1 maps
) {
relabel
(maps, pois
);
}
}