use of net.osmand.binary.BinaryMapDataObject in project Osmand by osmandapp.
the class MapRenderRepositories method processCoastlines.
// / MULTI POLYGONS (coastline)
// returns true if coastlines were added!
private boolean processCoastlines(List<BinaryMapDataObject> coastLines, int leftX, int rightX, int bottomY, int topY, int zoom, boolean doNotAddIfIncompleted, boolean addDebugIncompleted, List<BinaryMapDataObject> result) {
List<TLongList> completedRings = new ArrayList<TLongList>();
List<TLongList> uncompletedRings = new ArrayList<TLongList>();
MapIndex mapIndex = null;
long dbId = 0;
for (BinaryMapDataObject o : coastLines) {
int len = o.getPointsLength();
if (len < 2) {
continue;
}
mapIndex = o.getMapIndex();
dbId = o.getId() >> 1;
TLongList coordinates = new TLongArrayList(o.getPointsLength() / 2);
int px = o.getPoint31XTile(0);
int py = o.getPoint31YTile(0);
int x = px;
int y = py;
boolean pinside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
if (pinside) {
coordinates.add(combine2Points(x, y));
}
for (int i = 1; i < len; i++) {
x = o.getPoint31XTile(i);
y = o.getPoint31YTile(i);
boolean inside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
boolean lineEnded = calculateLineCoordinates(inside, x, y, pinside, px, py, leftX, rightX, bottomY, topY, coordinates);
if (lineEnded) {
combineMultipolygonLine(completedRings, uncompletedRings, coordinates);
// create new line if it goes outside
coordinates = new TLongArrayList();
}
px = x;
py = y;
pinside = inside;
}
combineMultipolygonLine(completedRings, uncompletedRings, coordinates);
}
if (completedRings.size() == 0 && uncompletedRings.size() == 0) {
return false;
}
if (uncompletedRings.size() > 0) {
unifyIncompletedRings(uncompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom);
}
long mask = 0xffffffffL;
// draw uncompleted for debug purpose
for (int i = 0; i < uncompletedRings.size(); i++) {
TLongList ring = uncompletedRings.get(i);
int[] coordinates = new int[ring.size() * 2];
for (int j = 0; j < ring.size(); j++) {
coordinates[j * 2] = (int) (ring.get(j) >> 32);
coordinates[j * 2 + 1] = (int) (ring.get(j) & mask);
}
BinaryMapDataObject o = new BinaryMapDataObject(dbId, coordinates, new int[0][], RenderingRulesStorage.POLYGON_RULES, true, new int[] { mapIndex.coastlineBrokenEncodingType }, null);
o.setMapIndex(mapIndex);
result.add(o);
}
if (!doNotAddIfIncompleted && uncompletedRings.size() > 0) {
return false;
}
boolean clockwiseFound = false;
for (int i = 0; i < completedRings.size(); i++) {
TLongList ring = completedRings.get(i);
int[] coordinates = new int[ring.size() * 2];
for (int j = 0; j < ring.size(); j++) {
coordinates[j * 2] = (int) (ring.get(j) >> 32);
coordinates[j * 2 + 1] = (int) (ring.get(j) & mask);
}
boolean clockwise = MapAlgorithms.isClockwiseWay(ring);
clockwiseFound = clockwiseFound || clockwise;
BinaryMapDataObject o = new BinaryMapDataObject(dbId, coordinates, new int[0][], RenderingRulesStorage.POLYGON_RULES, true, new int[] { clockwise ? mapIndex.coastlineEncodingType : mapIndex.landEncodingType }, null);
o.setMapIndex(mapIndex);
o.setArea(true);
result.add(o);
}
if (!clockwiseFound && uncompletedRings.size() == 0) {
// add complete water tile
BinaryMapDataObject o = new BinaryMapDataObject(dbId, new int[] { leftX, topY, rightX, topY, rightX, bottomY, leftX, bottomY, leftX, topY }, new int[0][], RenderingRulesStorage.POLYGON_RULES, true, new int[] { mapIndex.coastlineEncodingType }, null);
o.setMapIndex(mapIndex);
// $NON-NLS-1$
log.info("!!! Isolated islands !!!");
result.add(o);
}
return true;
}
Aggregations