Add coastline processing

This commit is contained in:
Victor Shcherb 2012-04-03 22:22:15 +02:00
parent d5f233cacf
commit 453747920e
10 changed files with 343 additions and 257 deletions

View file

@ -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="&quot;C:\Users\tpd\Documents\Osmand maps&quot;"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="DataExtractionOSM"/>
</launchConfiguration>

View file

@ -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>

View file

@ -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;
}
}

View file

@ -311,9 +311,11 @@ public class BinaryMapIndexWriter {
checkPeekState(MAP_ROOT_LEVEL_INIT);
StringTable.Builder bs = OsmandOdb.StringTable.newBuilder();
if (stringTable != null) {
for (String s : stringTable.keySet()) {
bs.addS(s);
}
}
StringTable st = bs.build();
builder.setStringTable(st);
int size = st.getSerializedSize();
@ -424,6 +426,7 @@ public class BinaryMapIndexWriter {
}
mapDataBuf.clear();
if (names != null) {
for (Entry<MapRulType, String> s : names.entrySet()) {
writeRawVarint32(mapDataBuf, s.getKey().getTargetId());
Integer ls = stringTable.get(s.getValue());
@ -433,6 +436,7 @@ public class BinaryMapIndexWriter {
}
writeRawVarint32(mapDataBuf, ls);
}
}
STRING_TABLE_SIZE += mapDataBuf.size();
data.setStringNames(ByteString.copyFrom(mapDataBuf.toArray()));

View file

@ -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();
}
}

View file

@ -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);

View file

@ -61,6 +61,8 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
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

View file

@ -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();
}
}

View file

@ -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;
}

View file

@ -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;
}
}