Fix double cloning issue of MapElement, use copy-constructor in GeometryBuffer and MapElement (#455)

This commit is contained in:
Gustl22 2017-12-19 00:30:06 +01:00 committed by Emux
parent 9a6da018a9
commit bc1dee49a4
No known key found for this signature in database
GPG Key ID: 89C6921D7AF2BDD0
3 changed files with 32 additions and 31 deletions

View File

@ -1,6 +1,7 @@
/* /*
* Copyright 2013 Hannes Janetzek * Copyright 2013 Hannes Janetzek
* Copyright 2016 Andrey Novikov * Copyright 2016 Andrey Novikov
* Copyright 2017 Gustl22
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@ -17,6 +18,8 @@
*/ */
package org.oscim.core; package org.oscim.core;
import java.util.Arrays;
/* TODO /* TODO
* - check indexPos < Short.Max * - check indexPos < Short.Max
* - should make internals private, maybe * - should make internals private, maybe
@ -128,6 +131,22 @@ public class GeometryBuffer {
this.pointLimit = points.length - 2; this.pointLimit = points.length - 2;
} }
/**
* @param buffer the buffer to copy
*/
public GeometryBuffer(GeometryBuffer buffer) {
int indexSize = 0;
while (indexSize < buffer.index.length && buffer.index[indexSize] != -1) {
indexSize++;
}
this.points = Arrays.copyOf(buffer.points, buffer.pointNextPos);
this.index = Arrays.copyOf(buffer.index, indexSize);
this.pointNextPos = buffer.pointNextPos;
this.indexCurrentPos = buffer.indexCurrentPos;
this.type = buffer.type;
}
/** /**
* @param out PointF to set coordinates to. * @param out PointF to set coordinates to.
* @return when out is null a temporary PointF is * @return when out is null a temporary PointF is

View File

@ -18,15 +18,13 @@
*/ */
package org.oscim.core; package org.oscim.core;
import java.util.Arrays;
/** /**
* The MapElement class is a reusable containter for a geometry * The MapElement class is a reusable container for a geometry
* with tags. * with tags.
* MapElement is created by TileDataSource(s) and passed to * MapElement is created by TileDataSource(s) and passed to
* MapTileLoader via ITileDataSink.process(). * MapTileLoader via ITileDataSink.process().
* This is just a buffer that belongs to TileDataSource, * This is just a buffer that belongs to TileDataSource,
* so dont keep a reference to it when passed as parameter. * so don't keep a reference to it when passed as parameter.
*/ */
public class MapElement extends GeometryBuffer { public class MapElement extends GeometryBuffer {
@ -51,6 +49,16 @@ public class MapElement extends GeometryBuffer {
super(points, index); super(points, index);
} }
/**
* @param element the map element to copy
*/
public MapElement(MapElement element) {
super(element);
this.tags.set(element.tags.asArray());
this.labelPosition = element.labelPosition;
this.setLayer(element.layer);
}
public void setLabelPosition(float x, float y) { public void setLabelPosition(float x, float y) {
labelPosition = new PointF(x, y); labelPosition = new PointF(x, y);
} }
@ -68,32 +76,6 @@ public class MapElement extends GeometryBuffer {
@Override @Override
public String toString() { public String toString() {
return tags.toString() + '\n' + super.toString() + '\n'; return tags.toString() + '\n' + super.toString() + '\n';
}
/**
* @return a deep copy of this MapElement
*/
public MapElement clone() {
int indexSize = this.indexCurrentPos + 1;
for (int i = 0; i < this.index.length; i++) {
if (this.index[i] == -1) {
indexSize = i;
break;
}
}
float[] copyPoints = Arrays.copyOf(this.points, this.pointNextPos);
int[] copyIndex = Arrays.copyOf(this.index, indexSize);
MapElement copy = new MapElement(copyPoints, copyIndex);
copy.tags.set(this.tags.asArray());
copy.pointNextPos = this.pointNextPos;
copy.labelPosition = this.labelPosition;
copy.setLayer(this.layer);
copy.indexCurrentPos = this.indexCurrentPos;
copy.type = this.type;
return copy;
} }
} }

View File

@ -109,7 +109,7 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook {
buildingElements = new ArrayList<>(); buildingElements = new ArrayList<>();
mBuildings.put(tile.hashCode(), buildingElements); mBuildings.put(tile.hashCode(), buildingElements);
} }
element = element.clone(); // Deep copy, because element will be cleared element = new MapElement(element); // Deep copy, because element will be cleared
buildingElements.add(new BuildingElement(element, extrusion, isBuildingPart)); buildingElements.add(new BuildingElement(element, extrusion, isBuildingPart));
return true; return true;
} }