Add coastline processing
This commit is contained in:
parent
d5f233cacf
commit
453747920e
10 changed files with 343 additions and 257 deletions
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/DataExtractionOSM/src/net/osmand/data/index/IndexZipper.java"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="net.osmand.data.index.IndexZipper"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value=""C:\Users\tpd\Documents\Osmand maps""/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="DataExtractionOSM"/>
|
||||
</launchConfiguration>
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/DataExtractionOSM/src/net/osmand/swing/OsmExtractionUI.java"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="net.osmand.swing.OsmExtractionUI"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="DataExtractionOSM"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+UseParallelGC -Xmx1300M -Xmn256M -Djava.util.logging.config.file=logging.properties"/>
|
||||
</launchConfiguration>
|
|
@ -284,4 +284,91 @@ public class MapAlgorithms {
|
|||
return (int) rx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* outx,outy are the coordinates out of the box
|
||||
* inx,iny are the coordinates from the box
|
||||
* @return -1 if there is no instersection or x<<32 | y
|
||||
*/
|
||||
public static long calculateIntersection(int inx, int iny, int outx, int outy, int leftX, int rightX, int bottomY, int topY) {
|
||||
int by = -1;
|
||||
int bx = -1;
|
||||
// firstly try to search if the line goes in
|
||||
if (outy < topY && iny >= topY) {
|
||||
int tx = (int) (outx + ((double) (inx - outx) * (topY - outy)) / (iny - outy));
|
||||
if (leftX <= tx && tx <= rightX) {
|
||||
bx = tx;
|
||||
by = topY;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
}
|
||||
if (outy > bottomY && iny <= bottomY) {
|
||||
int tx = (int) (outx + ((double) (inx - outx) * (outy - bottomY)) / (outy - iny));
|
||||
if (leftX <= tx && tx <= rightX) {
|
||||
bx = tx;
|
||||
by = bottomY;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
}
|
||||
if (outx < leftX && inx >= leftX) {
|
||||
int ty = (int) (outy + ((double) (iny - outy) * (leftX - outx)) / (inx - outx));
|
||||
if (ty >= topY && ty <= bottomY) {
|
||||
by = ty;
|
||||
bx = leftX;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
|
||||
}
|
||||
if (outx > rightX && inx <= rightX) {
|
||||
int ty = (int) (outy + ((double) (iny - outy) * (outx - rightX)) / (outx - inx));
|
||||
if (ty >= topY && ty <= bottomY) {
|
||||
by = ty;
|
||||
bx = rightX;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// try to search if point goes out
|
||||
if (outy > topY && iny <= topY) {
|
||||
int tx = (int) (outx + ((double) (inx - outx) * (topY - outy)) / (iny - outy));
|
||||
if (leftX <= tx && tx <= rightX) {
|
||||
bx = tx;
|
||||
by = topY;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
}
|
||||
if (outy < bottomY && iny >= bottomY) {
|
||||
int tx = (int) (outx + ((double) (inx - outx) * (outy - bottomY)) / (outy - iny));
|
||||
if (leftX <= tx && tx <= rightX) {
|
||||
bx = tx;
|
||||
by = bottomY;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
}
|
||||
if (outx > leftX && inx <= leftX) {
|
||||
int ty = (int) (outy + ((double) (iny - outy) * (leftX - outx)) / (inx - outx));
|
||||
if (ty >= topY && ty <= bottomY) {
|
||||
by = ty;
|
||||
bx = leftX;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
|
||||
}
|
||||
if (outx < rightX && inx >= rightX) {
|
||||
int ty = (int) (outy + ((double) (iny - outy) * (outx - rightX)) / (outx - inx));
|
||||
if (ty >= topY && ty <= bottomY) {
|
||||
by = ty;
|
||||
bx = rightX;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (outx == rightX || outx == leftX || outy == topY || outy == bottomY) {
|
||||
bx = outx;
|
||||
by = outy;
|
||||
}
|
||||
return -1l;
|
||||
}
|
||||
}
|
|
@ -311,8 +311,10 @@ public class BinaryMapIndexWriter {
|
|||
|
||||
checkPeekState(MAP_ROOT_LEVEL_INIT);
|
||||
StringTable.Builder bs = OsmandOdb.StringTable.newBuilder();
|
||||
for (String s : stringTable.keySet()) {
|
||||
bs.addS(s);
|
||||
if (stringTable != null) {
|
||||
for (String s : stringTable.keySet()) {
|
||||
bs.addS(s);
|
||||
}
|
||||
}
|
||||
StringTable st = bs.build();
|
||||
builder.setStringTable(st);
|
||||
|
@ -424,14 +426,16 @@ public class BinaryMapIndexWriter {
|
|||
}
|
||||
|
||||
mapDataBuf.clear();
|
||||
for (Entry<MapRulType, String> s : names.entrySet()) {
|
||||
writeRawVarint32(mapDataBuf, s.getKey().getTargetId());
|
||||
Integer ls = stringTable.get(s.getValue());
|
||||
if (ls == null) {
|
||||
ls = stringTable.size();
|
||||
stringTable.put(s.getValue(), ls);
|
||||
if (names != null) {
|
||||
for (Entry<MapRulType, String> s : names.entrySet()) {
|
||||
writeRawVarint32(mapDataBuf, s.getKey().getTargetId());
|
||||
Integer ls = stringTable.get(s.getValue());
|
||||
if (ls == null) {
|
||||
ls = stringTable.size();
|
||||
stringTable.put(s.getValue(), ls);
|
||||
}
|
||||
writeRawVarint32(mapDataBuf, ls);
|
||||
}
|
||||
writeRawVarint32(mapDataBuf, ls);
|
||||
}
|
||||
STRING_TABLE_SIZE += mapDataBuf.size();
|
||||
data.setStringNames(ByteString.copyFrom(mapDataBuf.toArray()));
|
||||
|
|
|
@ -1,45 +1,34 @@
|
|||
package net.osmand.data.preparation;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
import gnu.trove.procedure.TObjectProcedure;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
|
||||
import org.apache.tools.bzip2.CBZip2InputStream;
|
||||
|
||||
import rtree.Element;
|
||||
import rtree.LeafElement;
|
||||
import rtree.NonLeafElement;
|
||||
import rtree.RTree;
|
||||
import rtree.RTreeException;
|
||||
import rtree.Rect;
|
||||
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
import gnu.trove.procedure.TObjectProcedure;
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.binary.OsmandOdb.MapData;
|
||||
import net.osmand.binary.OsmandOdb.MapDataBlock;
|
||||
import net.osmand.binary.OsmandOdb.MapDataBlock.Builder;
|
||||
import net.osmand.data.MapAlgorithms;
|
||||
import net.osmand.data.preparation.MapZooms.MapZoomPair;
|
||||
import net.osmand.osm.Entity;
|
||||
import net.osmand.osm.Entity.EntityId;
|
||||
import net.osmand.osm.MapRenderingTypes.MapRulType;
|
||||
import net.osmand.osm.EntityInfo;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
@ -49,6 +38,9 @@ import net.osmand.osm.WayChain;
|
|||
import net.osmand.osm.io.OsmBaseStorage;
|
||||
import net.osmand.osm.io.OsmStorageWriter;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.tools.bzip2.CBZip2InputStream;
|
||||
|
||||
public class CoastlineProcessor {
|
||||
TLongObjectHashMap<WayChain> coastlinesEndPoint = new TLongObjectHashMap<WayChain>();
|
||||
TLongObjectHashMap<WayChain> coastlinesStartPoint = new TLongObjectHashMap<WayChain>();
|
||||
|
@ -63,8 +55,12 @@ public class CoastlineProcessor {
|
|||
private static final byte BITMASK = 0x3;
|
||||
private static final int BITS_COUNT = (1 << TILE_ZOOMLEVEL) * (1 << TILE_ZOOMLEVEL);
|
||||
|
||||
private final BitSet seaTileInfo = new BitSet(BITS_COUNT);
|
||||
private final BitSet landTileInfo = new BitSet(BITS_COUNT);
|
||||
|
||||
private final int zoomWaySmothness;
|
||||
private final MapRenderingTypes renderingTypes;
|
||||
private final MapZooms mapZooms;
|
||||
private final Log logMapDataWarn;
|
||||
private SimplisticQuadTree quadTree;
|
||||
|
||||
private static class SimplisticQuadTree {
|
||||
public boolean ocean;
|
||||
|
@ -80,6 +76,7 @@ public class CoastlineProcessor {
|
|||
}
|
||||
|
||||
SimplisticQuadTree[] children = null;
|
||||
List<Way> coastlines = null;
|
||||
|
||||
public SimplisticQuadTree[] getAllChildren(){
|
||||
initChildren();
|
||||
|
@ -90,6 +87,13 @@ public class CoastlineProcessor {
|
|||
return children != null;
|
||||
}
|
||||
|
||||
public void addCoastline(Way w){
|
||||
if(coastlines == null) {
|
||||
coastlines = new ArrayList<Way>();
|
||||
}
|
||||
coastlines.add(w);
|
||||
}
|
||||
|
||||
public SimplisticQuadTree getOrCreateSubTree(int x, int y, int zm) {
|
||||
if (zm <= zoom) {
|
||||
return this;
|
||||
|
@ -118,8 +122,17 @@ public class CoastlineProcessor {
|
|||
}
|
||||
|
||||
|
||||
public CoastlineProcessor() {
|
||||
public CoastlineProcessor(Log logMapDataWarn, MapZooms mapZooms, MapRenderingTypes renderingTypes, int zoomWaySmothness) {
|
||||
this.logMapDataWarn = logMapDataWarn;
|
||||
this.mapZooms = mapZooms;
|
||||
this.renderingTypes = renderingTypes;
|
||||
this.zoomWaySmothness = zoomWaySmothness;
|
||||
quadTree = constructTilesQuadTree();
|
||||
}
|
||||
|
||||
private void constructBitSetInfo(BitSet seaTileInfo , BitSet landTileInfo) {
|
||||
try {
|
||||
|
||||
InputStream stream = CoastlineProcessor.class.getResourceAsStream("oceantiles_12.dat.bz2");
|
||||
if (stream.read() != 'B' || stream.read() != 'Z') {
|
||||
throw new RuntimeException("The source stream must start with the characters BZ if it is to be read as a BZip2 stream."); //$NON-NLS-1$
|
||||
|
@ -129,24 +142,24 @@ public class CoastlineProcessor {
|
|||
for (int i = 0; i < BITS_COUNT / 4; i++) {
|
||||
currentByte = dis.read();
|
||||
if (((currentByte >> 6) & BITMASK) == SEA) {
|
||||
this.seaTileInfo.set(i * 4);
|
||||
seaTileInfo.set(i * 4);
|
||||
} else if (((currentByte >> 6) & BITMASK) == LAND) {
|
||||
this.landTileInfo.set(i * 4);
|
||||
landTileInfo.set(i * 4);
|
||||
}
|
||||
if (((currentByte >> 4) & BITMASK) == SEA) {
|
||||
this.seaTileInfo.set(i * 4 + 1);
|
||||
seaTileInfo.set(i * 4 + 1);
|
||||
} else if (((currentByte >> 4) & BITMASK) == LAND) {
|
||||
this.landTileInfo.set(i * 4 + 1);
|
||||
landTileInfo.set(i * 4 + 1);
|
||||
}
|
||||
if (((currentByte >> 2) & BITMASK) == SEA) {
|
||||
this.seaTileInfo.set(i * 4 + 2);
|
||||
seaTileInfo.set(i * 4 + 2);
|
||||
} else if (((currentByte >> 2) & BITMASK) == LAND) {
|
||||
this.landTileInfo.set(i * 4 + 2);
|
||||
landTileInfo.set(i * 4 + 2);
|
||||
}
|
||||
if ((currentByte & BITMASK) == SEA) {
|
||||
this.seaTileInfo.set(i * 4 + 3);
|
||||
seaTileInfo.set(i * 4 + 3);
|
||||
} else if (((currentByte >> 0) & BITMASK) == LAND) {
|
||||
this.landTileInfo.set(i * 4 + 3);
|
||||
landTileInfo.set(i * 4 + 3);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -154,11 +167,11 @@ public class CoastlineProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isWaterTile(int x, int y, int zoom) {
|
||||
private boolean isWaterTile(BitSet seaTileInfo, int x, int y, int zoom) {
|
||||
if (zoom >= TILE_ZOOMLEVEL) {
|
||||
int x1 = x >> (zoom - TILE_ZOOMLEVEL);
|
||||
int y1 = y >> (zoom - TILE_ZOOMLEVEL);
|
||||
if (!this.seaTileInfo.get(y1 * 4096 + x1)) {
|
||||
if (!seaTileInfo.get(y1 * 4096 + x1)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -168,7 +181,7 @@ public class CoastlineProcessor {
|
|||
int max = 1 << TILE_ZOOMLEVEL - zoom;
|
||||
for (int i = 0; i < max; i++) {
|
||||
for (int j = 0; j < max; j++) {
|
||||
if (!this.seaTileInfo.get((y1 + i) * 4096 + (x1 + i))) {
|
||||
if (!seaTileInfo.get((y1 + i) * 4096 + (x1 + i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -177,11 +190,11 @@ public class CoastlineProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isLandTile(int x, int y, int zoom) {
|
||||
private boolean isLandTile(BitSet landTileInfo, int x, int y, int zoom) {
|
||||
if (zoom >= TILE_ZOOMLEVEL) {
|
||||
int x1 = x >> (zoom - TILE_ZOOMLEVEL);
|
||||
int y1 = y >> (zoom - TILE_ZOOMLEVEL);
|
||||
if (!this.landTileInfo.get(y1 * 4096 + x1)) {
|
||||
if (!landTileInfo.get(y1 * 4096 + x1)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -191,7 +204,7 @@ public class CoastlineProcessor {
|
|||
int max = 1 << TILE_ZOOMLEVEL - zoom;
|
||||
for (int i = 0; i < max; i++) {
|
||||
for (int j = 0; j < max; j++) {
|
||||
if (!this.landTileInfo.get((y1 + i) * 4096 + (x1 + i))) {
|
||||
if (!landTileInfo.get((y1 + i) * 4096 + (x1 + i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +213,12 @@ public class CoastlineProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
public SimplisticQuadTree calculateTilesQuadTree(){
|
||||
public SimplisticQuadTree constructTilesQuadTree(){
|
||||
SimplisticQuadTree rootTree = new SimplisticQuadTree(0, 0, 0);
|
||||
|
||||
BitSet seaTileInfo = new BitSet(BITS_COUNT);
|
||||
BitSet landTileInfo = new BitSet(BITS_COUNT);
|
||||
constructBitSetInfo(seaTileInfo, landTileInfo);
|
||||
int baseZoom = 4;
|
||||
int tiles = 1 << baseZoom;
|
||||
ArrayList<SimplisticQuadTree> toVisit = new ArrayList<SimplisticQuadTree>();
|
||||
|
@ -219,10 +235,10 @@ public class CoastlineProcessor {
|
|||
for (SimplisticQuadTree subtree : toVisit) {
|
||||
int x = subtree.x;
|
||||
int y = subtree.y;
|
||||
if (isWaterTile(x, y, zoom)) {
|
||||
if (isWaterTile(seaTileInfo, x, y, zoom)) {
|
||||
cnt++;
|
||||
rootTree.getOrCreateSubTree(x, y, zoom).ocean = true;
|
||||
} else if (isLandTile(x, y, zoom)) {
|
||||
} else if (isLandTile(landTileInfo, x, y, zoom)) {
|
||||
rootTree.getOrCreateSubTree(x, y, zoom).land = true;
|
||||
cnt++;
|
||||
} else if(zoom < TILE_ZOOMLEVEL){
|
||||
|
@ -235,18 +251,176 @@ public class CoastlineProcessor {
|
|||
ntc ++;
|
||||
}
|
||||
}
|
||||
System.out.println(" Zoom " + zoom + " count " + cnt);
|
||||
// System.out.println(" Zoom " + zoom + " count " + cnt);
|
||||
toVisit = newToVisit;
|
||||
}
|
||||
System.out.println("Not covered " + ntc + " from " + (float) ntc / ((1 << TILE_ZOOMLEVEL) * (1<<TILE_ZOOMLEVEL)));
|
||||
// System.out.println("Not covered " + ntc + " from " + (float) ntc / ((1 << TILE_ZOOMLEVEL) * (1<<TILE_ZOOMLEVEL)));
|
||||
return rootTree;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void writeCoastlinesFile(BinaryMapIndexWriter writer) throws IOException {
|
||||
writeCoastlinesFile(writer, quadTree);
|
||||
}
|
||||
|
||||
private void writeCoastlinesFile(BinaryMapIndexWriter writer, SimplisticQuadTree simplisticQuadTree) throws IOException {
|
||||
writer.startWriteMapIndex("Coastline");
|
||||
// write map encoding rules
|
||||
writer.writeMapEncodingRules(renderingTypes.getEncodingRuleTypes());
|
||||
|
||||
// TODO zooms file iterate in cycle
|
||||
MapZoomPair p = mapZooms.getLevels().get(mapZooms.getLevels().size() - 1);
|
||||
// write map levels and map index
|
||||
writer.startWriteMapLevelIndex(p.getMinZoom(), p.getMinZoom(), 0, 0, (1 << 31) - 1, (1 << 31) - 1);
|
||||
|
||||
Map<SimplisticQuadTree, BinaryFileReference> refs = new LinkedHashMap<CoastlineProcessor.SimplisticQuadTree, BinaryFileReference>();
|
||||
writeBinaryMapTree(simplisticQuadTree, writer, refs);
|
||||
|
||||
// without data blocks
|
||||
writeBinaryMapBlock(simplisticQuadTree, writer, refs);
|
||||
|
||||
writer.endWriteMapLevelIndex();
|
||||
|
||||
writer.endWriteMapIndex();
|
||||
writer.flush();
|
||||
|
||||
}
|
||||
|
||||
private void writeBinaryMapBlock(SimplisticQuadTree simplisticQuadTree, BinaryMapIndexWriter writer,
|
||||
Map<SimplisticQuadTree, BinaryFileReference> refs) throws IOException {
|
||||
Iterator<Entry<SimplisticQuadTree, BinaryFileReference>> it = refs.entrySet().iterator();
|
||||
TIntArrayList type = new TIntArrayList();
|
||||
type.add(renderingTypes.getCoastlineRuleType().getTargetId());
|
||||
|
||||
while(it.hasNext()) {
|
||||
Entry<SimplisticQuadTree, BinaryFileReference> e = it.next();
|
||||
MapDataBlock.Builder dataBlock = MapDataBlock.newBuilder();
|
||||
SimplisticQuadTree quad = e.getKey();
|
||||
|
||||
for (Way w : quad.coastlines) {
|
||||
dataBlock.setBaseId(w.getId());
|
||||
ByteArrayOutputStream bcoordinates = new ByteArrayOutputStream();
|
||||
for (Node n : w.getNodes()) {
|
||||
if (n != null) {
|
||||
int y = MapUtils.get31TileNumberY(n.getLatitude());
|
||||
int x = MapUtils.get31TileNumberX(n.getLongitude());
|
||||
Algoritms.writeInt(bcoordinates, x);
|
||||
Algoritms.writeInt(bcoordinates, y);
|
||||
}
|
||||
}
|
||||
MapData mapData = writer.writeMapData(0,
|
||||
quad.x << (31 - quad.zoom), quad.y << (31 - quad.zoom), false,
|
||||
bcoordinates.toByteArray(), null, type, null, null, null, dataBlock);
|
||||
if (mapData != null) {
|
||||
dataBlock.addDataObjects(mapData);
|
||||
}
|
||||
}
|
||||
|
||||
writer.writeMapDataBlock(dataBlock, null, e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeBinaryMapTree(SimplisticQuadTree quadTree, BinaryMapIndexWriter writer,
|
||||
Map<SimplisticQuadTree, BinaryFileReference> refs) throws IOException {
|
||||
int xL = (quadTree.x) << (31 - quadTree.zoom);
|
||||
int xR = (quadTree.x + 1) << (31 - quadTree.zoom) - 1;
|
||||
int yT = (quadTree.y) << (31 - quadTree.zoom);
|
||||
int yB = (quadTree.y + 1) << (31 - quadTree.zoom) - 1;
|
||||
BinaryFileReference ref = writer.startMapTreeElement(xL, xR, yT, yB, false,
|
||||
quadTree.ocean, quadTree.land);
|
||||
if (ref != null) {
|
||||
refs.put(quadTree, ref);
|
||||
}
|
||||
|
||||
if (quadTree.areChildrenDefined()) {
|
||||
SimplisticQuadTree[] allChildren = quadTree.getAllChildren();
|
||||
|
||||
for (SimplisticQuadTree ch : allChildren) {
|
||||
writeBinaryMapTree(ch, writer, refs);
|
||||
}
|
||||
}
|
||||
writer.endWriteMapTreeElement();
|
||||
|
||||
}
|
||||
|
||||
public void processCoastline(Way e) {
|
||||
// for(MapZoomPair p : mapZooms.getLevels()) {
|
||||
renderingTypes.getCoastlineRuleType().updateFreq();
|
||||
MapZoomPair p = mapZooms.getLevels().get(mapZooms.getLevels().size() - 1);
|
||||
{
|
||||
int z = (p.getMinZoom() + p.getMaxZoom()) / 2;
|
||||
List<Node> ns = e.getNodes();
|
||||
if(ns.size() < 2) {
|
||||
return;
|
||||
}
|
||||
int i = 1;
|
||||
Node prevNode = ns.get(0);
|
||||
int px31 = MapUtils.get31TileNumberX(prevNode.getLongitude());
|
||||
int py31 = MapUtils.get31TileNumberY(prevNode.getLatitude());
|
||||
while(i<ns.size()) {
|
||||
Way w = new Way(-1000);
|
||||
w.addNode(prevNode);
|
||||
int tilex = px31 >> (31 - z);
|
||||
int tiley = py31 >> (31 - z);
|
||||
boolean sameTile = true;
|
||||
wayConstruct : while(sameTile && i<ns.size()) {
|
||||
Node next = ns.get(i);
|
||||
int ntilex = (int) MapUtils.getTileNumberX(z, next.getLongitude());
|
||||
int ntiley = (int) MapUtils.getTileNumberY(z, next.getLatitude());
|
||||
if(ntilex == tilex && tiley == ntiley) {
|
||||
sameTile = true;
|
||||
w.addNode(next);
|
||||
prevNode = next;
|
||||
px31 = MapUtils.get31TileNumberX(prevNode.getLongitude());
|
||||
py31 = MapUtils.get31TileNumberY(prevNode.getLatitude());
|
||||
i++;
|
||||
} else {
|
||||
int nx31 = MapUtils.get31TileNumberX(next.getLongitude());
|
||||
int ny31 = MapUtils.get31TileNumberY(next.getLatitude());
|
||||
// increase boundaries to drop into another tile
|
||||
int leftX = (tilex << (31 - z)) - 1;
|
||||
int rightX = (tilex + 1) << (31 - z);
|
||||
if( rightX < 0 ){
|
||||
rightX = Integer.MAX_VALUE;
|
||||
}
|
||||
int topY = (tiley << (31 - z)) - 1;
|
||||
int bottomY = (tiley + 1) << (31 - z);
|
||||
if( bottomY < 0 ){
|
||||
bottomY = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
long inter = MapAlgorithms.calculateIntersection(px31, py31, nx31, ny31, leftX, rightX, bottomY, topY);
|
||||
int cy31 = (int) inter;
|
||||
int cx31 = (int) (inter >> 32l);
|
||||
prevNode = new Node(MapUtils.get31LatitudeY(cy31), MapUtils.get31LongitudeX(cx31), -1000);
|
||||
px31 = cx31;
|
||||
py31 = cy31;
|
||||
w.addNode(prevNode);
|
||||
break wayConstruct;
|
||||
}
|
||||
}
|
||||
SimplisticQuadTree quad = quadTree.getOrCreateSubTree(tilex, tiley, z);
|
||||
if (quad == null) {
|
||||
if (logMapDataWarn != null) {
|
||||
logMapDataWarn.error("Tile " + tilex + " / " + tiley + " at " + z + " can not be found");
|
||||
} else {
|
||||
System.err.println("Tile " + tilex + " / " + tiley + " at " + z + " can not be found");
|
||||
}
|
||||
}
|
||||
quad.addCoastline(w);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////// OLD CODE ///////////////////////////////
|
||||
|
||||
public void processCoastlineOld(Way e) {
|
||||
WayChain chain = null;
|
||||
if(coastlinesEndPoint.contains(e.getFirstNodeId())){
|
||||
chain = coastlinesEndPoint.remove(e.getFirstNodeId());
|
||||
|
@ -402,8 +576,6 @@ public class CoastlineProcessor {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void processCoastlines() {
|
||||
System.out.println("Way chains " + coastlinesStartPoint.size());
|
||||
final List<CoastlineTile> processed = new ArrayList<CoastlineTile>();
|
||||
|
@ -503,61 +675,6 @@ public class CoastlineProcessor {
|
|||
map.put(EntityId.valueOf(w), new EntityInfo("1"));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
CoastlineProcessor proc = new CoastlineProcessor();
|
||||
BinaryMapIndexWriter writer = new BinaryMapIndexWriter(new RandomAccessFile(
|
||||
"/home/victor/projects/OsmAnd/data/osm-gen/coastline.obf", "rw"));
|
||||
proc.writeCoastlinesFile( writer,
|
||||
proc.calculateTilesQuadTree());
|
||||
writer.close();
|
||||
}
|
||||
|
||||
private void writeCoastlinesFile(BinaryMapIndexWriter writer, SimplisticQuadTree simplisticQuadTree) throws IOException {
|
||||
writer.startWriteMapIndex("Coastline");
|
||||
// write map encoding rules
|
||||
writer.writeMapEncodingRules(MapRenderingTypes.getDefault().getEncodingRuleTypes());
|
||||
|
||||
// write map levels and map index
|
||||
writer.startWriteMapLevelIndex(1, 12, 0, 0, 1 << 31, 1 << 31);
|
||||
|
||||
Map<SimplisticQuadTree, BinaryFileReference> refs = new LinkedHashMap<CoastlineProcessor.SimplisticQuadTree, BinaryFileReference>();
|
||||
writeBinaryMapTree(simplisticQuadTree, writer, refs);
|
||||
|
||||
// without data blocks
|
||||
// writeBinaryMapBlock(root, rootBounds, rtree, writer, selectData, treeHeader, new LinkedHashMap<String, Integer>(),
|
||||
// new LinkedHashMap<MapRenderingTypes.MapRulType, String>());
|
||||
|
||||
writer.endWriteMapLevelIndex();
|
||||
|
||||
writer.endWriteMapIndex();
|
||||
writer.flush();
|
||||
|
||||
}
|
||||
|
||||
private void writeBinaryMapTree(SimplisticQuadTree quadTree, BinaryMapIndexWriter writer,
|
||||
Map<SimplisticQuadTree, BinaryFileReference> refs) throws IOException {
|
||||
int xL = (quadTree.x) << (31 - quadTree.zoom);
|
||||
int xR = (quadTree.x + 1) << (31 - quadTree.zoom) - 1;
|
||||
int yT = (quadTree.y) << (31 - quadTree.zoom);
|
||||
int yB = (quadTree.y + 1) << (31 - quadTree.zoom) - 1;
|
||||
long fp = writer.getFilePointer();
|
||||
BinaryFileReference ref = writer.startMapTreeElement(xL, xR, yT, yB, false,
|
||||
quadTree.ocean, quadTree.land);
|
||||
if (ref != null) {
|
||||
refs.put(quadTree, ref);
|
||||
}
|
||||
|
||||
if (quadTree.areChildrenDefined()) {
|
||||
SimplisticQuadTree[] allChildren = quadTree.getAllChildren();
|
||||
|
||||
for (SimplisticQuadTree ch : allChildren) {
|
||||
writeBinaryMapTree(ch, writer, refs);
|
||||
}
|
||||
}
|
||||
writer.endWriteMapTreeElement();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -637,11 +637,11 @@ public class IndexCreator {
|
|||
creator.setZoomWaySmothness(2);
|
||||
MapRenderingTypes rt = MapRenderingTypes.getDefault();// new MapRenderingTypes("/home/victor/projects/OsmAnd/data/testdata/roads_rendering_types.xml");
|
||||
MapZooms zooms = MapZooms.getDefault(); // MapZooms.parseZooms("15-");
|
||||
// creator.setNodesDBFile(new File("/home/victor/projects/OsmAnd/data/osm-gen/nodes.tmp.odb"));
|
||||
creator.setNodesDBFile(new File("/home/victor/projects/OsmAnd/data/osm-gen/nodes.tmp.odb"));
|
||||
// creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/luxembourg.osm.pbf"),
|
||||
// creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/cuba2.osm.bz2"),
|
||||
// new ConsoleProgressImplementation(1), null, zooms, rt, log);
|
||||
zooms = MapZooms.parseZooms("1-5;6-9;10-12");
|
||||
zooms = MapZooms.parseZooms("1-5;6-14");
|
||||
creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/basemap/10m_coastline_out.osm"),
|
||||
new ConsoleProgressImplementation(1), null, zooms, rt, log);
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
private static final int MAP_LEVELS_MAX = 1 << MAP_LEVELS_POWER;
|
||||
private MapRenderingTypes renderingTypes;
|
||||
private MapZooms mapZooms;
|
||||
|
||||
private boolean COASTLINE_PROCESS = true;
|
||||
|
||||
Map<Long, TIntArrayList> multiPolygonsWays = new LinkedHashMap<Long, TIntArrayList>();
|
||||
|
||||
|
@ -74,7 +76,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
TIntArrayList addtypeUse = new TIntArrayList(8);
|
||||
List<Long> restrictionsUse = new ArrayList<Long>(8);
|
||||
|
||||
private CoastlineProcessor coastlineProcessor = new CoastlineProcessor();
|
||||
private CoastlineProcessor coastlineProcessor;
|
||||
private PreparedStatement mapBinaryStat;
|
||||
private PreparedStatement mapLowLevelBinaryStat;
|
||||
private int lowLevelWays = -1;
|
||||
|
@ -91,6 +93,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
this.mapZooms = mapZooms;
|
||||
this.zoomWaySmothness = zoomWaySmothness;
|
||||
this.renderingTypes = renderingTypes;
|
||||
this.coastlineProcessor = new CoastlineProcessor(logMapDataWarn, mapZooms, renderingTypes, zoomWaySmothness);
|
||||
lowLevelWays = -1;
|
||||
}
|
||||
|
||||
|
@ -502,10 +505,10 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
if (e instanceof Way || e instanceof Node) {
|
||||
// manipulate what kind of way to load
|
||||
ctx.loadEntityData(e);
|
||||
// if(e instanceof Way && "coastline".equals(e.getTag(OSMTagKey.NATURAL))){
|
||||
// coastlineProcessor.processCoastline((Way) e);
|
||||
// return;
|
||||
// }
|
||||
if (e instanceof Way && "coastline".equals(e.getTag(OSMTagKey.NATURAL)) && COASTLINE_PROCESS) {
|
||||
coastlineProcessor.processCoastline((Way) e);
|
||||
return;
|
||||
}
|
||||
for (int level = 0; level < mapZooms.size(); level++) {
|
||||
boolean area = renderingTypes.encodeEntityWithType(e, mapZooms.getLevel(level).getMaxZoom(), typeUse, addtypeUse, namesUse,
|
||||
tempNameUse);
|
||||
|
@ -552,10 +555,12 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
|
||||
|
||||
public void writeBinaryMapIndex(BinaryMapIndexWriter writer, String regionName) throws IOException, SQLException {
|
||||
// coastlineProcessor.processCoastlines();
|
||||
|
||||
closePreparedStatements(mapBinaryStat, mapLowLevelBinaryStat);
|
||||
mapConnection.commit();
|
||||
if(COASTLINE_PROCESS) {
|
||||
coastlineProcessor.writeCoastlinesFile(writer);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
writer.startWriteMapIndex(regionName);
|
||||
// write map encoding rules
|
||||
|
|
|
@ -122,10 +122,12 @@ public class MapRenderingTypes {
|
|||
}
|
||||
|
||||
public MapRulType getNameRuleType() {
|
||||
getEncodingRuleTypes();
|
||||
return nameRuleType;
|
||||
}
|
||||
|
||||
public MapRulType getCoastlineRuleType() {
|
||||
getEncodingRuleTypes();
|
||||
return coastlineRuleType;
|
||||
}
|
||||
|
||||
|
@ -156,7 +158,7 @@ public class MapRenderingTypes {
|
|||
if(rType.targetTagValue != null) {
|
||||
rType = rType.targetTagValue;
|
||||
}
|
||||
rType.freq++;
|
||||
rType.updateFreq();
|
||||
if (rType.names != null) {
|
||||
for (int i = 0; i < rType.names.length; i++) {
|
||||
tempList.add(rType.names[i]);
|
||||
|
@ -658,25 +660,5 @@ public class MapRenderingTypes {
|
|||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// MapRenderingTypes def = MapRenderingTypes.getDefault();
|
||||
// long ts = System.currentTimeMillis();
|
||||
// Map<String, Map<String, AmenityType>> amenityMap = def.getAmenityTagValToTypeMap();
|
||||
// for(String s : amenityMap.keySet()){
|
||||
// System.out.println(s + " - " + amenityMap.get(s));
|
||||
// }
|
||||
// Map<AmenityType, Map<String, String>> amenityType = def.getAmenityTypeNameToTagVal();
|
||||
// for(AmenityType s : amenityType.keySet()){
|
||||
// Map<String, String> map = amenityType.get(s);
|
||||
// for(String t : map.keySet()){
|
||||
// System.out.println(s + " - " + t + " " + map.get(t));
|
||||
// }
|
||||
// }
|
||||
// System.out.println(def.getAmenityNameToType());
|
||||
|
||||
|
||||
// def.initAmenityMap();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -178,6 +178,11 @@ public class MapUtils {
|
|||
latitude -= 180;
|
||||
}
|
||||
}
|
||||
if(latitude < -85.0511) {
|
||||
return -85.0511;
|
||||
} else if(latitude > 85.0511){
|
||||
return 85.0511;
|
||||
}
|
||||
return latitude;
|
||||
}
|
||||
|
||||
|
|
|
@ -438,7 +438,7 @@ public class MapRenderRepositories {
|
|||
RenderingRuleSearchRequest renderingReq = new RenderingRuleSearchRequest(storage);
|
||||
renderingReq.setBooleanFilter(renderingReq.ALL.R_NIGHT_MODE, nightMode);
|
||||
for (RenderingRuleProperty customProp : storage.PROPS.getCustomRules()) {
|
||||
CommonPreference<String> settings = app.getSettings().getCustomRenderProperty(customProp.getAttrName());
|
||||
CommonPreference<String> settings = OsmandApplication.getSettings().getCustomRenderProperty(customProp.getAttrName());
|
||||
String res = settings.get();
|
||||
if (!Algoritms.isEmpty(res)) {
|
||||
if (customProp.isString()) {
|
||||
|
@ -913,7 +913,7 @@ public class MapRenderRepositories {
|
|||
boolean lineEnded = false;
|
||||
if (pinside) {
|
||||
if (!inside) {
|
||||
long is = calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY);
|
||||
long is = MapAlgorithms.calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY);
|
||||
if (is == -1) {
|
||||
// it is an error (!)
|
||||
is = (((long) px) << 32) | ((long) py);
|
||||
|
@ -924,7 +924,7 @@ public class MapRenderRepositories {
|
|||
coordinates.add((((long) x) << 32) | ((long) y));
|
||||
}
|
||||
} else {
|
||||
long is = calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY);
|
||||
long is = MapAlgorithms.calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY);
|
||||
if (inside) {
|
||||
// assert is != -1;
|
||||
coordinates.add(is);
|
||||
|
@ -933,7 +933,7 @@ public class MapRenderRepositories {
|
|||
int bx = (int) (is >> 32);
|
||||
int by = (int) (is & 0xffffffff);
|
||||
coordinates.add(is);
|
||||
is = calculateIntersection(x, y, bx, by, leftX, rightX, bottomY, topY);
|
||||
is = MapAlgorithms.calculateIntersection(x, y, bx, by, leftX, rightX, bottomY, topY);
|
||||
coordinates.add(is);
|
||||
lineEnded = true;
|
||||
}
|
||||
|
@ -942,90 +942,7 @@ public class MapRenderRepositories {
|
|||
return lineEnded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return -1 if there is no instersection or x<<32 | y
|
||||
*/
|
||||
private long calculateIntersection(int x, int y, int px, int py, int leftX, int rightX, int bottomY, int topY) {
|
||||
int by = -1;
|
||||
int bx = -1;
|
||||
// firstly try to search if the line goes in
|
||||
if (py < topY && y >= topY) {
|
||||
int tx = (int) (px + ((double) (x - px) * (topY - py)) / (y - py));
|
||||
if (leftX <= tx && tx <= rightX) {
|
||||
bx = tx;
|
||||
by = topY;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
}
|
||||
if (py > bottomY && y <= bottomY) {
|
||||
int tx = (int) (px + ((double) (x - px) * (py - bottomY)) / (py - y));
|
||||
if (leftX <= tx && tx <= rightX) {
|
||||
bx = tx;
|
||||
by = bottomY;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
}
|
||||
if (px < leftX && x >= leftX) {
|
||||
int ty = (int) (py + ((double) (y - py) * (leftX - px)) / (x - px));
|
||||
if (ty >= topY && ty <= bottomY) {
|
||||
by = ty;
|
||||
bx = leftX;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
|
||||
}
|
||||
if (px > rightX && x <= rightX) {
|
||||
int ty = (int) (py + ((double) (y - py) * (px - rightX)) / (px - x));
|
||||
if (ty >= topY && ty <= bottomY) {
|
||||
by = ty;
|
||||
bx = rightX;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// try to search if point goes out
|
||||
if (py > topY && y <= topY) {
|
||||
int tx = (int) (px + ((double) (x - px) * (topY - py)) / (y - py));
|
||||
if (leftX <= tx && tx <= rightX) {
|
||||
bx = tx;
|
||||
by = topY;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
}
|
||||
if (py < bottomY && y >= bottomY) {
|
||||
int tx = (int) (px + ((double) (x - px) * (py - bottomY)) / (py - y));
|
||||
if (leftX <= tx && tx <= rightX) {
|
||||
bx = tx;
|
||||
by = bottomY;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
}
|
||||
if (px > leftX && x <= leftX) {
|
||||
int ty = (int) (py + ((double) (y - py) * (leftX - px)) / (x - px));
|
||||
if (ty >= topY && ty <= bottomY) {
|
||||
by = ty;
|
||||
bx = leftX;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
|
||||
}
|
||||
if (px < rightX && x >= rightX) {
|
||||
int ty = (int) (py + ((double) (y - py) * (px - rightX)) / (px - x));
|
||||
if (ty >= topY && ty <= bottomY) {
|
||||
by = ty;
|
||||
bx = rightX;
|
||||
return (((long) bx) << 32) | ((long) by);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (px == rightX || px == leftX || py == topY || py == bottomY) {
|
||||
bx = px;
|
||||
by = py;
|
||||
}
|
||||
return -1l;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue