Write poi data
This commit is contained in:
parent
bbcf0e344c
commit
bfdf307975
6 changed files with 1492 additions and 164 deletions
|
@ -1,10 +1,10 @@
|
|||
<!-- build JAR libraty -->
|
||||
<project name="OsmPDB" default="build" basedir=".">
|
||||
<target name="build" >
|
||||
<exec dir="." executable="protoc">
|
||||
<arg value="src/osmand_odb.proto"/>
|
||||
<arg value="--java_out=./src/"/>
|
||||
</exec>
|
||||
<target name="build">
|
||||
<exec dir="." executable="/usr/bin/protoc">
|
||||
<arg value="src/osmand_odb.proto" />
|
||||
<arg value="--java_out=./src/" />
|
||||
</exec>
|
||||
</target>
|
||||
</project>
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
|
@ -15,6 +17,7 @@ import net.osmand.Algoritms;
|
|||
import net.osmand.binary.OsmandOdb.CityIndex;
|
||||
import net.osmand.binary.OsmandOdb.InteresectedStreets;
|
||||
import net.osmand.binary.OsmandOdb.MapEncodingRule;
|
||||
import net.osmand.binary.OsmandOdb.OsmAndPoiBoxDataAtom;
|
||||
import net.osmand.binary.OsmandOdb.OsmAndTransportIndex;
|
||||
import net.osmand.binary.OsmandOdb.PostcodeIndex;
|
||||
import net.osmand.binary.OsmandOdb.StreetIndex;
|
||||
|
@ -37,6 +40,7 @@ import net.sf.junidecode.Junidecode;
|
|||
import com.google.protobuf.CodedOutputStream;
|
||||
import com.google.protobuf.WireFormat;
|
||||
import com.google.protobuf.WireFormat.FieldType;
|
||||
import com.sun.org.apache.bcel.internal.generic.ALOAD;
|
||||
|
||||
public class BinaryMapIndexWriter {
|
||||
|
||||
|
@ -85,6 +89,7 @@ public class BinaryMapIndexWriter {
|
|||
|
||||
private final static int POI_INDEX_INIT = 12;
|
||||
private final static int POI_BOX = 13;
|
||||
private final static int POI_DATA = 14;
|
||||
|
||||
public BinaryMapIndexWriter(final RandomAccessFile raf) throws IOException{
|
||||
this.raf = raf;
|
||||
|
@ -114,10 +119,12 @@ public class BinaryMapIndexWriter {
|
|||
}
|
||||
|
||||
|
||||
private void preserveInt32Size() throws IOException {
|
||||
private long preserveInt32Size() throws IOException {
|
||||
codedOutStream.flush();
|
||||
stackSizes.push(raf.getFilePointer());
|
||||
long filePointer = raf.getFilePointer();
|
||||
stackSizes.push(filePointer);
|
||||
codedOutStream.writeFixed32NoTag(0);
|
||||
return filePointer + 4;
|
||||
}
|
||||
|
||||
private int writeInt32Size() throws IOException{
|
||||
|
@ -737,14 +744,22 @@ public class BinaryMapIndexWriter {
|
|||
codedOutStream.writeMessage(OsmAndTransportIndex.STRINGTABLE_FIELD_NUMBER, st.build());
|
||||
}
|
||||
|
||||
public void startWritePOIIndex(String name) throws IOException {
|
||||
public long startWritePOIIndex(String name) throws IOException {
|
||||
pushState(POI_INDEX_INIT, OSMAND_STRUCTURE_INIT);
|
||||
codedOutStream.writeTag(OsmandOdb.OsmAndStructure.POIINDEX_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED);
|
||||
stackBounds.push(new Bounds(0, 0, 0, 0)); // for poi index tree
|
||||
preserveInt32Size();
|
||||
long startPoiIndex = preserveInt32Size();
|
||||
if(name != null){
|
||||
codedOutStream.writeString(OsmandOdb.OsmAndTransportIndex.NAME_FIELD_NUMBER, name);
|
||||
codedOutStream.writeString(OsmandOdb.OsmAndPoiIndex.NAME_FIELD_NUMBER, name);
|
||||
}
|
||||
return startPoiIndex;
|
||||
}
|
||||
|
||||
public void endWritePOIIndex() throws IOException {
|
||||
popState(POI_INDEX_INIT);
|
||||
int len = writeInt32Size();
|
||||
stackBounds.pop();
|
||||
System.out.println("POI INDEX SIZE : " + len);
|
||||
}
|
||||
|
||||
public Map<String, Integer> writePOICategoriesTable(Map<String, Map<String, Integer>> categories)
|
||||
|
@ -771,23 +786,95 @@ public class BinaryMapIndexWriter {
|
|||
return catIndexes;
|
||||
}
|
||||
|
||||
public void writePoiDataAtom(long id, int x24shift, int y24shift, String nameEn, String name, TIntArrayList types, String openingHours,
|
||||
String site, String phone) throws IOException {
|
||||
checkPeekState(POI_DATA);
|
||||
|
||||
OsmAndPoiBoxDataAtom.Builder builder = OsmandOdb.OsmAndPoiBoxDataAtom.newBuilder();
|
||||
builder.setDx(x24shift);
|
||||
builder.setDy(y24shift);
|
||||
for(int i=0; i < types.size(); i++){
|
||||
int j = types.get(i);
|
||||
builder.addCategories(j);
|
||||
}
|
||||
|
||||
if(!Algoritms.isEmpty(name)){
|
||||
builder.setName(name);
|
||||
}
|
||||
if(!Algoritms.isEmpty(nameEn)){
|
||||
builder.setNameEn(nameEn);
|
||||
}
|
||||
builder.setId(id);
|
||||
if(!Algoritms.isEmpty(openingHours)){
|
||||
builder.setOpeningHours(openingHours);
|
||||
}
|
||||
if(!Algoritms.isEmpty(site)){
|
||||
builder.setSite(site);
|
||||
}
|
||||
if(!Algoritms.isEmpty(phone)){
|
||||
builder.setPhone(phone);
|
||||
}
|
||||
|
||||
codedOutStream.writeMessage(OsmandOdb.OsmAndPoiBoxData.POIDATA_FIELD_NUMBER, builder.build());
|
||||
|
||||
}
|
||||
|
||||
public void startWritePoiBox(int zoom) throws IOException {
|
||||
pushState(POI_BOX, POI_INDEX_INIT);
|
||||
codedOutStream.writeTag(OsmandOdb.OsmAndTransportIndex.ROUTES_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED);
|
||||
public void startWritePoiData(int zoom, int x, int y, long fpPoiIndex, long fpPoiBox) throws IOException {
|
||||
pushState(POI_DATA, POI_INDEX_INIT);
|
||||
codedOutStream.writeTag(OsmandOdb.OsmAndPoiIndex.POIDATA_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED);
|
||||
long startPoiData = preserveInt32Size();
|
||||
// write shift to that data
|
||||
long filePointer = raf.getFilePointer();
|
||||
raf.seek(fpPoiBox);
|
||||
raf.writeInt((int) (startPoiData - fpPoiIndex));
|
||||
raf.seek(filePointer);
|
||||
|
||||
codedOutStream.writeUInt32(OsmandOdb.OsmAndPoiBoxData.ZOOM_FIELD_NUMBER, zoom);
|
||||
codedOutStream.writeUInt32(OsmandOdb.OsmAndPoiBoxData.X_FIELD_NUMBER, x);
|
||||
codedOutStream.writeUInt32(OsmandOdb.OsmAndPoiBoxData.Y_FIELD_NUMBER, y);
|
||||
|
||||
}
|
||||
|
||||
public void endWritePoiData() throws IOException {
|
||||
popState(POI_DATA);
|
||||
writeInt32Size();
|
||||
}
|
||||
|
||||
public long startWritePoiBox(int zoom, int tileX, int tileY) throws IOException {
|
||||
checkPeekState(POI_INDEX_INIT, POI_BOX);
|
||||
if(state.peek() == POI_INDEX_INIT){
|
||||
codedOutStream.writeTag(OsmandOdb.OsmAndPoiIndex.BOXES_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED);
|
||||
} else {
|
||||
codedOutStream.writeTag(OsmandOdb.OsmAndPoiBox.SUBBOXES_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED);
|
||||
}
|
||||
state.push(POI_BOX);
|
||||
preserveInt32Size();
|
||||
|
||||
Bounds bounds = stackBounds.peek();
|
||||
int parentZoom = bounds.rightX;
|
||||
int parentTileX = bounds.leftX;
|
||||
int parentTileY = bounds.topY;
|
||||
|
||||
int pTileX = parentTileX << (zoom - parentZoom);
|
||||
int pTileY = parentTileY << (zoom - parentZoom);
|
||||
|
||||
codedOutStream.writeSInt32(OsmandOdb.OsmAndPoiBox.LEFT_FIELD_NUMBER, tileX - pTileX);
|
||||
codedOutStream.writeSInt32(OsmandOdb.OsmAndPoiBox.TOP_FIELD_NUMBER, tileY - pTileY);
|
||||
codedOutStream.writeUInt32(OsmandOdb.OsmAndPoiBox.ZOOM_FIELD_NUMBER, (zoom - parentZoom));
|
||||
stackBounds.push(new Bounds(tileX, zoom, tileY, 0 ));
|
||||
|
||||
|
||||
codedOutStream.writeFixed32(OsmandOdb.OsmAndPoiBox.SHIFTTODATA_FIELD_NUMBER, 0);
|
||||
codedOutStream.flush();
|
||||
long filePointer = raf.getFilePointer() - 4;
|
||||
|
||||
return filePointer;
|
||||
}
|
||||
|
||||
public void endWritePoiBox() throws IOException {
|
||||
popState(POI_BOX);
|
||||
writeInt32Size();
|
||||
}
|
||||
|
||||
public void endWritePOIIndex() throws IOException {
|
||||
popState(POI_INDEX_INIT);
|
||||
int len = writeInt32Size();
|
||||
stackBounds.pop();
|
||||
System.out.println("POI INDEX SIZE : " + len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -827,4 +914,5 @@ public class BinaryMapIndexWriter {
|
|||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -542,7 +542,8 @@ public class IndexCreator {
|
|||
if (indexPOI) {
|
||||
progress.setGeneralProgress("[95 of 100]");
|
||||
progress.startTask("Writing poi index to binary file...", -1);
|
||||
indexPoiCreator.writeBinaryPoiIndex(writer, regionName, progress);
|
||||
// TODO uncomment
|
||||
// indexPoiCreator.writeBinaryPoiIndex(writer, regionName, progress);
|
||||
}
|
||||
|
||||
if (indexTransport) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package net.osmand.data.preparation;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
@ -15,8 +17,6 @@ import java.util.Iterator;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.IProgress;
|
||||
|
@ -33,21 +33,22 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class IndexPoiCreator extends AbstractIndexPartCreator {
|
||||
|
||||
|
||||
private static final Log log = LogFactory.getLog(IndexPoiCreator.class);
|
||||
|
||||
|
||||
private Connection poiConnection;
|
||||
private File poiIndexFile;
|
||||
private PreparedStatement poiPreparedStatement;
|
||||
private static final int ZOOM_TO_SAVE_END = 14;
|
||||
private static final int ZOOM_TO_SAVE_END = 15;
|
||||
private static final int ZOOM_TO_SAVE_START = 6;
|
||||
|
||||
private static final int SHIFT_BYTES_CATEGORY = 7;
|
||||
|
||||
private List<Amenity> tempAmenityList = new ArrayList<Amenity>();
|
||||
|
||||
public IndexPoiCreator(){
|
||||
public IndexPoiCreator() {
|
||||
}
|
||||
|
||||
public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException{
|
||||
|
||||
public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException {
|
||||
tempAmenityList.clear();
|
||||
tempAmenityList = Amenity.parseAmenities(e, tempAmenityList);
|
||||
if (!tempAmenityList.isEmpty() && poiPreparedStatement != null) {
|
||||
|
@ -66,7 +67,7 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void commitAndClosePoiFile(Long lastModifiedDate) throws SQLException {
|
||||
closeAllPreparedStatements();
|
||||
if (poiConnection != null) {
|
||||
|
@ -78,10 +79,10 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEntity(Entity e){
|
||||
|
||||
private void checkEntity(Entity e) {
|
||||
String name = e.getTag(OSMTagKey.NAME);
|
||||
if (name == null){
|
||||
if (name == null) {
|
||||
String msg = "";
|
||||
Collection<String> keys = e.getTagKeySet();
|
||||
int cnt = 0;
|
||||
|
@ -101,10 +102,10 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void insertAmenityIntoPoi(Amenity amenity) throws SQLException {
|
||||
assert IndexConstants.POI_TABLE != null : "use constants here to show table usage "; //$NON-NLS-1$
|
||||
|
||||
|
||||
poiPreparedStatement.setLong(1, amenity.getId());
|
||||
poiPreparedStatement.setInt(2, MapUtils.get31TileNumberX(amenity.getLocation().getLongitude()));
|
||||
poiPreparedStatement.setInt(3, MapUtils.get31TileNumberY(amenity.getLocation().getLatitude()));
|
||||
|
@ -117,7 +118,6 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
|
|||
poiPreparedStatement.setString(10, amenity.getPhone());
|
||||
addBatch(poiPreparedStatement);
|
||||
}
|
||||
|
||||
|
||||
public void createDatabaseStructure(File poiIndexFile) throws SQLException {
|
||||
this.poiIndexFile = poiIndexFile;
|
||||
|
@ -128,31 +128,57 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
|
|||
poiIndexFile.getParentFile().mkdirs();
|
||||
// creating connection
|
||||
poiConnection = (Connection) DBDialect.SQLITE.getDatabaseConnection(poiIndexFile.getAbsolutePath(), log);
|
||||
|
||||
|
||||
// create database structure
|
||||
Statement stat = poiConnection.createStatement();
|
||||
stat.executeUpdate("create table " + IndexConstants.POI_TABLE + //$NON-NLS-1$
|
||||
"(id bigint, x int, y int, name_en varchar(1024), name varchar(1024), " +
|
||||
"type varchar(1024), subtype varchar(1024), opening_hours varchar(1024), phone varchar(1024), site varchar(1024)," +
|
||||
"primary key(id, type, subtype))");
|
||||
stat.executeUpdate("create index poi_loc on poi (x, y, type, subtype)");
|
||||
stat.executeUpdate("create index poi_id on poi (id, type, subtype)");
|
||||
stat.execute("PRAGMA user_version = " + IndexConstants.POI_TABLE_VERSION); //$NON-NLS-1$
|
||||
stat.close();
|
||||
|
||||
// create prepared statment
|
||||
stat.executeUpdate("create table " + IndexConstants.POI_TABLE + //$NON-NLS-1$
|
||||
"(id bigint, x int, y int, name_en varchar(1024), name varchar(1024), "
|
||||
+ "type varchar(1024), subtype varchar(1024), opening_hours varchar(1024), phone varchar(1024), site varchar(1024),"
|
||||
+ "primary key(id, type, subtype))");
|
||||
stat.executeUpdate("create index poi_loc on poi (x, y, type, subtype)");
|
||||
stat.executeUpdate("create index poi_id on poi (id, type, subtype)");
|
||||
stat.execute("PRAGMA user_version = " + IndexConstants.POI_TABLE_VERSION); //$NON-NLS-1$
|
||||
stat.close();
|
||||
|
||||
// create prepared statment
|
||||
poiPreparedStatement = poiConnection
|
||||
.prepareStatement("INSERT INTO " + IndexConstants.POI_TABLE + "(id, x, y, name_en, name, type, subtype, opening_hours, site, phone) " + //$NON-NLS-1$//$NON-NLS-2$
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
pStatements.put(poiPreparedStatement, 0);
|
||||
|
||||
|
||||
|
||||
poiConnection.setAutoCommit(false);
|
||||
}
|
||||
|
||||
|
||||
private void buildTypeIds(String category, String subcategory, Map<String, Map<String, Integer>> categories,
|
||||
Map<String, Integer> catIndexes, TIntArrayList types) {
|
||||
types.clear();
|
||||
Map<String, Integer> map = categories.get(category);
|
||||
if (map == null) {
|
||||
throw new IllegalArgumentException("Unknown category " + category);
|
||||
}
|
||||
int catInd = catIndexes.get(category);
|
||||
if (subcategory.contains(";") || subcategory.contains(",")) {
|
||||
String[] split = subcategory.split(",|;");
|
||||
for (String sub : split) {
|
||||
sub = sub.trim();
|
||||
Integer subcatInd = map.get(sub);
|
||||
if (subcatInd == null) {
|
||||
throw new IllegalArgumentException("Unknown subcategory " + sub + " category " + category);
|
||||
}
|
||||
types.add((subcatInd << SHIFT_BYTES_CATEGORY) | catInd);
|
||||
}
|
||||
} else {
|
||||
subcategory = subcategory.trim();
|
||||
Integer subcatInd = map.get(subcategory);
|
||||
if (subcatInd == null) {
|
||||
throw new IllegalArgumentException("Unknown subcategory " + subcategory + " category " + category);
|
||||
}
|
||||
types.add((subcatInd << SHIFT_BYTES_CATEGORY) | catInd);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBinaryPoiIndex(BinaryMapIndexWriter writer, String regionName, IProgress progress) throws SQLException, IOException {
|
||||
if(poiPreparedStatement != null){
|
||||
if (poiPreparedStatement != null) {
|
||||
closePreparedStatements(poiPreparedStatement);
|
||||
}
|
||||
poiConnection.commit();
|
||||
|
@ -177,61 +203,204 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
|
|||
Statement stat = rs.getStatement();
|
||||
rs.close();
|
||||
stat.close();
|
||||
|
||||
|
||||
// 1. write header
|
||||
writer.startWritePOIIndex(regionName);
|
||||
|
||||
long startFpPoiIndex = writer.startWritePOIIndex(regionName);
|
||||
|
||||
// 2. write categories table
|
||||
Map<String, Integer> catIndexes = writer.writePOICategoriesTable(categories);
|
||||
|
||||
|
||||
// 3. write boxes
|
||||
String selectZm = (31 - ZOOM_TO_SAVE_END) +"";
|
||||
rs = poiConnection.createStatement().executeQuery("SELECT DISTINCT x>>"+selectZm +", y>>"+selectZm + " from poi");
|
||||
Set<Long>[] zooms = new Set[ZOOM_TO_SAVE_END + 1];
|
||||
String selectZm = (31 - ZOOM_TO_SAVE_END) + "";
|
||||
rs = poiConnection.createStatement().executeQuery("SELECT DISTINCT x>>" + selectZm + ", y>>" + selectZm + " from poi");
|
||||
Tree<Long> rootZoomsTree = new Tree<Long>();
|
||||
int zoomToStart = ZOOM_TO_SAVE_START;
|
||||
for(int i=zoomToStart; i<=ZOOM_TO_SAVE_END; i++){
|
||||
zooms[i] = new TreeSet<Long>();
|
||||
}
|
||||
while(rs.next()){
|
||||
while (rs.next()) {
|
||||
int x = rs.getInt(1);
|
||||
int y = rs.getInt(2);
|
||||
for(int i=zoomToStart; i<=ZOOM_TO_SAVE_END; i++){
|
||||
Tree<Long> prevTree = rootZoomsTree;
|
||||
for (int i = zoomToStart; i <= ZOOM_TO_SAVE_END; i++) {
|
||||
int shift = ZOOM_TO_SAVE_END - i;
|
||||
long l = (((long)x >> shift) << 31) | ((long)y >> shift);
|
||||
zooms[i].add(l);
|
||||
long l = (((long) x >> shift) << 31) | ((long) y >> shift);
|
||||
|
||||
Tree<Long> subtree = prevTree.getSubtreeByNode(l);
|
||||
if (subtree == null) {
|
||||
subtree = new Tree<Long>();
|
||||
subtree.setNode(l);
|
||||
prevTree.addSubTree(subtree);
|
||||
}
|
||||
prevTree = subtree;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = zoomToStart; i < ZOOM_TO_SAVE_END; i++) {
|
||||
if (zooms[i].size() > 4) {
|
||||
int level = 0;
|
||||
for (; level < (ZOOM_TO_SAVE_END - zoomToStart); level++) {
|
||||
int subtrees = rootZoomsTree.getSubTreesOnLevel(level);
|
||||
if (subtrees > 8) {
|
||||
level--;
|
||||
break;
|
||||
}
|
||||
zoomToStart = i;
|
||||
}
|
||||
|
||||
for (int i = zoomToStart; i <= ZOOM_TO_SAVE_END; i++) {
|
||||
System.out.println(i + " " + zooms[i].size());
|
||||
if (level > 0) {
|
||||
rootZoomsTree.extractChildrenFromLevel(level);
|
||||
zoomToStart = zoomToStart + level;
|
||||
}
|
||||
|
||||
|
||||
// write tree using stack
|
||||
Map<Long, Long> fpToWriteSeeks = new LinkedHashMap<Long, Long>();
|
||||
for (Tree<Long> subs : rootZoomsTree.getSubtrees()) {
|
||||
writePoiBoxes(writer, subs, zoomToStart, fpToWriteSeeks);
|
||||
}
|
||||
|
||||
stat = rs.getStatement();
|
||||
rs.close();
|
||||
stat.close();
|
||||
|
||||
|
||||
|
||||
// 4. write poi data
|
||||
PreparedStatement prepareStatement = poiConnection
|
||||
.prepareStatement("SELECT id, x, y, name_en, name, type, subtype, opening_hours, site, phone from poi "
|
||||
+ "where x >= ? AND x < ? AND y >= ? AND y < ?");
|
||||
TIntArrayList types = new TIntArrayList();
|
||||
for (Map.Entry<Long, Long> entry : fpToWriteSeeks.entrySet()) {
|
||||
long l = entry.getKey();
|
||||
int z = ZOOM_TO_SAVE_END;
|
||||
int x = (int) (l >> 31);
|
||||
int y = (int) (l & ((1 << 31) - 1));
|
||||
writer.startWritePoiData(z, x, y, startFpPoiIndex, entry.getValue());
|
||||
|
||||
prepareStatement.setInt(1, x << (31 - z));
|
||||
prepareStatement.setInt(2, (x + 1) << (31 - z));
|
||||
prepareStatement.setInt(3, y << (31 - z));
|
||||
prepareStatement.setInt(4, (y + 1) << (31 - z));
|
||||
rs = prepareStatement.executeQuery();
|
||||
while (rs.next()) {
|
||||
long id = rs.getLong(1);
|
||||
int x31 = rs.getInt(2);
|
||||
int y31 = rs.getInt(3);
|
||||
int x24shift = (x31 >> 7) - (x << (24 - z));
|
||||
int y24shift = (y31 >> 7) - (y << (24 - z));
|
||||
String nameEn = rs.getString(4);
|
||||
String name = rs.getString(5);
|
||||
String type = rs.getString(6);
|
||||
String subtype = rs.getString(7);
|
||||
buildTypeIds(type, subtype, categories, catIndexes, types);
|
||||
|
||||
String openingHours = rs.getString(8);
|
||||
String site = rs.getString(9);
|
||||
String phone = rs.getString(10);
|
||||
|
||||
writer.writePoiDataAtom(id, x24shift, y24shift, nameEn, name, types, openingHours, site, phone);
|
||||
|
||||
}
|
||||
writer.endWritePoiData();
|
||||
rs.close();
|
||||
|
||||
}
|
||||
|
||||
prepareStatement.close();
|
||||
|
||||
writer.endWritePOIIndex();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void writePoiBoxes(BinaryMapIndexWriter writer, Tree<Long> tree, int zoom, Map<Long, Long> fpToWriteSeeks) throws IOException {
|
||||
long l = tree.getNode();
|
||||
int x = (int) (l >> 31);
|
||||
int y = (int) (l & ((1 << 31) - 1));
|
||||
long fp = writer.startWritePoiBox(zoom, x, y);
|
||||
if (zoom < ZOOM_TO_SAVE_END) {
|
||||
for (Tree<Long> subTree : tree.getSubtrees()) {
|
||||
writePoiBoxes(writer, subTree, zoom + 1, fpToWriteSeeks);
|
||||
}
|
||||
} else {
|
||||
fpToWriteSeeks.put(l, fp);
|
||||
}
|
||||
writer.endWritePoiBox();
|
||||
}
|
||||
|
||||
private static class Tree<T> {
|
||||
|
||||
private T node;
|
||||
private List<Tree<T>> subtrees = null;
|
||||
|
||||
public List<Tree<T>> getSubtrees() {
|
||||
if (subtrees == null) {
|
||||
subtrees = new ArrayList<Tree<T>>();
|
||||
}
|
||||
return subtrees;
|
||||
}
|
||||
|
||||
public void addSubTree(Tree<T> t) {
|
||||
getSubtrees().add(t);
|
||||
}
|
||||
|
||||
public T getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public void setNode(T node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public void extractChildrenFromLevel(int level) {
|
||||
List<Tree<T>> list = new ArrayList<Tree<T>>();
|
||||
collectChildrenFromLevel(list, level);
|
||||
subtrees = list;
|
||||
}
|
||||
|
||||
public void collectChildrenFromLevel(List<Tree<T>> list, int level) {
|
||||
if (level == 0) {
|
||||
if (subtrees != null) {
|
||||
list.addAll(subtrees);
|
||||
}
|
||||
} else if (subtrees != null) {
|
||||
for (Tree<T> sub : subtrees) {
|
||||
sub.collectChildrenFromLevel(list, level - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getSubTreesOnLevel(int level) {
|
||||
if (level == 0) {
|
||||
if (subtrees == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return subtrees.size();
|
||||
}
|
||||
} else {
|
||||
int sum = 0;
|
||||
for (Tree<T> t : subtrees) {
|
||||
sum += t.getSubTreesOnLevel(level - 1);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
||||
public Tree<T> getSubtreeByNode(T node) {
|
||||
if (subtrees == null) {
|
||||
return null;
|
||||
}
|
||||
for (Tree<T> s : subtrees) {
|
||||
if (node.equals(s.getNode())) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws SQLException, FileNotFoundException, IOException {
|
||||
long time = System.currentTimeMillis();
|
||||
IndexPoiCreator poiCreator = new IndexPoiCreator();
|
||||
poiCreator.poiConnection = (Connection) DBDialect.SQLITE.getDatabaseConnection("/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.odb", log);
|
||||
BinaryMapIndexWriter writer = new BinaryMapIndexWriter(new RandomAccessFile("/home/victor/projects/OsmAnd/data/osm-gen/POI/Test-Ru.poi.obf", "rw"));
|
||||
poiCreator.poiConnection = (Connection) DBDialect.SQLITE.getDatabaseConnection(
|
||||
"/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.odb", log);
|
||||
BinaryMapIndexWriter writer = new BinaryMapIndexWriter(new RandomAccessFile(
|
||||
"/home/victor/projects/OsmAnd/data/osm-gen/POI/Test-Ru.poi.obf", "rw"));
|
||||
poiCreator.poiConnection.setAutoCommit(false);
|
||||
poiCreator.writeBinaryPoiIndex(writer, "Ru-mow", new ConsoleProgressImplementation());
|
||||
writer.close();
|
||||
System.out.println("TIME " + (System.currentTimeMillis() - time));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@ message OsmAndStructure {
|
|||
*/
|
||||
message StringTable {
|
||||
repeated string s = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
message OsmAndMapIndex {
|
||||
// encoded as fixed32 length delimited
|
||||
|
@ -271,12 +270,23 @@ message OsmAndPoiIndex {
|
|||
repeated OsmAndPoiBox boxes = 6; // children
|
||||
|
||||
// encoded as fixed32 length delimited
|
||||
repeated OsmAndPoiBoxData poiData = 7;
|
||||
repeated OsmAndPoiBoxData poiData = 9;
|
||||
|
||||
}
|
||||
|
||||
message OsmAndCategoryTable {
|
||||
message IndexedStringTable {
|
||||
// common prefix for all strings inside
|
||||
optional string prefix = 1;
|
||||
|
||||
repeated string s = 3;
|
||||
|
||||
// subtables are supposed to make search faster
|
||||
// instead of searching through all strings
|
||||
// it's enought to read prefix in the header
|
||||
repeated IndexedStringTable subtables = 6;
|
||||
}
|
||||
|
||||
message OsmAndCategoryTable {
|
||||
required string category = 1;
|
||||
repeated string subcategories = 3;
|
||||
}
|
||||
|
@ -289,18 +299,15 @@ message OsmAndPoiBox {
|
|||
|
||||
optional OsmAndPoiCategories categories = 4;
|
||||
|
||||
optional StringTable includeNamesList = 5;
|
||||
optional IndexedStringTable includeNamesList = 5;
|
||||
|
||||
optional StringTable excludeNamesList = 6;
|
||||
optional IndexedStringTable excludeNamesList = 6;
|
||||
|
||||
// encoded as fixed32 length delimited
|
||||
repeated OsmAndPoiBox subBoxes = 10;
|
||||
|
||||
optional uint32 shiftToData = 14; // shift to OsmAndPoiBoxDataAtom
|
||||
// TODO
|
||||
// TransportStop.Message.start - sizeof(TransportStop.Message.length) - routes[i]
|
||||
// = TransportRoute.Message.start - sizeof(TransportRoute.Message.length)
|
||||
// message is started when body is started
|
||||
optional fixed32 shiftToData = 14; // shift to OsmAndPoiBoxData message from OsmAndPoiIndex.start
|
||||
// message is started when body is started
|
||||
}
|
||||
|
||||
message OsmAndPoiCategories {
|
||||
|
@ -309,9 +316,26 @@ message OsmAndPoiCategories {
|
|||
}
|
||||
|
||||
message OsmAndPoiBoxData {
|
||||
repeated OsmAndPoiBoxDataAtom poiData = 3;
|
||||
optional uint32 zoom = 1; // zoom level
|
||||
optional uint32 x = 2; // x tile
|
||||
optional uint32 y = 3; // y tile
|
||||
|
||||
repeated OsmAndPoiBoxDataAtom poiData = 5;
|
||||
}
|
||||
|
||||
message OsmAndPoiBoxDataAtom {
|
||||
required sint32 dx = 2; // delta encoded to OsmAndPoiBox on 24 zoom
|
||||
required sint32 dy = 3; // delta encoded to OsmAndPoiBox on 24 zoom
|
||||
|
||||
optional uint64 id = 4;
|
||||
optional string name = 5;
|
||||
optional string nameEn = 6;
|
||||
|
||||
repeated uint32 categories = 7;
|
||||
|
||||
optional string openingHours = 10;
|
||||
optional string site = 11;
|
||||
optional string phone = 12;
|
||||
optional string note = 13;
|
||||
|
||||
}
|
Loading…
Reference in a new issue