2013-04-18 23:35:02 +02:00
|
|
|
package net.osmand.binary;
|
|
|
|
|
2017-08-19 11:18:49 +02:00
|
|
|
import gnu.trove.list.array.TIntArrayList;
|
|
|
|
import gnu.trove.map.hash.TIntObjectHashMap;
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
2015-12-09 19:37:26 +01:00
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
import java.util.Map;
|
|
|
|
|
2013-04-18 23:35:02 +02:00
|
|
|
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
|
2017-08-19 12:45:06 +02:00
|
|
|
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
2013-04-18 23:35:02 +02:00
|
|
|
import net.osmand.render.RenderingRulesStorage;
|
2017-08-23 16:28:18 +02:00
|
|
|
import net.osmand.util.Algorithms;
|
2013-04-18 23:35:02 +02:00
|
|
|
|
|
|
|
public class BinaryMapDataObject {
|
|
|
|
protected int[] coordinates = null;
|
|
|
|
protected int[][] polygonInnerCoordinates = null;
|
|
|
|
protected boolean area = false;
|
|
|
|
protected int[] types = null;
|
|
|
|
protected int[] additionalTypes = null;
|
|
|
|
protected int objectType = RenderingRulesStorage.POINT_RULES;
|
|
|
|
|
|
|
|
protected TIntObjectHashMap<String> objectNames = null;
|
2014-06-26 01:14:30 +02:00
|
|
|
protected TIntArrayList namesOrder = null;
|
2013-04-18 23:35:02 +02:00
|
|
|
protected long id = 0;
|
|
|
|
|
|
|
|
protected MapIndex mapIndex = null;
|
|
|
|
|
|
|
|
|
|
|
|
public BinaryMapDataObject(){
|
|
|
|
}
|
|
|
|
|
2017-08-19 12:45:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
public BinaryMapDataObject(long id, int[] coordinates, int[][] polygonInnerCoordinates, int objectType, boolean area,
|
|
|
|
int[] types, int[] additionalTypes){
|
2013-04-18 23:35:02 +02:00
|
|
|
this.polygonInnerCoordinates = polygonInnerCoordinates;
|
|
|
|
this.coordinates = coordinates;
|
2017-08-19 12:45:06 +02:00
|
|
|
this.additionalTypes = additionalTypes;
|
2013-04-18 23:35:02 +02:00
|
|
|
this.types = types;
|
|
|
|
this.id = id;
|
2017-08-19 12:45:06 +02:00
|
|
|
this.objectType = objectType;
|
|
|
|
this.area = area;
|
2013-04-18 23:35:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected void setCoordinates(int[] coordinates) {
|
|
|
|
this.coordinates = coordinates;
|
|
|
|
}
|
|
|
|
|
2014-03-01 12:30:25 +01:00
|
|
|
|
2013-04-18 23:35:02 +02:00
|
|
|
public String getName(){
|
|
|
|
if(objectNames == null){
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
String name = objectNames.get(mapIndex.nameEncodingType);
|
|
|
|
if(name == null){
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public TIntObjectHashMap<String> getObjectNames() {
|
|
|
|
return objectNames;
|
|
|
|
}
|
|
|
|
|
2015-12-09 19:37:26 +01:00
|
|
|
public Map<Integer, String> getOrderedObjectNames() {
|
2017-08-23 14:55:27 +02:00
|
|
|
if (namesOrder == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2015-12-09 19:37:26 +01:00
|
|
|
LinkedHashMap<Integer, String> lm = new LinkedHashMap<Integer, String> ();
|
|
|
|
for (int i = 0; i < namesOrder.size(); i++) {
|
|
|
|
int nm = namesOrder.get(i);
|
|
|
|
lm.put(nm, objectNames.get(nm));
|
|
|
|
}
|
|
|
|
return lm;
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:35:02 +02:00
|
|
|
public void putObjectName(int type, String name){
|
|
|
|
if(objectNames == null){
|
|
|
|
objectNames = new TIntObjectHashMap<String>();
|
2014-06-26 01:14:30 +02:00
|
|
|
namesOrder = new TIntArrayList();
|
2013-04-18 23:35:02 +02:00
|
|
|
}
|
|
|
|
objectNames.put(type, name);
|
2014-06-26 01:14:30 +02:00
|
|
|
namesOrder.add(type);
|
2013-04-18 23:35:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public int[][] getPolygonInnerCoordinates() {
|
|
|
|
return polygonInnerCoordinates;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int[] getTypes(){
|
|
|
|
return types;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsType(int cachedType) {
|
|
|
|
if(cachedType != -1) {
|
|
|
|
for(int i=0; i<types.length; i++){
|
|
|
|
if(types[i] == cachedType) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsAdditionalType(int cachedType) {
|
|
|
|
if (cachedType != -1) {
|
|
|
|
for (int i = 0; i < additionalTypes.length; i++) {
|
|
|
|
if (additionalTypes[i] == cachedType) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getNameByType(int type) {
|
|
|
|
if(type != -1 && objectNames != null) {
|
|
|
|
return objectNames.get(type);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int[] getAdditionalTypes() {
|
|
|
|
return additionalTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isArea() {
|
|
|
|
return area;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isCycle(){
|
|
|
|
if(coordinates == null || coordinates.length < 2) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return coordinates[0] == coordinates[coordinates.length - 2] &&
|
|
|
|
coordinates[1] == coordinates[coordinates.length - 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setArea(boolean area) {
|
|
|
|
this.area = area;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long getId() {
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void setId(long id) {
|
|
|
|
this.id = id;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void setTypes(int[] types) {
|
|
|
|
this.types = types;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public int getSimpleLayer(){
|
|
|
|
if(mapIndex != null) {
|
|
|
|
for (int i = 0; i < additionalTypes.length; i++) {
|
|
|
|
if (mapIndex.positiveLayers.contains(additionalTypes[i])) {
|
|
|
|
return 1;
|
|
|
|
} else if (mapIndex.negativeLayers.contains(additionalTypes[i])) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-06-26 01:14:30 +02:00
|
|
|
public TIntArrayList getNamesOrder() {
|
|
|
|
return namesOrder;
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:35:02 +02:00
|
|
|
public MapIndex getMapIndex() {
|
|
|
|
return mapIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setMapIndex(MapIndex mapIndex) {
|
|
|
|
this.mapIndex = mapIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getPointsLength(){
|
|
|
|
if(coordinates == null){
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return coordinates.length / 2;
|
|
|
|
}
|
|
|
|
public int getPoint31YTile(int ind) {
|
|
|
|
return coordinates[2 * ind + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getPoint31XTile(int ind) {
|
|
|
|
return coordinates[2 * ind];
|
|
|
|
}
|
|
|
|
|
2017-08-19 12:45:06 +02:00
|
|
|
|
2017-08-19 11:18:49 +02:00
|
|
|
public boolean compareBinary(BinaryMapDataObject thatObj) {
|
2017-08-19 12:45:06 +02:00
|
|
|
if(this.objectType == thatObj.objectType
|
|
|
|
&& this.id == thatObj.id
|
2017-08-19 11:18:49 +02:00
|
|
|
&& this.area == thatObj.area
|
2017-08-19 12:45:06 +02:00
|
|
|
&& Arrays.equals(this.coordinates, thatObj.coordinates) ) {
|
2017-08-29 20:53:01 +02:00
|
|
|
if(mapIndex == null) {
|
|
|
|
throw new IllegalStateException("Illegal binary object: " + id);
|
|
|
|
}
|
|
|
|
if(thatObj.mapIndex == null) {
|
|
|
|
throw new IllegalStateException("Illegal binary object: " + thatObj.id);
|
|
|
|
}
|
2017-09-02 22:24:49 +02:00
|
|
|
|
2017-08-19 12:45:06 +02:00
|
|
|
boolean equals = true;
|
2017-09-02 22:24:49 +02:00
|
|
|
if(equals) {
|
|
|
|
if(polygonInnerCoordinates == null || thatObj.polygonInnerCoordinates == null) {
|
|
|
|
equals = polygonInnerCoordinates == thatObj.polygonInnerCoordinates;
|
|
|
|
} else if(polygonInnerCoordinates.length != thatObj.polygonInnerCoordinates.length){
|
|
|
|
equals = false;
|
|
|
|
} else {
|
|
|
|
for(int i = 0; i < polygonInnerCoordinates.length && equals; i++) {
|
|
|
|
if(polygonInnerCoordinates[i] == null || thatObj.polygonInnerCoordinates[i] == null) {
|
|
|
|
equals = polygonInnerCoordinates[i] == thatObj.polygonInnerCoordinates[i];
|
|
|
|
} else if(polygonInnerCoordinates[i].length != thatObj.polygonInnerCoordinates[i].length){
|
|
|
|
equals = false;
|
|
|
|
} else {
|
|
|
|
equals = Arrays.equals(polygonInnerCoordinates[i], thatObj.polygonInnerCoordinates[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-19 12:45:06 +02:00
|
|
|
if(equals) {
|
|
|
|
if(types == null || thatObj.types == null) {
|
|
|
|
equals = types == thatObj.types;
|
|
|
|
} else if(types.length != thatObj.types.length){
|
|
|
|
equals = false;
|
|
|
|
} else {
|
|
|
|
for(int i = 0; i < types.length && equals; i++) {
|
|
|
|
TagValuePair o = mapIndex.decodeType(types[i]);
|
|
|
|
TagValuePair s = thatObj.mapIndex.decodeType(thatObj.types[i]);
|
2017-09-02 22:24:49 +02:00
|
|
|
equals = o.equals(s) && equals;
|
2017-08-19 12:45:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(equals) {
|
|
|
|
if(additionalTypes == null || thatObj.additionalTypes == null) {
|
|
|
|
equals = additionalTypes == thatObj.additionalTypes;
|
|
|
|
} else if(additionalTypes.length != thatObj.additionalTypes.length){
|
|
|
|
equals = false;
|
|
|
|
} else {
|
|
|
|
for(int i = 0; i < additionalTypes.length && equals; i++) {
|
|
|
|
TagValuePair o = mapIndex.decodeType(additionalTypes[i]);
|
|
|
|
TagValuePair s = thatObj.mapIndex.decodeType(thatObj.additionalTypes[i]);
|
|
|
|
equals = o.equals(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(equals) {
|
|
|
|
if(namesOrder == null || thatObj.namesOrder == null) {
|
|
|
|
equals = namesOrder == thatObj.namesOrder;
|
|
|
|
} else if(namesOrder.size() != thatObj.namesOrder.size()){
|
|
|
|
equals = false;
|
|
|
|
} else {
|
|
|
|
for(int i = 0; i < namesOrder.size() && equals; i++) {
|
|
|
|
TagValuePair o = mapIndex.decodeType(namesOrder.get(i));
|
|
|
|
TagValuePair s = thatObj.mapIndex.decodeType(thatObj.namesOrder.get(i));
|
|
|
|
equals = o.equals(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(equals) {
|
2017-08-23 14:55:27 +02:00
|
|
|
// here we know that name indexes are equal & it is enough to check the value sets
|
2017-08-19 12:45:06 +02:00
|
|
|
if(objectNames == null || thatObj.objectNames == null) {
|
|
|
|
equals = objectNames == thatObj.objectNames;
|
|
|
|
} else if(objectNames.size() != thatObj.objectNames.size()){
|
|
|
|
equals = false;
|
|
|
|
} else {
|
2017-08-23 16:28:18 +02:00
|
|
|
for(int i = 0; i < namesOrder.size() && equals; i++) {
|
|
|
|
String o = objectNames.get(namesOrder.get(i));
|
|
|
|
String s = thatObj.objectNames.get(thatObj.namesOrder.get(i));
|
|
|
|
equals = Algorithms.objectEquals(o, s);
|
|
|
|
}
|
2017-08-19 12:45:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return equals;
|
2017-08-19 11:18:49 +02:00
|
|
|
}
|
2017-08-19 12:45:06 +02:00
|
|
|
|
2017-08-19 11:18:49 +02:00
|
|
|
return false;
|
|
|
|
}
|
2017-08-19 12:45:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
public int[] getCoordinates() {
|
|
|
|
return coordinates;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public int getObjectType() {
|
|
|
|
return objectType;
|
|
|
|
}
|
2013-04-18 23:35:02 +02:00
|
|
|
}
|