Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS

 Conflicts:
	collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt
This commit is contained in:
squallzhjch
2023-04-24 15:36:25 +08:00
15 changed files with 466 additions and 97 deletions

View File

@@ -23,7 +23,10 @@ open class RenderEntity(): RealmObject() {
lateinit var table: String //要素表名
var code: Int = 0 // 要素编码
var geometry: String = ""
get() = field
get() {
wkt = GeometryTools.createGeometry(field)
return field
}
set(value) {
field = value
// 根据geometry自动计算当前要素的x-tile和y-tile
@@ -39,8 +42,8 @@ open class RenderEntity(): RealmObject() {
@Ignore
var wkt: Geometry? = null
var properties: RealmDictionary<String?> = RealmDictionary()
val tileX: RealmSet<Int> = RealmSet() // x方向的tile编码
val tileY: RealmSet<Int> = RealmSet() // y方向的tile编码
var tileX: RealmSet<Int> = RealmSet() // x方向的tile编码
var tileY: RealmSet<Int> = RealmSet() // y方向的tile编码
constructor(name: String, properties: RealmDictionary<String?>): this() {
this.name = name

View File

@@ -16,6 +16,7 @@ import com.navinfo.collect.library.map.cluster.ClusterMarkerRenderer
import com.navinfo.collect.library.map.layers.MyItemizedLayer
import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource
import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource
import com.navinfo.collect.library.map.source.OMDBTileSource
import com.navinfo.collect.library.system.Constant
import com.navinfo.collect.library.utils.GeometryTools
import io.realm.Realm
@@ -40,6 +41,7 @@ import org.oscim.layers.tile.buildings.BuildingLayer
import org.oscim.layers.tile.vector.VectorTileLayer
import org.oscim.layers.tile.vector.labeling.LabelLayer
import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook
import org.oscim.map.Map
import org.oscim.map.Map.UpdateListener
import org.oscim.tiling.source.OkHttpEngine.OkHttpFactory
import org.oscim.tiling.source.mapfile.MapFileTileSource
@@ -69,6 +71,15 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
*/
private lateinit var labelNiLocationLayer: LabelLayer
/**
* 显示待测评OMDB数据的图层
* */
private lateinit var omdbVectorTileLayer: VectorTileLayer
private lateinit var omdbLabelLayer: LabelLayer
/**
* 文字大小
*/
private val NUM_13 = 13
init {
initMap()
@@ -81,6 +92,8 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
loadBaseMap()
initOMDBVectorTileLayer()
mapLifeNiLocationTileSource = MapLifeNiLocationTileSource(mContext, mTracePath)
vectorNiLocationTileLayer = VectorTileLayer(mMapView.vtmMap, mapLifeNiLocationTileSource)
@@ -105,6 +118,17 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tr
}
private fun initOMDBVectorTileLayer() {
val omdbTileSource: OMDBTileSource = OMDBTileSource()
omdbVectorTileLayer = VectorTileLayer(mMapView.vtmMap, omdbTileSource)
omdbLabelLayer = LabelLayer(mMapView.vtmMap, omdbVectorTileLayer, LabelTileLoaderHook(), Constant.OMDB_MIN_ZOOM)
if(omdbVectorTileLayer!=null){
addLayer(omdbVectorTileLayer,NIMapView.LAYER_GROUPS.VECTOR_TILE)
}
if(omdbLabelLayer!=null){
addLayer(omdbLabelLayer, NIMapView.LAYER_GROUPS.VECTOR_TILE)
}
}
/**
* 切换基础底图样式

View File

@@ -0,0 +1,190 @@
package com.navinfo.collect.library.map.source;
import static org.oscim.core.MercatorProjection.latitudeToY;
import static org.oscim.core.MercatorProjection.longitudeToX;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity;
import com.navinfo.collect.library.data.entity.RenderEntity;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKBReader;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.source.mvt.TileDecoder;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
public class OMDBDataDecoder extends TileDecoder {
private final String mLocale;
private static final float REF_TILE_SIZE = 4096.0f;
private final GeometryFactory mGeomFactory;
private final MapElement mMapElement;
private ITileDataSink mTileDataSink;
private double mTileY, mTileX, mTileScale;
public OMDBDataDecoder() {
super();
mLocale = "";
mGeomFactory = new GeometryFactory();
mMapElement = new MapElement();
mMapElement.layer = 5;
}
@Override
public boolean decode(Tile tile, ITileDataSink sink, InputStream is) throws IOException {
mTileDataSink = sink;
mTileScale = 1 << tile.zoomLevel;
mTileX = tile.tileX / mTileScale;
mTileY = tile.tileY / mTileScale;
mTileScale *= Tile.SIZE;
return true;
}
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean decode(Tile tile, ITileDataSink sink, List<RenderEntity> listResult) {
mTileDataSink = sink;
mTileScale = 1 << tile.zoomLevel;
mTileX = tile.tileX / mTileScale;
mTileY = tile.tileY / mTileScale;
mTileScale *= Tile.SIZE;
listResult.stream().iterator().forEachRemaining(new Consumer<RenderEntity>() {
@Override
public void accept(RenderEntity renderEntity) {
Log.d("RealmDBTileDataSource", renderEntity.getGeometry());
Map<String, Object> properties= new HashMap<>(renderEntity.getProperties().size());
properties.putAll(renderEntity.getProperties());
parseGeometry(renderEntity.getTable(), renderEntity.getWkt(), properties);
}
});
return true;
}
public void parseGeometry(String layerName, Geometry geometry, Map<String, Object> tags) {
mMapElement.clear();
mMapElement.tags.clear();
parseTags(tags, layerName);
if (mMapElement.tags.size() == 0) {
return;
}
boolean err = false;
if (geometry instanceof Point) {
mMapElement.startPoints();
processCoordinateArray(geometry.getCoordinates(), false);
} else if (geometry instanceof MultiPoint) {
MultiPoint multiPoint = (MultiPoint) geometry;
for (int i = 0; i < multiPoint.getNumGeometries(); i++) {
mMapElement.startPoints();
processCoordinateArray(multiPoint.getGeometryN(i).getCoordinates(), false);
}
} else if (geometry instanceof LineString) {
processLineString((LineString) geometry);
} else if (geometry instanceof MultiLineString) {
MultiLineString multiLineString = (MultiLineString) geometry;
for (int i = 0; i < multiLineString.getNumGeometries(); i++) {
processLineString((LineString) multiLineString.getGeometryN(i));
}
} else if (geometry instanceof Polygon) {
Polygon polygon = (Polygon) geometry;
processPolygon(polygon);
} else if (geometry instanceof MultiPolygon) {
MultiPolygon multiPolygon = (MultiPolygon) geometry;
for (int i = 0; i < multiPolygon.getNumGeometries(); i++) {
processPolygon((Polygon) multiPolygon.getGeometryN(i));
}
} else {
err = true;
}
if (!err) {
mTileDataSink.process(mMapElement);
}
}
private void processLineString(LineString lineString) {
mMapElement.startLine();
processCoordinateArray(lineString.getCoordinates(), false);
}
private void processPolygon(Polygon polygon) {
mMapElement.startPolygon();
processCoordinateArray(polygon.getExteriorRing().getCoordinates(), true);
for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
mMapElement.startHole();
processCoordinateArray(polygon.getInteriorRingN(i).getCoordinates(), true);
}
}
private void processCoordinateArray(Coordinate[] coordinates, boolean removeLast) {
int length = removeLast ? coordinates.length - 1 : coordinates.length;
for (int i = 0; i < length; i++) {
mMapElement.addPoint((float) ((longitudeToX(coordinates[i].x) - mTileX) * mTileScale),
(float) ((latitudeToY(coordinates[i].y) - mTileY) * mTileScale));
}
// int length = removeLast ? coordinates.length - 1 : coordinates.length;
// // 初始化3D数据类型
// float[] point3D = new float[coordinates.length*3];
// for (int i = 0; i < length; i++) {
// point3D[i*3] = (float) coordinates[i].x;
// point3D[(i*3)+1] = (float) coordinates[i].y;
// point3D[(i*3)+2] = (float) coordinates[i].z;
// }
// mMapElement.points = point3D;
// mMapElement.pointNextPos = mMapElement.points.length;
// mMapElement.type = GeometryBuffer.GeometryType.TRIS;
}
private void parseTags(Map<String, Object> map, String layerName) {
mMapElement.tags.add(new Tag("layer", layerName));
boolean hasName = false;
String fallbackName = null;
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
String val = (value instanceof String) ? (String) value : String.valueOf(value);
if (key.startsWith(Tag.KEY_NAME)) {
int len = key.length();
if (len == 4) {
fallbackName = val;
continue;
}
if (len < 7)
continue;
if (mLocale.equals(key.substring(5))) {
hasName = true;
mMapElement.tags.add(new Tag(Tag.KEY_NAME, val, false));
}
} else {
mMapElement.tags.add(new Tag(key, val));
}
}
if (!hasName && fallbackName != null)
mMapElement.tags.add(new Tag(Tag.KEY_NAME, fallbackName, false));
}
}

View File

@@ -0,0 +1,74 @@
package com.navinfo.collect.library.map.source;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.navinfo.collect.library.data.RealmUtils;
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity;
import com.navinfo.collect.library.data.entity.RenderEntity;
import com.navinfo.collect.library.system.Constant;
import org.oscim.layers.tile.MapTile;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.QueryResult;
import java.util.List;
import io.realm.Realm;
import io.realm.RealmQuery;
public class OMDBTileDataSource implements ITileDataSource {
private final ThreadLocal<OMDBDataDecoder> mThreadLocalDecoders = new ThreadLocal<OMDBDataDecoder>() {
@Override
protected OMDBDataDecoder initialValue() {
return new OMDBDataDecoder();
}
};
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void query(MapTile tile, ITileDataSink mapDataSink) {
// 获取tile对应的坐标范围
if (tile.zoomLevel>=Constant.OMDB_MIN_ZOOM&&tile.zoomLevel<=Constant.OVER_ZOOM) {
int m = Constant.OVER_ZOOM-tile.zoomLevel;
int xStart = (int)tile.tileX<<m;
int xEnd = (int)((tile.tileX+1)<<m);
int yStart = (int)tile.tileY<<m;
int yEnd = (int)((tile.tileY+1)<<m);
RealmQuery<RenderEntity> realmQuery = Realm.getDefaultInstance().where(RenderEntity.class)
.rawPredicate("tileX>="+xStart+" and tileX<="+xEnd+" and tileY>="+yStart+" and tileY<="+yEnd);
// // 筛选不显示的数据
// if (Constant.HAD_LAYER_INVISIABLE_ARRAY!=null&&Constant.HAD_LAYER_INVISIABLE_ARRAY.length>0) {
// realmQuery.beginGroup();
// for (String type: Constant.HAD_LAYER_INVISIABLE_ARRAY) {
// realmQuery.notEqualTo("name", type);
// }
// realmQuery.endGroup();
// }
List<RenderEntity> listResult = realmQuery/*.distinct("id")*/.findAll();
if (!listResult.isEmpty()) {
mThreadLocalDecoders.get().decode(tile, mapDataSink, listResult);
}
mapDataSink.completed(QueryResult.SUCCESS);
Log.d("RealmDBTileDataSource", "tile:"+tile.getBoundingBox().toString());
} else {
mapDataSink.completed(QueryResult.SUCCESS);
}
}
@Override
public void dispose() {
}
@Override
public void cancel() {
if (Realm.getDefaultInstance().isInTransaction()) {
Realm.getDefaultInstance().cancelTransaction();
}
}
}

View File

@@ -0,0 +1,25 @@
package com.navinfo.collect.library.map.source;
import com.navinfo.collect.library.system.Constant;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.OverzoomTileDataSource;
import org.oscim.tiling.TileSource;
public class OMDBTileSource extends TileSource {
@Override
public ITileDataSource getDataSource() {
return new OverzoomTileDataSource(new OMDBTileDataSource(), Constant.OVER_ZOOM);
}
@Override
public OpenResult open() {
return OpenResult.SUCCESS;
}
@Override
public void close() {
}
}

View File

@@ -31,5 +31,6 @@ public class Constant {
public static String[] HAD_LAYER_INVISIABLE_ARRAY;
public static final int OVER_ZOOM = 21;
public static final int MAX_ZOOM = 25;
public static final int OMDB_MIN_ZOOM = 18;
}