创建工程
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
package com.navinfo.collect;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.PermissionChecker;
|
||||
|
||||
import com.baidu.ai.edge.core.base.Consts;
|
||||
|
||||
|
||||
/**
|
||||
* Created by linyiran on 6/16/22.
|
||||
*/
|
||||
public abstract class BaseActivity extends AppCompatActivity {
|
||||
private static final int REQUEST_PERMISSION = 1;
|
||||
|
||||
protected boolean allPermissionsGranted;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setLayout();
|
||||
requestPermission();
|
||||
onActivityCreated(savedInstanceState);
|
||||
}
|
||||
|
||||
protected abstract void setLayout();
|
||||
|
||||
protected abstract void onActivityCreated(Bundle savedInstanceState);
|
||||
|
||||
private void requestPermission() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
String[] permissions = new String[]{
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.INTERNET,
|
||||
Manifest.permission.ACCESS_NETWORK_STATE,
|
||||
Manifest.permission.READ_PHONE_STATE,
|
||||
Manifest.permission.CAMERA
|
||||
};
|
||||
allPermissionsGranted = true;
|
||||
for (String perm : permissions) {
|
||||
if ((PermissionChecker.checkSelfPermission(this, perm) != PermissionChecker.PERMISSION_GRANTED)) {
|
||||
allPermissionsGranted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allPermissionsGranted) {
|
||||
ActivityCompat.requestPermissions(BaseActivity.this, permissions, REQUEST_PERMISSION);
|
||||
} else {
|
||||
requestAllFilesAccess();
|
||||
}
|
||||
} else {
|
||||
allPermissionsGranted = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||
@NonNull int[] grantResults) {
|
||||
if (requestCode == REQUEST_PERMISSION) {
|
||||
allPermissionsGranted = true;
|
||||
for (int grantRes : grantResults) {
|
||||
if (grantRes != PackageManager.PERMISSION_GRANTED) {
|
||||
allPermissionsGranted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allPermissionsGranted) {
|
||||
requestAllFilesAccess();
|
||||
}
|
||||
}
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Android 11 跳转到设置获取SD卡根目录写入权限
|
||||
*/
|
||||
private void requestAllFilesAccess() {
|
||||
if (!Consts.AUTH_REQUIRE_SDCARD) {
|
||||
return;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
|
||||
allPermissionsGranted = false;
|
||||
|
||||
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(BaseActivity.this,
|
||||
androidx.appcompat.R.style.Theme_AppCompat_Light_Dialog_Alert);
|
||||
alertBuilder.setMessage("需授权访问SD卡文件");
|
||||
alertBuilder.setCancelable(false);
|
||||
alertBuilder.setPositiveButton("去设置", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
alertBuilder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
alertBuilder.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.navinfo.collect
|
||||
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.baidu.ai.edge.ui.view.model.BasePolygonResultModel
|
||||
import com.navinfo.collect.library.map.flutter.plugin.FlutterMapViewFactory
|
||||
import com.navinfo.collect.library.map.flutter.plugin.FlutterMapViewFlutterPlugin
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.cancel
|
||||
|
||||
abstract class FlutterBaseActivity : FlutterActivity(), CoroutineScope by MainScope() {
|
||||
lateinit var factory: FlutterMapViewFactory
|
||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
factory = FlutterMapViewFlutterPlugin.registerWith(flutterEngine, this);
|
||||
// FlutterNiMapCopyViewFlutterPlugin.registerWith(flutterEngine, this);
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == 0x10 && data != null) {
|
||||
val path = data.getStringExtra("photo_path")
|
||||
val list = data.getParcelableArrayListExtra<BasePolygonResultModel>("result_list")
|
||||
Log.e("jingo","OCR java 返回的数据:"+ path + list.toString());
|
||||
if (path != null && list != null) {
|
||||
factory.dataController.flutterDataCameraHandler.sendOcrResults(
|
||||
path,
|
||||
list as List<BasePolygonResultModel>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
//协程销毁
|
||||
cancel()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
package com.navinfo.collect.library.data
|
||||
|
||||
import android.graphics.Point
|
||||
import android.graphics.Rect
|
||||
import android.util.Log
|
||||
import android.view.WindowInsetsAnimation.Bounds
|
||||
import com.baidu.ai.edge.ui.view.model.BasePolygonResultModel
|
||||
import com.baidu.ai.edge.ui.view.model.OcrViewResultModel
|
||||
import com.navinfo.collect.library.data.entity.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.io.BufferedWriter
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.OutputStream
|
||||
import java.io.OutputStreamWriter
|
||||
|
||||
/**
|
||||
* 和flutter层进行数据传递时的数据格式转换
|
||||
*/
|
||||
class DataConversion {
|
||||
companion object {
|
||||
/**
|
||||
* 将数据转成map形式-传给flutter使用
|
||||
*/
|
||||
fun toElementMapList(list: List<Element>): List<Map<*, *>> {
|
||||
val newList = mutableListOf<Map<*, *>>()
|
||||
for (element in list) {
|
||||
newList.add(element.toMap())
|
||||
}
|
||||
return newList
|
||||
}
|
||||
|
||||
/**
|
||||
* json转数据图层自定义子表的所有字段对象列表
|
||||
* (现在用于从数据库中提取数据图层自定义表所有字段信息时,主要用于原生层)
|
||||
*/
|
||||
fun jsonToLayerItemsList(json: String): List<CustomLayerItem> {
|
||||
val list = mutableListOf<CustomLayerItem>()
|
||||
try {
|
||||
val jsonArray = JSONArray(json)
|
||||
for (i in 0 until jsonArray.length()) {
|
||||
val itemObject = jsonArray.getJSONObject(i)
|
||||
val itemMap = jsonToCustomLayerItem(itemObject)
|
||||
list.add(itemMap);
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
Log.e("jingo", e.stackTraceToString())
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据图层子表字段配置转Map
|
||||
* (主要原生层使用)
|
||||
*/
|
||||
fun customLayerItemsToMapList(list: List<CustomLayerItem>?): List<Map<*, *>> {
|
||||
var newList = mutableListOf<Map<*, *>>()
|
||||
if (list == null) {
|
||||
return newList
|
||||
}
|
||||
|
||||
for (item in list) {
|
||||
newList.add(item.toMap())
|
||||
}
|
||||
return newList
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据图层子表字段配置 json形式的数据 转成对象形式
|
||||
* (原生层主要用json,所以主要原生层使用)
|
||||
*/
|
||||
private fun jsonToCustomLayerItem(itemObject: JSONObject): CustomLayerItem {
|
||||
return CustomLayerItem(
|
||||
key = itemObject.optString("key"),
|
||||
title = itemObject.optString("title"),
|
||||
type = DataLayerItemType.values()[itemObject.optInt("type")],
|
||||
// nullable = itemObject.optBoolean("nullable"),
|
||||
// primaryKey = itemObject.optBoolean("primaryKey"),
|
||||
// value = itemObject.opt("value"),
|
||||
// selectOptions = itemObject.optString("selectOptions"),
|
||||
// isMainName = itemObject.optBoolean("isMainName"),
|
||||
describe = itemObject.optString("describe"),
|
||||
// checkManagerList = mutableListOf()
|
||||
itemBean = ""
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据图层子表字段配置转Map
|
||||
* (flutter层喜欢用map,所以主要用于flutter和原生交互使用)
|
||||
*/
|
||||
private fun jsonToCustomLayerItem(itemMap: Map<*, *>): CustomLayerItem {
|
||||
val checkMapList = itemMap["checkMangerList"] as List<Map<*, *>>
|
||||
val checkManagerList = mutableListOf<CheckManager>()
|
||||
for (c in checkMapList) {
|
||||
checkManagerList.add(
|
||||
CheckManager(
|
||||
id = (c["id"] as Int).toLong(),
|
||||
type = c["type"] as Int,
|
||||
tag = c["tag"] as String,
|
||||
regexStr = c["regexStr"] as String
|
||||
)
|
||||
)
|
||||
}
|
||||
return CustomLayerItem(
|
||||
key = itemMap["key"] as String,
|
||||
title = itemMap["title"] as String,
|
||||
type = DataLayerItemType.values()[itemMap["type"] as Int],
|
||||
// nullable = itemMap["nullable"] as Boolean,
|
||||
// primaryKey = itemMap["primaryKey"] as Boolean,
|
||||
// value = itemMap["value"] as Any,
|
||||
// selectOptions = itemMap["selectOptions"] as String,
|
||||
// isMainName = itemMap["isMainName"] as Boolean,
|
||||
describe = itemMap["describe"] as String,
|
||||
// checkManagerList = checkManagerList
|
||||
itemBean = ""
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据图层 map形式的字段数据集合转成对象集合
|
||||
* (主要用于flutter层与原生层数据交互时)
|
||||
*/
|
||||
fun listMapToCustomLayerItemsList(itemList: List<Map<*, *>>): List<CustomLayerItem> {
|
||||
val list = mutableListOf<CustomLayerItem>()
|
||||
for (itemMap in itemList) {
|
||||
list.add(jsonToCustomLayerItem(itemMap));
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// /**
|
||||
// * layerManager转化成map
|
||||
// */
|
||||
// fun layerManagerToMap(
|
||||
// layerManager: LayerManager,
|
||||
// itemsMap: List<Map<String, *>>
|
||||
// ): Map<*, *> {
|
||||
// return mapOf("layerManager" to layerManager.toMap(), "itemsList" to itemsMap);
|
||||
// }
|
||||
/**
|
||||
* 检查项转map给flutter
|
||||
*/
|
||||
fun toCheckManagerMapList(list: List<CheckManager>): List<Map<*, *>> {
|
||||
val newList = mutableListOf<Map<*, *>>()
|
||||
for (check in list) {
|
||||
newList.add(
|
||||
check.toMap()
|
||||
)
|
||||
}
|
||||
return newList
|
||||
}
|
||||
|
||||
fun toOcrList(
|
||||
path: String,
|
||||
basePolygonResultModels: List<BasePolygonResultModel>
|
||||
): Map<*, *> {
|
||||
val newList = mutableMapOf<String, Any>()
|
||||
newList["photo_path"] = path
|
||||
val list = mutableListOf<String>();
|
||||
for (model in basePolygonResultModels) {
|
||||
list.add(model.name)
|
||||
}
|
||||
newList["result"] = list
|
||||
return newList
|
||||
}
|
||||
|
||||
/**
|
||||
* 将ocr识别结果返回给flutter
|
||||
*/
|
||||
suspend fun toFlutterOcrList(
|
||||
list: List<Map<String, Any>>,
|
||||
): List<Any> {
|
||||
val listR = mutableListOf<Any>()
|
||||
val job = MainScope().async(Dispatchers.IO) {
|
||||
Log.e("jingo", "OCR图像识别写CSV文件 ${Thread.currentThread().name}")
|
||||
for (item in list) {
|
||||
if (item is Map) {
|
||||
val map1 = mutableMapOf<String, Any>()
|
||||
map1["path"] = item["path"]!!
|
||||
map1["width"] = item["width"]!!
|
||||
map1["height"] = item["height"]!!
|
||||
var data = item["data"]
|
||||
if (data is List<*>) {
|
||||
val dataList = mutableListOf<Any>()
|
||||
for (v in data) {
|
||||
val map = mutableMapOf<String, Any>()
|
||||
map["index"] = (v as OcrViewResultModel).index
|
||||
map["bounds"] = rectToMap(v.bounds)
|
||||
map["text"] = v.name
|
||||
map["confidence"] = v.confidence
|
||||
dataList.add(map)
|
||||
}
|
||||
map1["data"] = dataList
|
||||
}
|
||||
listR.add(map1)
|
||||
}
|
||||
}
|
||||
}
|
||||
job.await()
|
||||
Log.e("jingo", "ORC 识别结果 ${listR.toString()}")
|
||||
return listR
|
||||
}
|
||||
|
||||
private fun rectToMap(list: List<Point>): List<List<Int>> {
|
||||
val pointList = mutableListOf<List<Int>>()
|
||||
for (point in list) {
|
||||
val l = mutableListOf<Int>()
|
||||
l.add(point.x)
|
||||
l.add(point.y)
|
||||
pointList.add(l)
|
||||
}
|
||||
|
||||
return pointList
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.navinfo.collect.library.data
|
||||
|
||||
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity
|
||||
import java.io.File
|
||||
|
||||
interface GisFileUtils {
|
||||
fun parserGisFile(file: File): List<GeometryFeatureEntity>
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.navinfo.collect.library.data;
|
||||
|
||||
import org.gdal.gdal.gdal;
|
||||
import org.gdal.ogr.ogr;
|
||||
|
||||
/**
|
||||
* 使用gdal和ogr解析Gis数据的引擎
|
||||
*/
|
||||
public abstract class GisFileParserEngine implements IGisFileParserEngine {
|
||||
public GisFileParserEngine() {
|
||||
initEngine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initEngine() {
|
||||
ogr.RegisterAll();
|
||||
gdal.AllRegister();
|
||||
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
|
||||
gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.navinfo.collect.library.data;
|
||||
|
||||
import com.navinfo.collect.library.data.entity.LayerEntity;
|
||||
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 常用Gis文件的解析写入引擎
|
||||
* */
|
||||
public interface IGisFileParserEngine {
|
||||
void initEngine();
|
||||
|
||||
List<LayerEntity> parserGisFile(File gisFile);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.navinfo.collect.library.data;
|
||||
|
||||
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity;
|
||||
import com.navinfo.collect.library.data.entity.LayerEntity;
|
||||
|
||||
import org.gdal.gdal.gdal;
|
||||
import org.gdal.ogr.DataSource;
|
||||
import org.gdal.ogr.Feature;
|
||||
import org.gdal.ogr.FeatureDefn;
|
||||
import org.gdal.ogr.ogr;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MapInfoParserEngine extends GisFileParserEngine {
|
||||
|
||||
/**
|
||||
* 读取MapInfo文件
|
||||
* */
|
||||
@Override
|
||||
public List<LayerEntity> parserGisFile(File mifFile) {
|
||||
DataSource ds = ogr.Open(mifFile.getAbsolutePath(), 0);
|
||||
if (ds == null) {
|
||||
System.out.println("打开文件失败");
|
||||
return null;
|
||||
}
|
||||
System.out.println("打开文件成功");
|
||||
List<LayerEntity> layerEntityList = new ArrayList<>();
|
||||
if (ds.GetLayerCount()>0) {
|
||||
for (int i = 0; i < ds.GetLayerCount(); i++) {
|
||||
org.gdal.ogr.Layer layer = ds.GetLayer(i);
|
||||
if (layer == null) {
|
||||
System.out.println("获取第"+i+"个图层失败");
|
||||
continue;
|
||||
}
|
||||
|
||||
LayerEntity layerEntity = new LayerEntity();
|
||||
layerEntity.setLayerName(layer.GetName());
|
||||
layerEntity.setGeomType(layer.GetGeomType());
|
||||
layerEntity.setFromDataName(mifFile.getName());
|
||||
|
||||
|
||||
System.out.println("读取到Layer" + layer.GetName());
|
||||
layer.ResetReading();
|
||||
for (int j = 0; j < layer.GetFeatureCount(); j++) {
|
||||
GeometryFeatureEntity entity = new GeometryFeatureEntity();
|
||||
Feature feature = layer.GetFeature(j);
|
||||
entity.setGeometry(feature.GetGeometryRef().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return layerEntityList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.navinfo.collect.library.data
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.FlutterBaseActivity
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.handler.DataLayerHandler
|
||||
import com.navinfo.collect.library.system.Constant
|
||||
|
||||
/**
|
||||
* 地图控制器
|
||||
*/
|
||||
|
||||
open class NIDataController(
|
||||
context: Context,
|
||||
activity: FlutterBaseActivity,
|
||||
) {
|
||||
protected val mContext = context
|
||||
protected val mActivity = activity
|
||||
internal val mDateBase: MapLifeDataBase = MapLifeDataBase.getDatabase(
|
||||
context, "${Constant.ROOT_PATH}/coremap.db"
|
||||
)
|
||||
|
||||
init {
|
||||
RealmUtils.getInstance().init(mContext, Constant.ROOT_PATH, "hd-data")
|
||||
}
|
||||
|
||||
protected val dataHandler: DataLayerHandler = DataLayerHandler(mContext, mDateBase);
|
||||
|
||||
open fun release() {
|
||||
mDateBase.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
package com.navinfo.collect.library.data;
|
||||
|
||||
import com.google.protobuf.Descriptors;
|
||||
import com.google.protobuf.GeneratedMessageV3;
|
||||
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Resultdata;
|
||||
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.CoordinateXYM;
|
||||
import org.locationtech.jts.geom.CoordinateXYZM;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.GeometryFactory;
|
||||
import org.locationtech.jts.geom.LineString;
|
||||
import org.locationtech.jts.geom.Point;
|
||||
import org.locationtech.jts.geom.Polygon;
|
||||
import org.locationtech.jts.io.WKBWriter;
|
||||
import org.locationtech.spatial4j.context.SpatialContext;
|
||||
import org.locationtech.spatial4j.context.SpatialContextFactory;
|
||||
import org.locationtech.spatial4j.context.jts.JtsSpatialContextFactory;
|
||||
import org.locationtech.spatial4j.io.ShapeIO;
|
||||
import org.locationtech.spatial4j.io.ShapeReader;
|
||||
import org.locationtech.spatial4j.io.ShapeWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class NavinfoPbfData {
|
||||
private static GeometryFactory factory;
|
||||
private static SpatialContext spatialContext;
|
||||
private static ShapeReader shapeReader;
|
||||
private static ShapeWriter shapeWriter;
|
||||
private static WKBWriter wkbWriter;
|
||||
private boolean isInit = false;
|
||||
|
||||
public NavinfoPbfData() {
|
||||
if (!isInit) {
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean init() {
|
||||
SpatialContextFactory spatialContextFactory = new SpatialContextFactory();
|
||||
wkbWriter= new WKBWriter(3, true);
|
||||
factory = new JtsSpatialContextFactory().getGeometryFactory();
|
||||
|
||||
spatialContext = new SpatialContext(spatialContextFactory);
|
||||
shapeReader = spatialContext.getFormats().getWktReader();
|
||||
shapeWriter = spatialContext.getFormats().getWktWriter();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Resultdata.ResultData readPbfData(InputStream inputStream) throws IOException {
|
||||
return Resultdata.ResultData.parseFrom(inputStream);
|
||||
}
|
||||
|
||||
public static Geometry createGeometry(GeneratedMessageV3 geometry) {
|
||||
Geometry resultGeometry = null;
|
||||
if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point2d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point2d point2d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point2d) geometry;
|
||||
Coordinate coordinate = new Coordinate(point2d.getLongitudeDegrees(), point2d.getLatitudeDegrees());
|
||||
resultGeometry = factory.createPoint(coordinate);
|
||||
} else if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point3d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point3d point3d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point3d) geometry;
|
||||
CoordinateXYZM coordinate = new CoordinateXYZM(point3d.getLatLon().getLongitudeDegrees(), point3d.getLatLon().getLatitudeDegrees(), point3d.getElevation().getZ(), 7);
|
||||
resultGeometry = factory.createPoint(coordinate);
|
||||
} else if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.LineString2d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.LineString2d lineString2d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.LineString2d) geometry;
|
||||
Coordinate[] coordinates = new Coordinate[lineString2d.getLinestringPointsCount()];
|
||||
for (int i = 0; i < lineString2d.getLinestringPointsCount(); i++) {
|
||||
coordinates[i] = new Coordinate(lineString2d.getLinestringPoints(i).getLongitudeDegrees(), lineString2d.getLinestringPoints(i).getLatitudeDegrees());
|
||||
}
|
||||
resultGeometry = factory.createLineString(coordinates);
|
||||
} else if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.LineString3d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.LineString3d lineString3d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.LineString3d) geometry;
|
||||
CoordinateXYZM[] coordinates = new CoordinateXYZM[lineString3d.getLinestringPointsCount()];
|
||||
for (int i = 0; i < lineString3d.getLinestringPointsCount(); i++) {
|
||||
coordinates[i] = new CoordinateXYZM(lineString3d.getLinestringPoints(i).getLatLon().getLongitudeDegrees(), lineString3d.getLinestringPoints(i).getLatLon().getLatitudeDegrees(), lineString3d.getLinestringPoints(i).getElevation().getZ(), 7);
|
||||
}
|
||||
resultGeometry = factory.createLineString(coordinates);
|
||||
} else if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiLineString2d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiLineString2d multiLineString2d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiLineString2d) geometry;
|
||||
LineString[] lineStrings = new LineString[multiLineString2d.getLineStringsCount()];
|
||||
for (int i = 0; i < multiLineString2d.getLineStringsCount(); i++) {
|
||||
lineStrings[i] = (LineString) createGeometry(multiLineString2d.getLineStrings(i));
|
||||
}
|
||||
resultGeometry = factory.createMultiLineString(lineStrings);
|
||||
} else if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiLineString3d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiLineString3d multiLineString3d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiLineString3d) geometry;
|
||||
LineString[] lineStrings = new LineString[multiLineString3d.getLineStringsCount()];
|
||||
for (int i = 0; i < multiLineString3d.getLineStringsCount(); i++) {
|
||||
lineStrings[i] = (LineString) createGeometry(multiLineString3d.getLineStrings(i));
|
||||
}
|
||||
resultGeometry = factory.createMultiLineString(lineStrings);
|
||||
} else if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Polygon2d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Polygon2d polygon2d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Polygon2d) geometry;
|
||||
Coordinate[] coordinates = new Coordinate[polygon2d.getPolygonPointsCount()];
|
||||
for (int i = 0; i < polygon2d.getPolygonPointsCount(); i++) {
|
||||
coordinates[i] = new Coordinate(polygon2d.getPolygonPoints(i).getLongitudeDegrees(), polygon2d.getPolygonPoints(i).getLatitudeDegrees());
|
||||
}
|
||||
resultGeometry = factory.createPolygon(coordinates);
|
||||
} else if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Polygon3d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Polygon3d polygon3d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Polygon3d) geometry;
|
||||
CoordinateXYZM[] coordinates = new CoordinateXYZM[polygon3d.getPolygonPointsCount()];
|
||||
for (int i = 0; i < polygon3d.getPolygonPointsCount(); i++) {
|
||||
coordinates[i] = new CoordinateXYZM(polygon3d.getPolygonPoints(i).getLatLon().getLongitudeDegrees(), polygon3d.getPolygonPoints(i).getLatLon().getLatitudeDegrees(), polygon3d.getPolygonPoints(i).getElevation().getZ(), 7);
|
||||
}
|
||||
resultGeometry = factory.createPolygon(coordinates);
|
||||
} else if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiPolygon2d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiPolygon2d multiPolygon2d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiPolygon2d) geometry;
|
||||
Polygon[] polygons = new Polygon[multiPolygon2d.getPolygonsCount()];
|
||||
for (int i = 0; i < multiPolygon2d.getPolygonsCount(); i++) {
|
||||
polygons[i] = (Polygon) createGeometry(multiPolygon2d.getPolygons(i));
|
||||
}
|
||||
resultGeometry = factory.createMultiPolygon(polygons);
|
||||
} else if (geometry instanceof com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiPolygon3d) {
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiPolygon3d multiPolygon3d = (com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.MultiPolygon3d) geometry;
|
||||
Polygon[] polygons = new Polygon[multiPolygon3d.getPolygonsCount()];
|
||||
for (int i = 0; i < multiPolygon3d.getPolygonsCount(); i++) {
|
||||
polygons[i] = (Polygon) createGeometry(multiPolygon3d.getPolygons(i));
|
||||
}
|
||||
resultGeometry = factory.createMultiPolygon(polygons);
|
||||
}
|
||||
return resultGeometry;
|
||||
}
|
||||
|
||||
public static GeometryFeatureEntity createGeometryEntity(Geometry geometry, Map<Descriptors.FieldDescriptor, Object> userData, Map<String, String> extendFields) {
|
||||
if (geometry == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder prefixStr = new StringBuilder();
|
||||
GeometryFeatureEntity entity = new GeometryFeatureEntity();
|
||||
entity.setId(UUID.randomUUID().toString());
|
||||
entity.setGeometry(geometry);
|
||||
entity.setWkb(wkbWriter.write(geometry));
|
||||
if (userData!=null&&!userData.isEmpty()) {
|
||||
for (Map.Entry<Descriptors.FieldDescriptor, Object> e: userData.entrySet()) {
|
||||
getFieldEntry(e, prefixStr, entity.getProperties());
|
||||
}
|
||||
}
|
||||
if (extendFields!=null&&!extendFields.isEmpty()) {
|
||||
entity.getOtherProperties().putAll(extendFields);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归调用,如果存在子属性,则父子属性以{parent.child}格式存入map
|
||||
* */
|
||||
private static void getFieldEntry(Map.Entry<Descriptors.FieldDescriptor, Object> e, StringBuilder prefix, Map<String, String> properties) {
|
||||
prefix.append(".").append(e.getKey().getName());
|
||||
if (e.getValue() instanceof GeneratedMessageV3) {
|
||||
for (Map.Entry<Descriptors.FieldDescriptor, Object> subE: ((GeneratedMessageV3)e.getValue()).getAllFields().entrySet()) {
|
||||
getFieldEntry(subE, prefix, properties);
|
||||
}
|
||||
} else {
|
||||
properties.put(e.getKey().getName(), e.getValue().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
package com.navinfo.collect.library.data
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.google.protobuf.GeneratedMessageV3
|
||||
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity
|
||||
import com.navinfo.collect.library.data.entity.LayerEntity
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.*
|
||||
import org.locationtech.jts.algorithm.Angle
|
||||
import org.locationtech.jts.geom.Coordinate
|
||||
import org.locationtech.jts.geom.Geometry
|
||||
import org.locationtech.jts.geom.LineString
|
||||
import org.locationtech.jts.geom.util.AffineTransformation
|
||||
import org.locationtech.jts.geom.util.AffineTransformationFactory
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.util.*
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
import kotlin.streams.toList
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
class NavinfoPbfFileUtils: GisFileUtils {
|
||||
/*
|
||||
* 解析Pbf文件
|
||||
* */
|
||||
override fun parserGisFile(file: File): List<GeometryFeatureEntity> {
|
||||
val geometryEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (!file?.isFile || !file.exists()) {
|
||||
return geometryEntityList;
|
||||
}
|
||||
// 解析pbf文件
|
||||
val pbfData = NavinfoPbfData.readPbfData(FileInputStream(file))
|
||||
|
||||
// 解析roadLink道路线
|
||||
geometryEntityList.addAll(parserRoadLink(pbfData.roadlinkList, file, "道路线"))
|
||||
// 解析roadLink上的道路方向
|
||||
geometryEntityList.addAll(parserRoadDirect(pbfData.roadlinkList, file, "道路方向"))
|
||||
// 解析roadLink的桥属性
|
||||
geometryEntityList.addAll(parserRoadBrunnel(pbfData.roadlinkList, file, "桥隧道"))
|
||||
// 解析roadLink的移动式桥属性
|
||||
geometryEntityList.addAll(parserRoadMovBrg(pbfData.roadlinkList, file, "移动式桥"))
|
||||
// 解析hadLaneLink车道中心线
|
||||
geometryEntityList.addAll(parserHadLaneLink(pbfData.hadlanelinkList, file, "车道中心线"))
|
||||
// 解析hadLaneMarkLink车道边线
|
||||
geometryEntityList.addAll(parserHadLaneMarkLink(pbfData.hadlanemarklinkList, file, "车道边线"))
|
||||
// 解析hadLaneMarkLink.traversal车道边线可跨越性
|
||||
geometryEntityList.addAll(parserHadLaneMarkLinkTraversal(pbfData.hadlanemarklinkList, file, "车道边线可跨越性"))
|
||||
// 解析hadLaneMarkLink.marking车道边线划线类型
|
||||
geometryEntityList.addAll(parserHadLaneMarkLinkBoundary(pbfData.hadlanemarklinkList, file, "车道边线非标线类型"))
|
||||
// 解析speedLimitGen固定限速
|
||||
geometryEntityList.addAll(parserSpeedLimitGen(pbfData.rdspeedlimitgenList, file, "固定限速"))
|
||||
// 解析speedLimitDepend条件限速
|
||||
geometryEntityList.addAll(parserSpeedLimitDepend(pbfData.rdspeedlimitdependList, file, "条件限速"))
|
||||
// 解析speedLimitVar可变限速
|
||||
geometryEntityList.addAll(parserSpeedLimitVar(pbfData.rdspeedlimitvarList, file, "可变限速"))
|
||||
return geometryEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理道路线RoadLink
|
||||
* */
|
||||
private fun parserRoadLink(roadLinkList: List<Roadlink.RoadLink>, file: File, layerName: String= "道路线", layerTableName: String = "ROAD_LINK"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (roadLinkList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
for (roadLink in roadLinkList) {
|
||||
val geometry = NavinfoPbfData.createGeometry(roadLink.geometry)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(geometry, roadLink, layerName, layerTableName, file)
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
|
||||
return featureEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理车道中心线HadLaneLink
|
||||
* */
|
||||
private fun parserHadLaneLink(hadLaneLinkList: List<Hadlanelink.HadLaneLink>, file: File, layerName: String= "车道中心线", layerTableName: String = "HAD_LANE_LINK"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (hadLaneLinkList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
for (hadLaneLink in hadLaneLinkList) {
|
||||
val geometry = NavinfoPbfData.createGeometry(hadLaneLink.geometry)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(geometry, hadLaneLink, layerName, layerTableName, file)
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
return featureEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理speedLimitGen固定限速
|
||||
* */
|
||||
private fun parserSpeedLimitGen(speedLimitGenList: List<Rdspeedlimitgen.RdSpeedlimitGen>, file: File, layerName: String= "固定限速", layerTableName: String = "SPEED_LIMIT_GEN"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (speedLimitGenList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
for (speedLimitGen in speedLimitGenList) {
|
||||
val geometry = NavinfoPbfData.createGeometry(speedLimitGen.geometry)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(geometry, speedLimitGen, layerName, layerTableName, file)
|
||||
geometryFeatureEntity.otherProperties["SPEED_FLAG"] = speedLimitGen.speedFlag.toString()
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
return featureEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理speedLimitDepend条件限速
|
||||
* */
|
||||
private fun parserSpeedLimitDepend(speedLimitDenpendList: List<Rdspeedlimitdepend.RdSpeedlimitDepend>, file: File, layerName: String= "条件限速", layerTableName: String = "SPEED_LIMIT_DEPEND"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (speedLimitDenpendList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
for (speedLimitDepend in speedLimitDenpendList) {
|
||||
val geometry = NavinfoPbfData.createGeometry(speedLimitDepend.geometry)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(geometry, speedLimitDepend, layerName, layerTableName, file)
|
||||
geometryFeatureEntity.otherProperties["SPEED_FLAG"] = speedLimitDepend.speedFlag.toString()
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
return featureEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理speedLimitDepend条件限速
|
||||
* */
|
||||
private fun parserSpeedLimitVar(speedLimitVarList: List<Rdspeedlimitvar.RdSpeedlimitVar>, file: File,
|
||||
layerName: String= "可变限速", layerTableName: String = "SPEED_LIMIT_VAR"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (speedLimitVarList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
for (speedLimitVar in speedLimitVarList) {
|
||||
val geometry = NavinfoPbfData.createGeometry(speedLimitVar.geometry)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(geometry, speedLimitVar, layerName, layerTableName, file)
|
||||
geometryFeatureEntity.otherProperties["SPEED_FLAG"] = speedLimitVar.speedFlag.toString()
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
return featureEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理车道边线HadLaneMarkLink
|
||||
* */
|
||||
private fun parserHadLaneMarkLink(hadLaneMarkLinkList: List<Hadlanemarklink.HadLaneMarkLink>, file: File,
|
||||
layerName: String= "车道边线", layerTableName: String = "HAD_LANE_MARK_LINK"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (hadLaneMarkLinkList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
for (hadLaneMarkLink in hadLaneMarkLinkList) {
|
||||
val geometry = NavinfoPbfData.createGeometry(hadLaneMarkLink.geometry)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(geometry, hadLaneMarkLink, layerName, layerTableName, file)
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
|
||||
return featureEntityList;
|
||||
}
|
||||
/**
|
||||
* 处理车道边线HadLaneMarkLinkTraversal
|
||||
* */
|
||||
private fun parserHadLaneMarkLinkTraversal(hadLaneMarkLinkList: List<Hadlanemarklink.HadLaneMarkLink>, file: File,
|
||||
layerName: String= "车道边线可跨越性", layerTableName: String = "HAD_LANE_MARK_LINK_TRAVERSAL"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (hadLaneMarkLinkList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
// 解析道路边线可跨越性
|
||||
for (hadLaneMarkLink in hadLaneMarkLinkList) {
|
||||
// for (traversal in hadLaneMarkLink.traversalList) {
|
||||
// // 根据给出的起终点计算切割点在线上的index
|
||||
// val startPoint3d = traversal.paPosition.sIndex
|
||||
// val endPoint3d = traversal.paPosition.eIndex
|
||||
// val subIndex:List<Map<String, Any>> = List()
|
||||
// val sortedIndex =subIndex.sortedBy { item->item["startIndex"].toString().toInt() }
|
||||
// for ((index, map) in sortedIndex.withIndex()) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
for (traversal in hadLaneMarkLink.traversalList) {
|
||||
val startPoint3d = traversal.paPosition.sIndex
|
||||
val endPoint3d = traversal.paPosition.eIndex
|
||||
val traversalLineString = subLine(hadLaneMarkLink.geometry, startPoint3d, endPoint3d)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(traversalLineString, traversal, layerName, layerTableName, file)
|
||||
geometryFeatureEntity.otherProperties["TYPE"] = traversal.type.toString()
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
}
|
||||
|
||||
return featureEntityList;
|
||||
}
|
||||
/**
|
||||
* 处理车道边线HadLaneMarkLinkBoundary
|
||||
* */
|
||||
private fun parserHadLaneMarkLinkBoundary(hadLaneMarkLinkList: List<Hadlanemarklink.HadLaneMarkLink>, file: File,
|
||||
layerName: String= "车道边线非标线类型", layerTableName: String = "HAD_LANE_MARK_LINK_BOUNDARY"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (hadLaneMarkLinkList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
// 解析道路边线可跨越性
|
||||
for (hadLaneMarkLink in hadLaneMarkLinkList) {
|
||||
for (boundary in hadLaneMarkLink.boundaryList) {
|
||||
val startPoint3d = boundary.paPosition.sIndex
|
||||
val endPoint3d = boundary.paPosition.eIndex
|
||||
val boundaryLineString = subLine(hadLaneMarkLink.geometry, startPoint3d, endPoint3d)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(boundaryLineString, boundary, layerName, layerTableName, file)
|
||||
if (boundary.boundaryType.type!=2) {
|
||||
geometryFeatureEntity.otherProperties["BOUNDARY_TYPE"] = boundary.boundaryType.type.toString()
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
} else {
|
||||
if (boundary.markingList!=null&&boundary.markingList.isNotEmpty()) {
|
||||
for (mark in boundary.markingList) {
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(boundaryLineString, mark, "车道边线标线类型", "HAD_LANE_MARK_LINK_MARKING", file)
|
||||
geometryFeatureEntity.otherProperties["BOUNDARY_TYPE"] = "2"
|
||||
geometryFeatureEntity.otherProperties["MARK_TYPE"] = mark.markType.toString()
|
||||
geometryFeatureEntity.otherProperties["MARK_COLOR"] = mark.markColor.toString()
|
||||
// 根据mark的横向偏移量重新设置geometry值
|
||||
val lineString = boundaryLineString as LineString
|
||||
var degree = Angle.toDegrees(Angle.angle(lineString.startPoint.coordinate, lineString.endPoint.coordinate))
|
||||
degree = degree+90
|
||||
val transformation:AffineTransformation = AffineTransformationFactory.createFromControlVectors(
|
||||
Coordinate(0.toDouble(), 0.toDouble()), Coordinate(sin(degree) *(mark.lateralOffset*7e-9).toDouble(), cos(degree)*mark.lateralOffset*7e-9.toDouble())
|
||||
)
|
||||
val transformGeometry = transformation.transform(boundaryLineString)
|
||||
geometryFeatureEntity.geometry = transformGeometry.toString()
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return featureEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理道路方向
|
||||
* */
|
||||
private fun parserRoadDirect(roadLinkList: List<Roadlink.RoadLink>, file: File,
|
||||
layerName: String= "道路方向", layerTableName: String = "ROAD_LINK_DIRECT"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (roadLinkList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
for (roadLink in roadLinkList) {
|
||||
val geometry = NavinfoPbfData.createGeometry(roadLink.geometry)
|
||||
// 解析道路方向
|
||||
for (dirct in roadLink.directList) {
|
||||
val startPoint3d = dirct.paPosition.sIndex
|
||||
val endPoint3d = dirct.paPosition.eIndex
|
||||
val directLineString = subLine(roadLink.geometry, startPoint3d, endPoint3d)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(directLineString, dirct, layerName, layerTableName, file)
|
||||
geometryFeatureEntity.otherProperties["VALUE"] = dirct.value.toString()
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
}
|
||||
|
||||
return featureEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理道路的桥属性
|
||||
* */
|
||||
private fun parserRoadBrunnel(roadLinkList: List<Roadlink.RoadLink>, file: File,
|
||||
layerName: String= "桥隧道", layerTableName: String = "ROAD_LINK_BRUNNEL"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (roadLinkList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
for (roadLink in roadLinkList) {
|
||||
// 解析桥属性IS_BRUNNEL
|
||||
for (brunnel in roadLink.isBrunnelList) {
|
||||
val startPoint3d = brunnel.paPosition.sIndex
|
||||
val endPoint3d = brunnel.paPosition.eIndex
|
||||
val brunnelLineString = subLine(roadLink.geometry, startPoint3d, endPoint3d)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(brunnelLineString, brunnel, layerName, layerTableName, file)
|
||||
geometryFeatureEntity.otherProperties["TYPE"] = brunnel.type.toString()
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
}
|
||||
|
||||
return featureEntityList;
|
||||
}
|
||||
/**
|
||||
* 处理道路的移动式桥属性
|
||||
* */
|
||||
private fun parserRoadMovBrg(roadLinkList: List<Roadlink.RoadLink>, file: File,
|
||||
layerName: String= "移动式桥", layerTableName: String = "ROAD_LINK_MOVBRG"): List<GeometryFeatureEntity> {
|
||||
val featureEntityList = ArrayList<GeometryFeatureEntity>()
|
||||
if (roadLinkList?.isEmpty()) {
|
||||
return featureEntityList
|
||||
}
|
||||
for (roadLink in roadLinkList) {
|
||||
// 解析移动式桥属性MOVBRG
|
||||
for (movbrg in roadLink.movbrgList) {
|
||||
val startPoint3d = movbrg.paPosition.sIndex
|
||||
val endPoint3d = movbrg.paPosition.eIndex
|
||||
val movbrgLineString = subLine(roadLink.geometry, startPoint3d, endPoint3d)
|
||||
val geometryFeatureEntity =
|
||||
convertDefaultHDEntity(movbrgLineString, movbrg, layerName, layerTableName, file)
|
||||
featureEntityList.add(geometryFeatureEntity)
|
||||
}
|
||||
}
|
||||
|
||||
return featureEntityList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 读取指定的HD元素数据
|
||||
* */
|
||||
private fun convertDefaultHDEntity(geometry: Geometry, generatedMsg: GeneratedMessageV3, layerName: String, layerTableName: String, file: File): GeometryFeatureEntity {
|
||||
// 处理roadLink
|
||||
val layerEntity = LayerEntity()
|
||||
layerEntity.layerName = layerName
|
||||
layerEntity.layerTableName = layerTableName
|
||||
layerEntity.fromDataName = file.name
|
||||
// 转换geometry和属性信息为数据库字段
|
||||
val renderMap = obtainRenderMap(layerTableName)
|
||||
val featureEntity =
|
||||
NavinfoPbfData.createGeometryEntity(geometry, generatedMsg.allFields, renderMap)
|
||||
featureEntity.name = layerName
|
||||
featureEntity.layerEntity = layerEntity
|
||||
return featureEntity
|
||||
}
|
||||
|
||||
private fun obtainRenderMap(kind: String): Map<String, String> {
|
||||
val renderPropMap = HashMap<String, String>()
|
||||
renderPropMap.put("navinfo_hd", kind)
|
||||
return renderPropMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据给定的起终点截取LineString3D
|
||||
* */
|
||||
private fun subLine(line: com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.LineString3d,
|
||||
sPoint: com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point3d,
|
||||
ePoint: com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point3d): Geometry {
|
||||
var sIndex = 0
|
||||
var eIndex = 0
|
||||
for ((index, linePoint) in line.linestringPointsList.withIndex()) {
|
||||
if (sIndex <= eIndex&&linePoint.equals(sPoint)) {
|
||||
sIndex = index
|
||||
} else if (linePoint.equals(ePoint)) {
|
||||
eIndex = index
|
||||
break
|
||||
}
|
||||
}
|
||||
if (eIndex>sIndex&&eIndex<line.linestringPointsList.size) {
|
||||
// 转换为geometry
|
||||
// 注意,因为sublist取的尾数为参数-1,所以eIndex需要加1
|
||||
val coordinateArrays: List<Coordinate> = line.linestringPointsList.subList(sIndex, eIndex+1).stream().map { Coordinate(it.latLon.longitudeDegrees, it.latLon.latitudeDegrees, it.elevation.z) }.toList()
|
||||
val toTypedArray = coordinateArrays.toTypedArray()
|
||||
if (toTypedArray.size == 1) {
|
||||
toTypedArray[1] = toTypedArray[0].copy()
|
||||
}
|
||||
// println("toTypedArray点数:${toTypedArray.size},sIndex:${sIndex},eIndex:${eIndex}")
|
||||
return GeometryTools.getLineStrinGeo(toTypedArray)
|
||||
}
|
||||
// 如果没能截取到子线段,则返回第一个点组成的线
|
||||
return GeometryTools.getLineStrinGeo(
|
||||
arrayOf(
|
||||
Coordinate(line.linestringPointsList.get(0).latLon.longitudeDegrees, line.linestringPointsList.get(0).latLon.latitudeDegrees, line.linestringPointsList.get(0).elevation.z),
|
||||
Coordinate(line.linestringPointsList.get(1).latLon.longitudeDegrees, line.linestringPointsList.get(1).latLon.latitudeDegrees, line.linestringPointsList.get(1).elevation.z))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
package com.navinfo.collect.library.data;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.protobuf.GeneratedMessageV3;
|
||||
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity;
|
||||
import com.navinfo.collect.library.data.entity.LayerEntity;
|
||||
import com.navinfo.collect.library.map.NILayerManager;
|
||||
import com.navinfo.collect.library.utils.GeometryTools;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Hadlanelink;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Hadlanemarklink;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Objectarrow;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Objectcrosswalk;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Objectpole;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Objectsymbol;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Objecttrafficlights;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Resultdata;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.object.BoundaryOuterClass;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.object.Boundarytype;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.object.MarkingOuterClass;
|
||||
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.object.Paposition;
|
||||
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.LineString;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.realm.Realm;
|
||||
import io.realm.RealmConfiguration;
|
||||
import io.realm.RealmModel;
|
||||
import kotlin.jvm.internal.Intrinsics;
|
||||
|
||||
|
||||
public class RealmUtils {
|
||||
private Context mContext;
|
||||
private static RealmUtils instance;
|
||||
private Realm realm;
|
||||
private RealmConfiguration realmConfiguration;
|
||||
private String defaultDir = NILayerManager.defaultDir;
|
||||
private String realmName;
|
||||
|
||||
private final String NAME = "name";
|
||||
private final String TYPE = "navi_type";
|
||||
|
||||
public void init(Context mContext, String dir, String realmName) {
|
||||
this.mContext = mContext;
|
||||
Realm.init(this.mContext);
|
||||
this.realmName = realmName;
|
||||
realmConfiguration = new RealmConfiguration.Builder()
|
||||
.directory(dir == null?new File(defaultDir): new File(dir))
|
||||
.name(realmName)
|
||||
.allowWritesOnUiThread(true)
|
||||
.allowQueriesOnUiThread(true)
|
||||
.schemaVersion(1)
|
||||
.deleteRealmIfMigrationNeeded()
|
||||
.encryptionKey(Arrays.copyOf(new String("encryp").getBytes(StandardCharsets.UTF_8), 64))
|
||||
.build();
|
||||
System.out.println("encryp:"+toHexString(Arrays.copyOf(new String("encryp").getBytes(StandardCharsets.UTF_8), 64)));
|
||||
Realm.setDefaultConfiguration(realmConfiguration);
|
||||
}
|
||||
|
||||
public static RealmUtils getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new RealmUtils();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Realm getRealm() throws Exception {
|
||||
if (realmConfiguration == null) {
|
||||
throw new Exception("请先调用Realm.init方法初始化!");
|
||||
}
|
||||
return Realm.getDefaultInstance();
|
||||
}
|
||||
|
||||
public RealmConfiguration getRealmConfiguration() {
|
||||
return realmConfiguration;
|
||||
}
|
||||
|
||||
|
||||
private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
/**
|
||||
* 方法一:将byte类型数组转化成16进制字符串
|
||||
* @explain 字符串拼接
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
public static String toHexString(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int num;
|
||||
for (byte b : bytes) {
|
||||
num = b < 0 ? 256 + b : b;
|
||||
sb.append(HEX_CHAR[num / 16]).append(HEX_CHAR[num % 16]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public float getFileSize(){
|
||||
|
||||
File file = new File(defaultDir+"/"+realmName);
|
||||
|
||||
if(file.exists()&&file.isFile()){
|
||||
return file.length();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Map<String, Object> importPbfData(List<String> files) throws IOException {
|
||||
NavinfoPbfData pbfData = new NavinfoPbfData();
|
||||
long startTime = System.currentTimeMillis();
|
||||
RealmUtils var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).beginTransaction();
|
||||
Iterator fileIterator = files.iterator();
|
||||
|
||||
while(fileIterator.hasNext()) {
|
||||
String file = (String)fileIterator.next();
|
||||
Log.d("Realm-file:", file);
|
||||
System.out.print("file:" + file);
|
||||
Resultdata.ResultData resultData = pbfData.readPbfData((InputStream)(new FileInputStream(new File(file))));
|
||||
long sqlStartTime = System.currentTimeMillis();
|
||||
Intrinsics.checkNotNullExpressionValue(resultData, "resultData");
|
||||
List var40 = resultData.getHadlanelinkList();
|
||||
Intrinsics.checkNotNullExpressionValue(var40, "resultData.hadlanelinkList");
|
||||
Collection var9 = (Collection)var40;
|
||||
HashMap extentMapx;
|
||||
Iterator var12;
|
||||
Geometry geometry;
|
||||
GeometryFeatureEntity geometryEntityx;
|
||||
LayerEntity layerEntity;
|
||||
if (!var9.isEmpty()) {
|
||||
layerEntity = new LayerEntity();
|
||||
layerEntity.setLayerName("test");
|
||||
extentMapx = new HashMap();
|
||||
((Map)extentMapx).put(NAME, "车道中心线");
|
||||
((Map)extentMapx).put(TYPE, "had_lane_link");
|
||||
var12 = resultData.getHadlanelinkList().iterator();
|
||||
|
||||
while(var12.hasNext()) {
|
||||
Hadlanelink.HadLaneLink hadLaneLink = (Hadlanelink.HadLaneLink)var12.next();
|
||||
Intrinsics.checkNotNullExpressionValue(hadLaneLink, "hadLaneLink");
|
||||
geometry = pbfData.createGeometry((GeneratedMessageV3)hadLaneLink.getGeometry());
|
||||
geometryEntityx = pbfData.createGeometryEntity(geometry, hadLaneLink.getAllFields(), (Map)extentMapx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryEntityx, "geometryEntity");
|
||||
geometryEntityx.setLayerEntity(layerEntity);
|
||||
geometryEntityx.setName((String)extentMapx.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)geometryEntityx);
|
||||
}
|
||||
}
|
||||
|
||||
var40 = resultData.getHadlanemarklinkList();
|
||||
Intrinsics.checkNotNullExpressionValue(var40, "resultData.hadlanemarklinkList");
|
||||
var9 = (Collection)var40;
|
||||
Geometry lanLinkGeometry;
|
||||
Geometry intersection;
|
||||
if (!var9.isEmpty()) {
|
||||
layerEntity = new LayerEntity();
|
||||
layerEntity.setLayerName("test");
|
||||
extentMapx = new HashMap();
|
||||
((Map)extentMapx).put(NAME, "车道边线");
|
||||
((Map)extentMapx).put(TYPE, "had_lane_mark_link");
|
||||
var12 = resultData.getHadlanemarklinkList().iterator();
|
||||
|
||||
while(var12.hasNext()) {
|
||||
Hadlanemarklink.HadLaneMarkLink hadLaneMarkLink = (Hadlanemarklink.HadLaneMarkLink)var12.next();
|
||||
Intrinsics.checkNotNullExpressionValue(hadLaneMarkLink, "hadLaneMarkLink");
|
||||
geometry = pbfData.createGeometry((GeneratedMessageV3)hadLaneMarkLink.getGeometry());
|
||||
Iterator var15 = hadLaneMarkLink.getBoundaryList().iterator();
|
||||
|
||||
while(var15.hasNext()) {
|
||||
BoundaryOuterClass.Boundary boundary = (BoundaryOuterClass.Boundary)var15.next();
|
||||
Intrinsics.checkNotNullExpressionValue(boundary, "boundary");
|
||||
Paposition.PaPosition var43 = boundary.getPaPosition();
|
||||
Intrinsics.checkNotNullExpressionValue(var43, "boundary.paPosition");
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point3d sPoint = var43.getSIndex();
|
||||
var43 = boundary.getPaPosition();
|
||||
Intrinsics.checkNotNullExpressionValue(var43, "boundary.paPosition");
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point3d ePoint = var43.getEIndex();
|
||||
Coordinate[] var45 = new Coordinate[2];
|
||||
Intrinsics.checkNotNullExpressionValue(sPoint, "sPoint");
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point2d var10005 = sPoint.getLatLon();
|
||||
Intrinsics.checkNotNullExpressionValue(var10005, "sPoint.latLon");
|
||||
double fileIterator0 = var10005.getLongitudeDegrees();
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.Point2d var10006 = sPoint.getLatLon();
|
||||
Intrinsics.checkNotNullExpressionValue(var10006, "sPoint.latLon");
|
||||
double fileIterator3 = var10006.getLatitudeDegrees();
|
||||
com.navinfo.onemap.det.sdkpbf.proto.geometry.Geometry.ElevationMeasure var10007 = sPoint.getElevation();
|
||||
Intrinsics.checkNotNullExpressionValue(var10007, "sPoint.elevation");
|
||||
var45[0] = new Coordinate(fileIterator0, fileIterator3, var10007.getZ());
|
||||
Intrinsics.checkNotNullExpressionValue(ePoint, "ePoint");
|
||||
var10005 = ePoint.getLatLon();
|
||||
Intrinsics.checkNotNullExpressionValue(var10005, "ePoint.latLon");
|
||||
fileIterator0 = var10005.getLongitudeDegrees();
|
||||
var10006 = ePoint.getLatLon();
|
||||
Intrinsics.checkNotNullExpressionValue(var10006, "ePoint.latLon");
|
||||
fileIterator3 = var10006.getLatitudeDegrees();
|
||||
var10007 = ePoint.getElevation();
|
||||
Intrinsics.checkNotNullExpressionValue(var10007, "ePoint.elevation");
|
||||
var45[1] = new Coordinate(fileIterator0, fileIterator3, var10007.getZ());
|
||||
LineString line = GeometryTools.getLineStrinGeo(var45);
|
||||
lanLinkGeometry = line.buffer(1.0E-7D, 1, 2);
|
||||
intersection = geometry.intersection(lanLinkGeometry);
|
||||
extentMapx.remove("boundary_type");
|
||||
extentMapx.remove("mark_type");
|
||||
extentMapx.remove("mark_color");
|
||||
extentMapx.remove("mark_material");
|
||||
extentMapx.remove("mark_width");
|
||||
if (boundary.getBoundaryType() != null) {
|
||||
Map var46 = (Map)extentMapx;
|
||||
Boundarytype.BoundaryType2 var10002 = boundary.getBoundaryType();
|
||||
Intrinsics.checkNotNullExpressionValue(var10002, "boundary.boundaryType");
|
||||
var46.put("boundary_type", String.valueOf(var10002.getType()));
|
||||
Boundarytype.BoundaryType2 var49 = boundary.getBoundaryType();
|
||||
Intrinsics.checkNotNullExpressionValue(var49, "boundary.boundaryType");
|
||||
if (var49.getType() == 2 && boundary.getMarkingList() != null) {
|
||||
var40 = boundary.getMarkingList();
|
||||
Intrinsics.checkNotNullExpressionValue(var40, "boundary.markingList");
|
||||
Collection var21 = (Collection)var40;
|
||||
if (!var21.isEmpty()) {
|
||||
var46 = (Map)extentMapx;
|
||||
Object var48 = boundary.getMarkingList().get(0);
|
||||
Intrinsics.checkNotNullExpressionValue(var48, "boundary.markingList[0]");
|
||||
var46.put("mark_type", String.valueOf(((MarkingOuterClass.Marking)var48).getMarkType()));
|
||||
var46 = (Map)extentMapx;
|
||||
var48 = boundary.getMarkingList().get(0);
|
||||
Intrinsics.checkNotNullExpressionValue(var48, "boundary.markingList[0]");
|
||||
var46.put("mark_color", String.valueOf(((MarkingOuterClass.Marking)var48).getMarkColor()));
|
||||
var46 = (Map)extentMapx;
|
||||
var48 = boundary.getMarkingList().get(0);
|
||||
Intrinsics.checkNotNullExpressionValue(var48, "boundary.markingList[0]");
|
||||
var46.put("mark_material", String.valueOf(((MarkingOuterClass.Marking)var48).getMarkMaterial()));
|
||||
var46 = (Map)extentMapx;
|
||||
var48 = boundary.getMarkingList().get(0);
|
||||
Intrinsics.checkNotNullExpressionValue(var48, "boundary.markingList[0]");
|
||||
var46.put("mark_width", String.valueOf(((MarkingOuterClass.Marking)var48).getMarkWidth()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GeometryFeatureEntity geometryEntity = pbfData.createGeometryEntity(intersection, boundary.getAllFields(), (Map)extentMapx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryEntity, "geometryEntity");
|
||||
geometryEntity.setLayerEntity(layerEntity);
|
||||
geometryEntity.setName((String)extentMapx.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)geometryEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var40 = resultData.getObjectarrowList();
|
||||
Intrinsics.checkNotNullExpressionValue(var40, "resultData.objectarrowList");
|
||||
var9 = (Collection)var40;
|
||||
if (!var9.isEmpty()) {
|
||||
layerEntity = new LayerEntity();
|
||||
layerEntity.setLayerName("test");
|
||||
extentMapx = new HashMap();
|
||||
((Map)extentMapx).put(NAME, "道路箭头");
|
||||
((Map)extentMapx).put(TYPE, "object_arrow");
|
||||
var12 = resultData.getObjectarrowList().iterator();
|
||||
|
||||
label143:
|
||||
while(true) {
|
||||
label141:
|
||||
while(true) {
|
||||
if (!var12.hasNext()) {
|
||||
break label143;
|
||||
}
|
||||
|
||||
Objectarrow.ObjectArrow objectArrow = (Objectarrow.ObjectArrow)var12.next();
|
||||
Intrinsics.checkNotNullExpressionValue(objectArrow, "objectArrow");
|
||||
geometry = pbfData.createGeometry((GeneratedMessageV3)objectArrow.getGeometry());
|
||||
geometryEntityx = pbfData.createGeometryEntity(geometry, objectArrow.getAllFields(), (Map)extentMapx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryEntityx, "geometryEntity");
|
||||
geometryEntityx.setLayerEntity(layerEntity);
|
||||
geometryEntityx.setName((String)extentMapx.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)geometryEntityx);
|
||||
Iterator var41 = objectArrow.getLanePidList().iterator();
|
||||
|
||||
while(var41.hasNext()) {
|
||||
String lanLinkPid = (String)var41.next();
|
||||
Iterator var47 = resultData.getHadlanelinkList().iterator();
|
||||
|
||||
while(var47.hasNext()) {
|
||||
Hadlanelink.HadLaneLink lanLink = (Hadlanelink.HadLaneLink)var47.next();
|
||||
Intrinsics.checkNotNullExpressionValue(lanLink, "lanLink");
|
||||
if (lanLinkPid.equals(lanLink.getLaneLinkPid())) {
|
||||
lanLinkGeometry = pbfData.createGeometry((GeneratedMessageV3)lanLink.getGeometry());
|
||||
if (lanLinkGeometry.intersects(geometry)) {
|
||||
intersection = geometry.intersection(lanLinkGeometry);
|
||||
Intrinsics.checkNotNullExpressionValue(intersection, "intersection");
|
||||
if (intersection.isValid() && !intersection.isEmpty() && intersection instanceof LineString) {
|
||||
HashMap extentMap = new HashMap();
|
||||
((Map)extentMap).put(TYPE, "symbol_object_arrow");
|
||||
((Map)extentMap).put(NAME, "symbol_object_arrow");
|
||||
((Map)extentMap).put("arrow_class", String.valueOf(objectArrow.getArrowClass()));
|
||||
GeometryFeatureEntity geometryEntityxx = pbfData.createGeometryEntity(intersection, (Map)null, (Map)extentMap);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryEntityxx, "geometryEntity");
|
||||
geometryEntityxx.setLayerEntity(layerEntity);
|
||||
geometryEntityxx.setName((String)extentMap.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)geometryEntityxx);
|
||||
}
|
||||
continue label141;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var40 = resultData.getObjectcrosswalkList();
|
||||
Intrinsics.checkNotNullExpressionValue(var40, "resultData.objectcrosswalkList");
|
||||
var9 = (Collection)var40;
|
||||
if (!var9.isEmpty()) {
|
||||
layerEntity = new LayerEntity();
|
||||
layerEntity.setLayerName("test");
|
||||
extentMapx = new HashMap();
|
||||
((Map)extentMapx).put(NAME, "人行横道");
|
||||
((Map)extentMapx).put(TYPE, "object_crosswalk");
|
||||
var12 = resultData.getObjectcrosswalkList().iterator();
|
||||
|
||||
while(var12.hasNext()) {
|
||||
Objectcrosswalk.ObjectCrossWalk objectCross = (Objectcrosswalk.ObjectCrossWalk)var12.next();
|
||||
Intrinsics.checkNotNullExpressionValue(objectCross, "objectCross");
|
||||
geometry = pbfData.createGeometry((GeneratedMessageV3)objectCross.getGeometry());
|
||||
geometryEntityx = pbfData.createGeometryEntity(geometry, objectCross.getAllFields(), (Map)extentMapx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryEntityx, "geometryEntity");
|
||||
geometryEntityx.setLayerEntity(layerEntity);
|
||||
geometryEntityx.setName((String)extentMapx.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)geometryEntityx);
|
||||
}
|
||||
}
|
||||
|
||||
var40 = resultData.getObjectpoleList();
|
||||
Intrinsics.checkNotNullExpressionValue(var40, "resultData.objectpoleList");
|
||||
var9 = (Collection)var40;
|
||||
HashMap extentMap3D;
|
||||
Iterator var36;
|
||||
Geometry geometryx;
|
||||
GeometryFeatureEntity geometryEntityxxx;
|
||||
GeometryFeatureEntity symbolEntity;
|
||||
if (!var9.isEmpty()) {
|
||||
layerEntity = new LayerEntity();
|
||||
layerEntity.setLayerName("test");
|
||||
extentMapx = new HashMap();
|
||||
((Map)extentMapx).put(NAME, "杆状物");
|
||||
((Map)extentMapx).put(TYPE, "object_pole");
|
||||
extentMap3D = new HashMap();
|
||||
((Map)extentMap3D).put(TYPE, "symbol_object_pole");
|
||||
((Map)extentMap3D).put(NAME, "symbol_object_pole");
|
||||
var36 = resultData.getObjectpoleList().iterator();
|
||||
|
||||
while(var36.hasNext()) {
|
||||
Objectpole.ObjectPole objectPole = (Objectpole.ObjectPole)var36.next();
|
||||
Intrinsics.checkNotNullExpressionValue(objectPole, "objectPole");
|
||||
geometryx = pbfData.createGeometry((GeneratedMessageV3)objectPole.getGeometry());
|
||||
geometryEntityxxx = pbfData.createGeometryEntity(geometryx, objectPole.getAllFields(), (Map)extentMapx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryEntityxxx, "geometryEntity");
|
||||
geometryEntityxxx.setLayerEntity(layerEntity);
|
||||
geometryEntityxxx.setName((String)extentMapx.get(TYPE));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)geometryEntityxxx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryx, "geometry");
|
||||
symbolEntity = pbfData.createGeometryEntity((Geometry)geometryx.getCentroid(), (Map)null, (Map)extentMap3D);
|
||||
Intrinsics.checkNotNullExpressionValue(symbolEntity, "symbolEntity");
|
||||
symbolEntity.setLayerEntity(layerEntity);
|
||||
symbolEntity.setName((String)extentMap3D.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)symbolEntity);
|
||||
}
|
||||
}
|
||||
|
||||
var40 = resultData.getObjectsymbolList();
|
||||
Intrinsics.checkNotNullExpressionValue(var40, "resultData.objectsymbolList");
|
||||
var9 = (Collection)var40;
|
||||
if (!var9.isEmpty()) {
|
||||
layerEntity = new LayerEntity();
|
||||
layerEntity.setLayerName("test");
|
||||
extentMapx = new HashMap();
|
||||
((Map)extentMapx).put(NAME, "对象标志");
|
||||
((Map)extentMapx).put(TYPE, "object_symbol");
|
||||
extentMap3D = new HashMap();
|
||||
((Map)extentMap3D).put(NAME, "symbol_object_symbol");
|
||||
((Map)extentMap3D).put(TYPE, "symbol_object_symbol");
|
||||
var36 = resultData.getObjectsymbolList().iterator();
|
||||
|
||||
while(var36.hasNext()) {
|
||||
Objectsymbol.ObjectSymbol objectSymbol = (Objectsymbol.ObjectSymbol)var36.next();
|
||||
Intrinsics.checkNotNullExpressionValue(objectSymbol, "objectSymbol");
|
||||
geometryx = pbfData.createGeometry((GeneratedMessageV3)objectSymbol.getGeometry());
|
||||
geometryEntityxxx = pbfData.createGeometryEntity(geometryx, objectSymbol.getAllFields(), (Map)extentMapx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryEntityxxx, "geometryEntity");
|
||||
geometryEntityxxx.setLayerEntity(layerEntity);
|
||||
geometryEntityxxx.setName((String)extentMapx.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)geometryEntityxxx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryx, "geometry");
|
||||
symbolEntity = pbfData.createGeometryEntity((Geometry)geometryx.getCentroid(), (Map)null, (Map)extentMap3D);
|
||||
Intrinsics.checkNotNullExpressionValue(symbolEntity, "symbolEntity");
|
||||
symbolEntity.setLayerEntity(layerEntity);
|
||||
symbolEntity.setName((String)extentMap3D.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)symbolEntity);
|
||||
}
|
||||
}
|
||||
|
||||
var40 = resultData.getObjecttrafficlightsList();
|
||||
Intrinsics.checkNotNullExpressionValue(var40, "resultData.objecttrafficlightsList");
|
||||
var9 = (Collection)var40;
|
||||
if (!var9.isEmpty()) {
|
||||
layerEntity = new LayerEntity();
|
||||
layerEntity.setLayerName("test");
|
||||
extentMapx = new HashMap();
|
||||
((Map)extentMapx).put(NAME, "交通灯");
|
||||
((Map)extentMapx).put(TYPE, "object_traffic");
|
||||
extentMap3D = new HashMap();
|
||||
((Map)extentMap3D).put(TYPE, "symbol_object_traffic");
|
||||
((Map)extentMap3D).put(NAME, "symbol_object_traffic");
|
||||
var36 = resultData.getObjecttrafficlightsList().iterator();
|
||||
|
||||
while(var36.hasNext()) {
|
||||
Objecttrafficlights.ObjectTrafficLights objectTrrafic = (Objecttrafficlights.ObjectTrafficLights)var36.next();
|
||||
Intrinsics.checkNotNullExpressionValue(objectTrrafic, "objectTrrafic");
|
||||
geometryx = pbfData.createGeometry((GeneratedMessageV3)objectTrrafic.getGeometry());
|
||||
geometryEntityxxx = pbfData.createGeometryEntity(geometryx, objectTrrafic.getAllFields(), (Map)extentMapx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryEntityxxx, "geometryEntity");
|
||||
geometryEntityxxx.setLayerEntity(layerEntity);
|
||||
geometryEntityxxx.setName((String)extentMapx.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)geometryEntityxxx);
|
||||
Intrinsics.checkNotNullExpressionValue(geometryx, "geometry");
|
||||
symbolEntity = pbfData.createGeometryEntity((Geometry)geometryx.getCentroid(), (Map)null, (Map)extentMap3D);
|
||||
Intrinsics.checkNotNullExpressionValue(symbolEntity, "symbolEntity");
|
||||
symbolEntity.setLayerEntity(layerEntity);
|
||||
symbolEntity.setName((String)extentMap3D.get(NAME));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).insertOrUpdate((RealmModel)symbolEntity);
|
||||
}
|
||||
}
|
||||
|
||||
long sqlEndTime = System.currentTimeMillis();
|
||||
System.out.println(file + "All-Time:" + (sqlEndTime - sqlStartTime));
|
||||
}
|
||||
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.getInstance(var10000.getRealmConfiguration()).commitTransaction();
|
||||
long endTime = System.currentTimeMillis();
|
||||
System.out.println("All-Time:" + (endTime - startTime));
|
||||
var10000 = RealmUtils.getInstance();
|
||||
Intrinsics.checkNotNullExpressionValue(var10000, "RealmUtils.getInstance()");
|
||||
Realm.compactRealm(var10000.getRealmConfiguration());
|
||||
System.out.println("Arrow-All-Time: 数据处理结束");
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
resultMap.put("success", true);
|
||||
resultMap.put("msg", "导入成功");
|
||||
resultMap.put("data", (endTime - startTime)+"");
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.navinfo.collect.library.data.dao.impl
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.navinfo.collect.library.data.entity.CheckManager
|
||||
|
||||
@Dao
|
||||
interface ICheckManagerDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg check: CheckManager?)
|
||||
|
||||
@Query("SELECT * FROM CheckManager where id =:id")
|
||||
fun findCheckManagerById(id: Long): CheckManager?
|
||||
|
||||
@Query("SELECT * FROM CheckManager")
|
||||
fun findList(): List<CheckManager>
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.navinfo.collect.library.data.dao.impl;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Update;
|
||||
|
||||
import com.navinfo.collect.library.data.entity.Element;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Dao
|
||||
public interface IElementDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insert(Element... elements);
|
||||
|
||||
@Update
|
||||
int update(Element[] elements);
|
||||
|
||||
@Delete
|
||||
int delete(Element elements);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void inserts(Element[] elements);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insertList(List<Element> elementList);
|
||||
|
||||
@Query("DELETE FROM element")
|
||||
void deleteAll();
|
||||
|
||||
@Query("DELETE FROM element where rowId>:start and rowId<:end")
|
||||
void deleteAll(int start, int end);
|
||||
|
||||
@Query("SELECT * FROM element limit :start,:count")
|
||||
List<Element> findList(int start, int count);
|
||||
|
||||
|
||||
@Query("SELECT * FROM element where 1=1 limit :start,:count ")
|
||||
Element[] findAll(int start, int count);
|
||||
|
||||
|
||||
@Query("SELECT geometry FROM element where rowId>:value limit :start,:count")
|
||||
String[] find(int value, int start, int count);
|
||||
|
||||
@Query("SELECT * FROM element where uuid =:uuid")
|
||||
Element findById(String uuid);
|
||||
|
||||
@Query("SELECT * FROM element where uuid in (select element_uuid from tileElement where tilex>=:minx and tilex<=:maxx and tiley>=:miny and tiley <=:maxy)")
|
||||
List<Element> findList(int minx, int maxx, int miny, int maxy);
|
||||
|
||||
@Query("SELECT * FROM element where uuid in (select distinct element_uuid from tileElement where tilex IN (:xList) and tiley IN (:yList))")
|
||||
List<Element> findList(Set<Integer> xList, Set<Integer> yList);
|
||||
|
||||
@Query("SELECT * FROM element where display_text like '%'||:keyword||'%' limit :start,:count")
|
||||
List<Element> findListByKeyword(String keyword, int start, int count);
|
||||
|
||||
|
||||
@Query("SELECT * FROM element where display_text like '%'||:keyword||'%' and layer_id in (:layerIds) limit :start,:count")
|
||||
List<Element> findListByKeywordLimitLayer(String keyword, Set<String> layerIds, int start, int count);
|
||||
|
||||
@Query("SELECT * FROM element where display_text like '%'||:keyword||'%' and layer_id in (Select uuid from layerManager where project_id in (:projectIds)) limit :start,:count")
|
||||
List<Element> findListByKeywordLimitProject(String keyword, Set<String> projectIds, int start, int count);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.navinfo.collect.library.data.dao.impl;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Update;
|
||||
|
||||
import com.navinfo.collect.library.data.entity.Element;
|
||||
import com.navinfo.collect.library.data.entity.LayerManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Dao
|
||||
public interface ILayerManagerDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insert(LayerManager... layerManagers);
|
||||
|
||||
@Update
|
||||
int updates(LayerManager[] layerManagers);
|
||||
|
||||
@Update
|
||||
int update(LayerManager layerManagers);
|
||||
|
||||
@Delete
|
||||
int delete(LayerManager layerManagers);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void inserts(LayerManager[] layerManagers);
|
||||
|
||||
@Query("DELETE FROM layerManager")
|
||||
void deleteAll();
|
||||
|
||||
@Query("DELETE FROM layerManager where rowId>:start and rowId<:end")
|
||||
void deleteAll(int start, int end);
|
||||
|
||||
@Query("SELECT * FROM layerManager where visibility =:visable")
|
||||
List<LayerManager> findList(int visable);
|
||||
|
||||
@Query("SELECT * FROM layerManager")
|
||||
List<LayerManager> findList();
|
||||
|
||||
@Query("SELECT * FROM layerManager where project_id in(:projectIds)")
|
||||
List<LayerManager> findListByProject(Set<String> projectIds);
|
||||
|
||||
@Query("SELECT * FROM layerManager where uuid =:id")
|
||||
LayerManager findLayerManager(String id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.navinfo.collect.library.data.dao.impl;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Update;
|
||||
|
||||
import com.navinfo.collect.library.data.entity.Element;
|
||||
import com.navinfo.collect.library.data.entity.NiLocation;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Dao
|
||||
public interface INiLocationDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insert(NiLocation... niLocations);
|
||||
|
||||
@Update
|
||||
int update(NiLocation niLocation);
|
||||
|
||||
@Update
|
||||
int updateList(NiLocation[] niLocations);
|
||||
|
||||
@Delete
|
||||
int delete(NiLocation niLocations);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void inserts(NiLocation[] niLocations);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insertList(List<NiLocation> niLocationList);
|
||||
|
||||
@Query("DELETE FROM niLocation")
|
||||
void deleteAll();
|
||||
|
||||
@Query("SELECT * FROM niLocation where uuid=:id ")
|
||||
NiLocation find(String id);
|
||||
|
||||
@Query("SELECT * FROM niLocation where tilex>=:minx and tilex<=:maxx and tiley>=:miny and tiley <=:maxy")
|
||||
List<NiLocation> findList(int minx, int maxx, int miny, int maxy);
|
||||
|
||||
@Query("SELECT * FROM niLocation where tilex>=:minx and tilex<=:maxx and tiley>=:miny and tiley <=:maxy and time>=:startTime and time<=:endTime")
|
||||
List<NiLocation> timeTofindList(int minx, int maxx, int miny, int maxy,long startTime,long endTime);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
//package com.navinfo.collect.library.data.dao.impl;
|
||||
//
|
||||
//import androidx.room.Dao;
|
||||
//import androidx.room.Delete;
|
||||
//import androidx.room.Insert;
|
||||
//import androidx.room.OnConflictStrategy;
|
||||
//import androidx.room.Query;
|
||||
//import androidx.room.Update;
|
||||
//import com.navinfo.collect.library.data.entity.Project;
|
||||
//import java.util.List;
|
||||
//
|
||||
//@Dao
|
||||
//public interface IProjectDao {
|
||||
// @Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
// void insert(Project... projects);
|
||||
//
|
||||
// @Update
|
||||
// int update(Project[] projects);
|
||||
//
|
||||
// @Delete
|
||||
// int delete(Project projects);
|
||||
//
|
||||
// @Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
// void inserts(Project[] projects);
|
||||
//
|
||||
// @Query("DELETE FROM project")
|
||||
// void deleteAll();
|
||||
//
|
||||
// @Query("DELETE FROM project where rowId>:start and rowId<:end")
|
||||
// void deleteAll(int start, int end);
|
||||
//
|
||||
// @Query("SELECT * FROM project")
|
||||
// List<Project> findList();
|
||||
//
|
||||
// @Query("SELECT * FROM project where uuid =:id")
|
||||
// Project findProject(String id);
|
||||
//}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.navinfo.collect.library.data.dao.impl;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Update;
|
||||
|
||||
import com.navinfo.collect.library.data.entity.Project;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Dao
|
||||
public interface IProjectManagerDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insert(Project... projects);
|
||||
|
||||
@Update
|
||||
int update(Project[] projects);
|
||||
|
||||
@Delete
|
||||
int delete(Project project);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void inserts(Project[] projects);
|
||||
|
||||
@Query("DELETE FROM project")
|
||||
void deleteAll();
|
||||
|
||||
@Query("SELECT * FROM project where project_visibility =:visable")
|
||||
List<Project> findList(int visable);
|
||||
|
||||
@Query("SELECT * FROM project")
|
||||
List<Project> findList();
|
||||
|
||||
@Query("SELECT * FROM project where uuid =:id")
|
||||
Project findProject(String id);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.navinfo.collect.library.data.dao.impl;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Update;
|
||||
import com.navinfo.collect.library.data.entity.LayerManager;
|
||||
import com.navinfo.collect.library.data.entity.TileElement;
|
||||
import java.util.List;
|
||||
|
||||
@Dao
|
||||
public interface ITileElementDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insert(TileElement... tileElements);
|
||||
|
||||
@Update
|
||||
int update(TileElement[] tileElements);
|
||||
|
||||
@Delete
|
||||
int delete(TileElement tileElements);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void inserts(TileElement[] tileElements);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insertList(List<TileElement> tileElementList);
|
||||
|
||||
@Query("DELETE FROM tileElement")
|
||||
void deleteAll();
|
||||
|
||||
@Query("DELETE FROM tileElement where element_uuid =:elementId")
|
||||
void deleteElementId(String elementId);
|
||||
|
||||
@Query("DELETE FROM tileElement where rowId>:start and rowId<:end")
|
||||
void deleteAll(int start,int end);
|
||||
|
||||
@Query("SELECT * FROM tileElement where element_uuid =:elementId")
|
||||
List<TileElement> getElementIdList(String elementId);
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package com.navinfo.collect.library.data.dao.impl;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.Database;
|
||||
import androidx.room.Room;
|
||||
import androidx.room.RoomDatabase;
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||
|
||||
import com.navinfo.collect.library.data.entity.CheckManager;
|
||||
import com.navinfo.collect.library.data.entity.Element;
|
||||
import com.navinfo.collect.library.data.entity.LayerManager;
|
||||
import com.navinfo.collect.library.data.entity.NiLocation;
|
||||
import com.navinfo.collect.library.data.entity.Project;
|
||||
import com.navinfo.collect.library.data.entity.TileElement;
|
||||
import com.tencent.wcdb.database.SQLiteCipherSpec;
|
||||
import com.tencent.wcdb.database.SQLiteDatabase;
|
||||
|
||||
import com.tencent.wcdb.room.db.WCDBOpenHelperFactory;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import com.tencent.wcdb.repair.BackupKit;
|
||||
import com.tencent.wcdb.repair.RecoverKit;
|
||||
import com.tencent.wcdb.room.db.WCDBDatabase;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Database(entities = {Element.class, TileElement.class, LayerManager.class, Project.class, NiLocation.class, CheckManager.class},version = 1, exportSchema = false)
|
||||
public abstract class MapLifeDataBase extends RoomDatabase {
|
||||
// marking the instance as volatile to ensure atomic access to the variable
|
||||
/**
|
||||
* 数据库单例对象
|
||||
*/
|
||||
private static volatile MapLifeDataBase INSTANCE;
|
||||
|
||||
/**
|
||||
* 要素数据库类
|
||||
*/
|
||||
public abstract IElementDao getElementDao();
|
||||
|
||||
/**
|
||||
* 地图坐标库类
|
||||
*/
|
||||
public abstract INiLocationDao getNiLocationDao();
|
||||
|
||||
/**
|
||||
* 图层要素数据库类
|
||||
*/
|
||||
public abstract ITileElementDao getTileElementDao();
|
||||
|
||||
/**
|
||||
* 图层数据库类
|
||||
*/
|
||||
|
||||
public abstract ILayerManagerDao getLayerManagerDao();
|
||||
|
||||
/**
|
||||
* 项目管理类
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract IProjectManagerDao getProjectManagerDao();
|
||||
|
||||
/**
|
||||
* 字段检查项
|
||||
*/
|
||||
public abstract ICheckManagerDao getCheckManagerDao();
|
||||
|
||||
/**
|
||||
* 数据库秘钥
|
||||
*/
|
||||
private final static String DB_PASSWORD = "123456";
|
||||
|
||||
public static MapLifeDataBase getDatabase(final Context context, final String name) {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (MapLifeDataBase.class) {
|
||||
if (INSTANCE == null) {
|
||||
// [WCDB] To use Room library with WCDB, pass a WCDBOpenHelper factory object
|
||||
// to the database builder with .openHelperFactory(...). In the factory object,
|
||||
// you can specify passphrase and cipher options to open or create encrypted
|
||||
// database, as well as optimization options like asynchronous checkpoint.
|
||||
SQLiteCipherSpec cipherSpec = new SQLiteCipherSpec()
|
||||
.setPageSize(1024)
|
||||
.setSQLCipherVersion(3);
|
||||
WCDBOpenHelperFactory factory = new WCDBOpenHelperFactory()
|
||||
.passphrase(DB_PASSWORD.getBytes()) // passphrase to the database, remove this line for plain-text
|
||||
.cipherSpec(cipherSpec) // cipher to use, remove for default settings
|
||||
.writeAheadLoggingEnabled(true) // enable WAL mode, remove if not needed
|
||||
.asyncCheckpointEnabled(true); // enable asynchronous checkpoint, remove if not needed
|
||||
|
||||
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
|
||||
MapLifeDataBase.class, name)
|
||||
|
||||
// [WCDB] Specify open helper to use WCDB database implementation instead
|
||||
// of the Android framework.
|
||||
.openHelperFactory(factory)
|
||||
|
||||
// Wipes and rebuilds instead of migrating if no Migration object.
|
||||
// Migration is not part of this codelab.
|
||||
.fallbackToDestructiveMigration()
|
||||
.addCallback(sRoomDatabaseCallback)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the onOpen method to populate the database.
|
||||
* For this sample, we clear the database every time it is created or opened.
|
||||
* <p>
|
||||
* If you want to populate the database only when the database is created for the 1st time,
|
||||
* override RoomDatabase.Callback()#onCreate
|
||||
*/
|
||||
private static RoomDatabase.Callback sRoomDatabaseCallback = new RoomDatabase.Callback() {
|
||||
|
||||
@Override
|
||||
public void onOpen(@NonNull SupportSQLiteDatabase db) {
|
||||
super.onOpen(db);
|
||||
// If you want to keep the data through app restarts,
|
||||
// comment out the following line.
|
||||
new PopulateDbAsync(INSTANCE).execute();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Populate the database in the background.
|
||||
* If you want to start with more words, just add them.
|
||||
*/
|
||||
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private final ILayerManagerDao mLayerDao;
|
||||
|
||||
PopulateDbAsync(MapLifeDataBase db) {
|
||||
mLayerDao = db.getLayerManagerDao();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(final Void... params) {
|
||||
// Start the app with a clean database every time.
|
||||
// Not needed if you only populate on creation.
|
||||
//mDao.deleteAll();
|
||||
Log.e("qj", "doInBackground");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据恢复
|
||||
*/
|
||||
protected boolean recoverData(){
|
||||
if(INSTANCE!=null){
|
||||
SQLiteDatabase sqlite = ((WCDBDatabase) INSTANCE.getOpenHelper().getWritableDatabase()).getInnerDatabase();
|
||||
RecoverKit recover = new RecoverKit(
|
||||
sqlite, // 要恢复到的目标 DB
|
||||
sqlite.getPath() + "-backup", // 备份文件
|
||||
DB_PASSWORD.getBytes() // 加密备份文件的密钥,非 DB 密钥
|
||||
);
|
||||
int result = recover.run(false); // fatal 参数传 false 表示遇到错误忽略并继续,
|
||||
// 若传 true 遇到错误则中止并返回 FAILED
|
||||
switch (result) {
|
||||
case RecoverKit.RESULT_OK:
|
||||
/* 成功 */
|
||||
Log.e("qj","sRoomDatabaseCallback==RecoverKit成功");
|
||||
return true;
|
||||
case RecoverKit.RESULT_CANCELED: /* 取消操作 */
|
||||
Log.e("qj","sRoomDatabaseCallback==RecoverKit取消操作");
|
||||
break;
|
||||
case RecoverKit.RESULT_FAILED: /* 失败 */
|
||||
Log.e("qj","sRoomDatabaseCallback==RecoverKit失败");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
recover.release();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份数据
|
||||
*/
|
||||
protected boolean backup() {
|
||||
Log.e("qj", "sRoomDatabaseCallback===backup==start");
|
||||
if (INSTANCE != null) {
|
||||
//备份文件
|
||||
SQLiteDatabase sqlite = ((WCDBDatabase) INSTANCE.getOpenHelper().getWritableDatabase()).getInnerDatabase();
|
||||
BackupKit backup = new BackupKit(
|
||||
sqlite, // 要备份的 DB
|
||||
sqlite.getPath() + "-backup", // 备份文件
|
||||
"123456".getBytes(), // 加密备份文件的密钥,非 DB 密钥
|
||||
0, null);
|
||||
int result = backup.run();
|
||||
switch (result) {
|
||||
case BackupKit.RESULT_OK:
|
||||
/* 成功 */
|
||||
Log.e("qj", "sRoomDatabaseCallback==成功");
|
||||
return true;
|
||||
case BackupKit.RESULT_CANCELED:
|
||||
/* 取消操作 */
|
||||
Log.e("qj", "sRoomDatabaseCallback==取消操作");
|
||||
break;
|
||||
case BackupKit.RESULT_FAILED:
|
||||
/* 失败 */
|
||||
Log.e("qj", "sRoomDatabaseCallback==失败");
|
||||
break;
|
||||
}
|
||||
|
||||
backup.release();
|
||||
}
|
||||
Log.e("qj", "sRoomDatabaseCallback===backup==end");
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void release() {
|
||||
INSTANCE = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.navinfo.collect.library.data.db;
|
||||
|
||||
import androidx.room.RoomDatabase;
|
||||
|
||||
public abstract class CipherDataBase extends RoomDatabase {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.navinfo.collect.library.data.db;
|
||||
|
||||
public interface GeometryDao {
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.navinfo.collect.library.data.db;
|
||||
|
||||
import com.navinfo.collect.library.utils.GeometryTools;
|
||||
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GeometryEntity {
|
||||
private String id = UUID.randomUUID().toString();
|
||||
private String name;
|
||||
private String geometry;
|
||||
private String layerName;
|
||||
private String style;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getGeometry() {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
public void setGeometry(String wkt) {
|
||||
if (wkt == null||wkt.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Geometry geometry = GeometryTools.createGeometry(wkt);
|
||||
setGeometry(geometry);
|
||||
}
|
||||
|
||||
public void setGeometry(Geometry geometry) {
|
||||
this.geometry = geometry.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.navinfo.collect.library.data.db;
|
||||
|
||||
public class GeometryProperties {
|
||||
public String key;
|
||||
public String value;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.navinfo.collect.library.data.db;
|
||||
|
||||
public class GeometryTile {
|
||||
public int tileX;
|
||||
public int tileY;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.navinfo.collect.library.data.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "CheckManager")
|
||||
class CheckManager(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0,
|
||||
//检查项类型
|
||||
val type: Int,
|
||||
//检查项名称
|
||||
val tag: String,
|
||||
//检查项正则内容
|
||||
val regexStr: String
|
||||
|
||||
) {
|
||||
fun toJson(): String {
|
||||
return "{\"id\":$id,\"type\":$type,\"tag\":\"$tag\",\"regexStr\":\"$regexStr\"}"
|
||||
}
|
||||
|
||||
fun toMap(): Map<String, *> {
|
||||
return return mapOf("id" to id, "type" to type, "tag" to tag, "regexStr" to regexStr)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.navinfo.collect.library.data.entity
|
||||
|
||||
|
||||
enum class DataLayerItemType {
|
||||
///未知类型
|
||||
DataLayerItemTypeUnKnow,
|
||||
|
||||
///输入框
|
||||
DataLayerItemTypeInput,
|
||||
|
||||
///输入框集合
|
||||
DataLayerItemTypeInputArray,
|
||||
|
||||
///纯展示文本
|
||||
DataLayerItemTypeText,
|
||||
|
||||
///单选框
|
||||
DataLayerItemTypeSingleSelection,
|
||||
|
||||
///多选框
|
||||
DataLayerItemTypeMultipleSelection,
|
||||
|
||||
///照片
|
||||
DataLayerItemTypePhoto,
|
||||
|
||||
///多级菜单
|
||||
DataLayerItemTypeMultiLevelMenu
|
||||
}
|
||||
|
||||
data class CustomLayerItem(
|
||||
///对应的数据库字段名称
|
||||
val key: String,
|
||||
///用来显示控件名称
|
||||
val title: String = key,
|
||||
///控件类型
|
||||
val type: DataLayerItemType,
|
||||
///非必填项
|
||||
// val nullable: Boolean = true,
|
||||
///是不是主键
|
||||
// val primaryKey: Boolean = false,
|
||||
///默认值
|
||||
// var value: Any,
|
||||
///多选或单选的内容,如果 [isSelect] 为 false 可忽略这字段
|
||||
// var selectOptions: String,
|
||||
///是否是主名称属性,设置为true,地图上会已该字段内容渲染
|
||||
// val isMainName: Boolean = false,
|
||||
///简介
|
||||
val describe: String,
|
||||
val itemBean: String,
|
||||
///检查项
|
||||
// val checkManagerList: List<CheckManager>,
|
||||
) {
|
||||
|
||||
fun toMap(): Map<String, *> {
|
||||
// val checkManagerMapList = mutableListOf<Map<String, *>>()
|
||||
// for (check in checkManagerList) {
|
||||
// checkManagerMapList.add(check.toMap())
|
||||
// }
|
||||
return mapOf(
|
||||
"key" to key,
|
||||
"title" to title,
|
||||
"type" to type.ordinal,
|
||||
// "nullable" to nullable,
|
||||
// "primaryKey" to primaryKey,
|
||||
// "value" to value,
|
||||
// "selectOptions" to selectOptions,
|
||||
// "isMainName" to isMainName,
|
||||
"describe" to describe,
|
||||
// "checkManagerList" to checkManagerMapList,
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
// fun fromJson(json:JSONObject): CustomLayerItem {
|
||||
// return CustomLayerItem()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//class DataLayerItemTypeAdapter {
|
||||
// @ToJson
|
||||
// fun toJson(enum: DataLayerItemType): Int {
|
||||
// return enum.ordinal;
|
||||
// }
|
||||
//
|
||||
// @FromJson
|
||||
// fun fromJson(type: Int): DataLayerItemType {
|
||||
// return DataLayerItemType.values()[type];
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Index;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class DataBase extends Feature {
|
||||
|
||||
@ColumnInfo(name = "geometry")
|
||||
private String geometry;
|
||||
|
||||
|
||||
public String getGeometry() {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
public void setGeometry(String geometry) {
|
||||
this.geometry = geometry;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Ignore;
|
||||
import androidx.room.Index;
|
||||
|
||||
import com.google.protobuf.Any;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author qj
|
||||
* @version V1.0
|
||||
* @ClassName: Element
|
||||
* @Date 2022/4/14
|
||||
* @Description: ${Element}(要素数据)
|
||||
*/
|
||||
//@Entity(tableName = "element",indices = {@Index("visibility"),@Index(value = {"maxx", "minx", "maxy", "miny"})})
|
||||
@Entity(tableName = "element", indices = {@Index("visibility")})
|
||||
public class Element extends DataBase {
|
||||
|
||||
@ColumnInfo(name = "layer_id")
|
||||
private String LayerId;
|
||||
|
||||
@ColumnInfo(name = "display_style")
|
||||
private String DisplayStyle;
|
||||
|
||||
@ColumnInfo(name = "display_text")
|
||||
private String DisplayText;
|
||||
|
||||
@ColumnInfo(name = "start_level")
|
||||
private int StartLevel;
|
||||
|
||||
@ColumnInfo(name = "end_level")
|
||||
private int EndLevel;
|
||||
|
||||
@ColumnInfo(name = "zindex")
|
||||
private int ZIndex;
|
||||
|
||||
@ColumnInfo(name = "visibility")
|
||||
private int Visibility;
|
||||
|
||||
@ColumnInfo(name = "operation_time")
|
||||
private String OperationTime;
|
||||
|
||||
@ColumnInfo(name = "export_time")
|
||||
private String ExportTime;
|
||||
|
||||
@ColumnInfo(name = "t_lifecycle")
|
||||
private int TLifecycle;
|
||||
|
||||
@ColumnInfo(name = "t_status")
|
||||
private int TStatus;
|
||||
|
||||
@Ignore
|
||||
private Map<String, String> values;
|
||||
|
||||
public Map<String, String> getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public void setValues(Map<String, String> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public String getLayerId() {
|
||||
return LayerId;
|
||||
}
|
||||
|
||||
public void setLayerId(String layerId) {
|
||||
this.LayerId = layerId;
|
||||
}
|
||||
|
||||
public String getDisplayStyle() {
|
||||
return DisplayStyle;
|
||||
}
|
||||
|
||||
public void setDisplayStyle(String displayStyle) {
|
||||
DisplayStyle = displayStyle;
|
||||
}
|
||||
|
||||
public String getDisplayText() {
|
||||
return DisplayText;
|
||||
}
|
||||
|
||||
public void setDisplayText(String displayText) {
|
||||
DisplayText = displayText;
|
||||
}
|
||||
|
||||
public int getStartLevel() {
|
||||
return StartLevel;
|
||||
}
|
||||
|
||||
public void setStartLevel(int startLevel) {
|
||||
StartLevel = startLevel;
|
||||
}
|
||||
|
||||
public int getEndLevel() {
|
||||
return EndLevel;
|
||||
}
|
||||
|
||||
public void setEndLevel(int endLevel) {
|
||||
EndLevel = endLevel;
|
||||
}
|
||||
|
||||
public int getZIndex() {
|
||||
return ZIndex;
|
||||
}
|
||||
|
||||
public void setZIndex(int ZIndex) {
|
||||
this.ZIndex = ZIndex;
|
||||
}
|
||||
|
||||
public int getVisibility() {
|
||||
return Visibility;
|
||||
}
|
||||
|
||||
public void setVisibility(int visibility) {
|
||||
Visibility = visibility;
|
||||
}
|
||||
|
||||
public String getOperationTime() {
|
||||
return OperationTime;
|
||||
}
|
||||
|
||||
public void setOperationTime(String operationTime) {
|
||||
OperationTime = operationTime;
|
||||
}
|
||||
|
||||
public String getExportTime() {
|
||||
return ExportTime;
|
||||
}
|
||||
|
||||
public void setExportTime(String exportTime) {
|
||||
ExportTime = exportTime;
|
||||
}
|
||||
|
||||
public int getTLifecycle() {
|
||||
return TLifecycle;
|
||||
}
|
||||
|
||||
public void setTLifecycle(int TLifecycle) {
|
||||
this.TLifecycle = TLifecycle;
|
||||
}
|
||||
|
||||
public int getTStatus() {
|
||||
return TStatus;
|
||||
}
|
||||
|
||||
public void setTStatus(int TStatus) {
|
||||
this.TStatus = TStatus;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public Map toMap() {
|
||||
Map map = new HashMap();
|
||||
map.put("layerId", LayerId);
|
||||
map.put("uuid", getId());
|
||||
map.put("geometry", getGeometry());
|
||||
map.put("displayText", DisplayText);
|
||||
map.put("displayStyle", DisplayStyle);
|
||||
map.put("tOperateDate", OperationTime);
|
||||
map.put("tLifecycle", TLifecycle);
|
||||
map.put("tStatus", TStatus);
|
||||
map.put("values", values);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Element fromMap(Map<String, Object> map) {
|
||||
try {
|
||||
Element element = new Element();
|
||||
element.setLayerId((String) map.get("layerId"));
|
||||
element.setId((String) map.get("uuid"));
|
||||
element.setGeometry((String) map.get("geometry"));
|
||||
element.setDisplayText((String) map.get("displayText"));
|
||||
element.setDisplayStyle((String) map.get("displayStyle"));
|
||||
element.setOperationTime((String) map.get("tOperateDate"));
|
||||
element.setTLifecycle((Integer) map.get("tLifecycle"));
|
||||
element.setTStatus((Integer) map.get("tStatus"));
|
||||
return element;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Element fromJson(String json) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(json);
|
||||
return fromJson(jsonObject);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Element fromJson(JSONObject jsonObject) {
|
||||
Element element = new Element();
|
||||
element.setLayerId(jsonObject.optString("layerId"));
|
||||
element.setId(jsonObject.optString("uuid"));
|
||||
element.setGeometry(jsonObject.optString("geometry"));
|
||||
element.setDisplayText(jsonObject.optString("displayText"));
|
||||
element.setDisplayStyle(jsonObject.optString("displayStyle"));
|
||||
element.setOperationTime(jsonObject.optString("tOperateDate"));
|
||||
element.setTLifecycle(jsonObject.optInt("tLifecycle"));
|
||||
element.setTStatus(jsonObject.optInt("tStatus"));
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author qj
|
||||
* @version V1.0
|
||||
* @ClassName: Feature
|
||||
* @Date 2022/4/14
|
||||
* @Description: ${TODO}(数据基类)
|
||||
*/
|
||||
public class Feature implements Serializable, Cloneable {
|
||||
// //主键
|
||||
// @PrimaryKey(autoGenerate = true)
|
||||
// public int rowId;
|
||||
|
||||
@PrimaryKey()
|
||||
@ColumnInfo(name = "uuid")
|
||||
@NonNull
|
||||
private String id = UUID.randomUUID().toString();
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import com.navinfo.collect.library.system.Constant;
|
||||
import com.navinfo.collect.library.utils.GeometryTools;
|
||||
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.Envelope;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.oscim.core.MercatorProjection;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.realm.RealmDictionary;
|
||||
import io.realm.RealmObject;
|
||||
import io.realm.RealmSet;
|
||||
import io.realm.annotations.PrimaryKey;
|
||||
import io.realm.annotations.Required;
|
||||
|
||||
public class GeometryFeatureEntity extends RealmObject implements Cloneable {
|
||||
@PrimaryKey
|
||||
private String id = UUID.randomUUID().toString();
|
||||
private String name;
|
||||
@Required
|
||||
private String geometry;
|
||||
private byte[] wkb;
|
||||
private double xmax;
|
||||
private double xmin;
|
||||
private double ymax;
|
||||
private double ymin;
|
||||
private LayerEntity layerEntity;
|
||||
private RealmSet<Integer> tileX = new RealmSet<>();
|
||||
private RealmSet<Integer> tileY = new RealmSet<>();
|
||||
private RealmDictionary<String> properties = new RealmDictionary<>();
|
||||
private RealmDictionary<String> otherProperties = new RealmDictionary<>();
|
||||
|
||||
public GeometryFeatureEntity() {
|
||||
}
|
||||
|
||||
public GeometryFeatureEntity(String name, String geometry) {
|
||||
this.name = name;
|
||||
this.geometry = geometry;
|
||||
}
|
||||
|
||||
public GeometryFeatureEntity(String name, String geometry, double xmax, double xmin, double ymax, double ymin) {
|
||||
this.name = name;
|
||||
this.geometry = geometry;
|
||||
this.xmax = xmax;
|
||||
this.xmin = xmin;
|
||||
this.ymax = ymax;
|
||||
this.ymin = ymin;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public double getXmax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
public void setXmax(double xmax) {
|
||||
this.xmax = xmax;
|
||||
}
|
||||
|
||||
public double getXmin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
public void setXmin(double xmin) {
|
||||
this.xmin = xmin;
|
||||
}
|
||||
|
||||
public double getYmax() {
|
||||
return ymax;
|
||||
}
|
||||
|
||||
public void setYmax(double ymax) {
|
||||
this.ymax = ymax;
|
||||
}
|
||||
|
||||
public double getYmin() {
|
||||
return ymin;
|
||||
}
|
||||
|
||||
public void setYmin(double ymin) {
|
||||
this.ymin = ymin;
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
if (this.properties == null) {
|
||||
this.properties = new RealmDictionary<>();
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void addProperties(String k, String v) {
|
||||
this.properties.put(k, v);
|
||||
}
|
||||
|
||||
public RealmDictionary<String> getOtherProperties() {
|
||||
if (this.otherProperties == null) {
|
||||
this.otherProperties = new RealmDictionary<>();
|
||||
}
|
||||
return otherProperties;
|
||||
}
|
||||
|
||||
public String getGeometry() {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
public void setGeometry(String wkt) {
|
||||
if (wkt == null||wkt.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Geometry geometry = GeometryTools.createGeometry(wkt);
|
||||
setGeometry(geometry);
|
||||
}
|
||||
|
||||
public void setGeometry(Geometry geometry) {
|
||||
this.geometry = geometry.toString();
|
||||
// 每一次对geometry的更新,都会影响到数据的瓦片编号,记录数据的20级瓦片编号
|
||||
getTileXByGeometry(geometry, tileX);
|
||||
getTileYByGeometry(geometry, tileY);
|
||||
|
||||
Envelope envelope = geometry.getBoundary().getEnvelopeInternal();
|
||||
setXmin(envelope.getMinX());
|
||||
setXmax(envelope.getMaxX());
|
||||
setYmin(envelope.getMinY());
|
||||
setYmax(envelope.getMaxY());
|
||||
}
|
||||
|
||||
public LayerEntity getLayerEntity() {
|
||||
return layerEntity;
|
||||
}
|
||||
|
||||
public void setLayerEntity(LayerEntity layerEntity) {
|
||||
this.layerEntity = layerEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据给定的geometry计算其横跨的20级瓦片X值
|
||||
* */
|
||||
private Set<Integer> getTileXByGeometry(Geometry geometry, Set<Integer> tileXSet) {
|
||||
// long startTime = System.currentTimeMillis();
|
||||
if (tileXSet == null) {
|
||||
tileXSet = new RealmSet<>();
|
||||
}
|
||||
if (geometry!=null) {
|
||||
Geometry envelope = geometry.getEnvelope();
|
||||
if (envelope!=null) {
|
||||
Coordinate[] coordinates = envelope.getCoordinates();
|
||||
// 最小最大x轴坐标,索引0位最小x值,索引1位最大x值
|
||||
if (coordinates!=null&&coordinates.length>0) {
|
||||
double[] minMaxX = new double[]{coordinates[0].x, coordinates[0].x};
|
||||
for (Coordinate coordinate: coordinates) {
|
||||
// 获取最大和最小x的值
|
||||
if (coordinate.x<minMaxX[0]) {
|
||||
minMaxX[0] = coordinate.x;
|
||||
}
|
||||
if (coordinate.x>minMaxX[1]) {
|
||||
minMaxX[1] = coordinate.x;
|
||||
}
|
||||
}
|
||||
// 分别计算最大和最小x值对应的tile号
|
||||
int tileX0 = MercatorProjection.longitudeToTileX(minMaxX[0], (byte) Constant.OVER_ZOOM);
|
||||
int tileX1 = MercatorProjection.longitudeToTileX(minMaxX[1], (byte) Constant.OVER_ZOOM);
|
||||
int minTileX = tileX0 <= tileX1? tileX0: tileX1;
|
||||
int maxTileX = tileX0 <= tileX1? tileX1: tileX0;
|
||||
for (int i = minTileX; i <= maxTileX; i++) {
|
||||
tileXSet.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// System.out.println("XGeometry-time:"+(System.currentTimeMillis()-startTime));
|
||||
return tileXSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据给定的geometry计算其横跨的20级瓦片Y值
|
||||
* */
|
||||
private Set<Integer> getTileYByGeometry(Geometry geometry, Set<Integer> tileYSet) {
|
||||
// long startTime = System.currentTimeMillis();
|
||||
if (tileYSet == null) {
|
||||
tileYSet = new RealmSet<>();
|
||||
}
|
||||
Geometry envelope = geometry.getEnvelope();
|
||||
if (envelope!=null) {
|
||||
Coordinate[] coordinates = envelope.getCoordinates();
|
||||
// 最小最大x轴坐标,索引0位最小x值,索引1位最大y值
|
||||
if (coordinates!=null&&coordinates.length>0) {
|
||||
double[] minMaxY = new double[]{coordinates[0].y, coordinates[0].y};
|
||||
for (Coordinate coordinate: coordinates) {
|
||||
// 获取最大和最小y的值
|
||||
if (coordinate.y<minMaxY[0]) {
|
||||
minMaxY[0] = coordinate.y;
|
||||
}
|
||||
if (coordinate.y>minMaxY[1]) {
|
||||
minMaxY[1] = coordinate.y;
|
||||
}
|
||||
}
|
||||
// 分别计算最大和最小x值对应的tile号
|
||||
int tileY0 = MercatorProjection.latitudeToTileY(minMaxY[0], (byte) Constant.OVER_ZOOM);
|
||||
int tileY1 = MercatorProjection.latitudeToTileY(minMaxY[1], (byte) Constant.OVER_ZOOM);
|
||||
int minTileY = tileY0 <= tileY1? tileY0: tileY1;
|
||||
int maxTileY = tileY0 <= tileY1? tileY1: tileY0;
|
||||
for (int i = minTileY; i <= maxTileY; i++) {
|
||||
tileYSet.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
// System.out.println("YGeometry-time:"+(System.currentTimeMillis()-startTime));
|
||||
return tileYSet;
|
||||
}
|
||||
|
||||
public byte[] getWkb() {
|
||||
return wkb;
|
||||
}
|
||||
|
||||
public void setWkb(byte[] wkb) {
|
||||
this.wkb = wkb;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.TypeConverter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author qj
|
||||
* @version V1.0
|
||||
* @ClassName: GeometryEntity
|
||||
* @Date 2022/4/14
|
||||
* @Description: ${TODO}(几何基类)
|
||||
*/
|
||||
public class GeometryIndexEntity implements Serializable,Cloneable{
|
||||
@ColumnInfo(name = "geometry")
|
||||
private String geometry;
|
||||
@ColumnInfo(name = "xmax")
|
||||
private double xMax;
|
||||
@ColumnInfo(name = "xmin")
|
||||
private double xMin;
|
||||
@ColumnInfo(name = "ymax")
|
||||
private double yMax;
|
||||
@ColumnInfo(name = "ymin")
|
||||
private double yMin;
|
||||
|
||||
public String getGeometry() {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
public void setGeometry(String geometry) {
|
||||
this.geometry = geometry;
|
||||
}
|
||||
|
||||
public double getxMax() {
|
||||
return xMax;
|
||||
}
|
||||
|
||||
public void setxMax(double xMax) {
|
||||
this.xMax = xMax;
|
||||
}
|
||||
|
||||
public double getxMin() {
|
||||
return xMin;
|
||||
}
|
||||
|
||||
public void setxMin(double xMin) {
|
||||
this.xMin = xMin;
|
||||
}
|
||||
|
||||
public double getyMax() {
|
||||
return yMax;
|
||||
}
|
||||
|
||||
public void setyMax(double yMax) {
|
||||
this.yMax = yMax;
|
||||
}
|
||||
|
||||
public double getyMin() {
|
||||
return yMin;
|
||||
}
|
||||
|
||||
public void setyMin(double yMin) {
|
||||
this.yMin = yMin;
|
||||
}
|
||||
|
||||
public GeometryIndexEntity() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.realm.RealmObject;
|
||||
import io.realm.annotations.Ignore;
|
||||
import io.realm.annotations.PrimaryKey;
|
||||
import io.realm.annotations.Required;
|
||||
|
||||
public class LayerEntity extends RealmObject {
|
||||
@Required
|
||||
@PrimaryKey
|
||||
private String layerName;
|
||||
private String fromDataName;
|
||||
private int GeomType;
|
||||
private String layerTableName;
|
||||
@Ignore
|
||||
private List<Geometry> featureList;
|
||||
|
||||
public LayerEntity() {
|
||||
}
|
||||
|
||||
|
||||
public String getLayerName() {
|
||||
return layerName;
|
||||
}
|
||||
|
||||
public void setLayerName(String layerName) {
|
||||
this.layerName = layerName;
|
||||
}
|
||||
|
||||
public String getFromDataName() {
|
||||
return fromDataName;
|
||||
}
|
||||
|
||||
public void setFromDataName(String fromDataName) {
|
||||
this.fromDataName = fromDataName;
|
||||
}
|
||||
|
||||
public int getGeomType() {
|
||||
return GeomType;
|
||||
}
|
||||
|
||||
public void setGeomType(int geomType) {
|
||||
GeomType = geomType;
|
||||
}
|
||||
|
||||
public List<Geometry> getFeatureList() {
|
||||
return featureList;
|
||||
}
|
||||
|
||||
public void setFeatureList(List<Geometry> featureList) {
|
||||
this.featureList = featureList;
|
||||
}
|
||||
|
||||
public String getLayerTableName() {
|
||||
return layerTableName;
|
||||
}
|
||||
|
||||
public void setLayerTableName(String layerTableName) {
|
||||
this.layerTableName = layerTableName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Ignore;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author qj
|
||||
* @version V1.0
|
||||
* @ClassName: LayerManager
|
||||
* @Date 2022/4/14
|
||||
* @Description: ${LayerManager}(图层管理)
|
||||
*/
|
||||
@Entity(tableName = "layerManager")
|
||||
public class LayerManager extends Feature {
|
||||
|
||||
///项目Id
|
||||
@ColumnInfo(name = "project_id")
|
||||
private String projectId;
|
||||
///图层名称
|
||||
@ColumnInfo(name = "layer_name")
|
||||
private String layerName;
|
||||
///图层级别
|
||||
@ColumnInfo(name = "zindex")
|
||||
private int ZIndex;
|
||||
///图层是否显示
|
||||
@ColumnInfo(name = "visibility")
|
||||
private boolean visibility;
|
||||
///导出时间
|
||||
@ColumnInfo(name = "export_time")
|
||||
private String exportTime;
|
||||
///导入时间
|
||||
@ColumnInfo(name = "import_time")
|
||||
private String importTime;
|
||||
@ColumnInfo(name = "bundle")
|
||||
private String bundle;
|
||||
///图层表述信息
|
||||
@ColumnInfo(name = "describe")
|
||||
private String describe;
|
||||
|
||||
///点线面类型
|
||||
@ColumnInfo(name = "geometryType")
|
||||
private int geometryType;
|
||||
|
||||
///来源c
|
||||
@ColumnInfo(name = "source")
|
||||
private String source;
|
||||
|
||||
@ColumnInfo(name = "style")
|
||||
private String style;
|
||||
|
||||
///每个字段的样式和控制条件
|
||||
@Ignore
|
||||
private List<CustomLayerItem> itemList;
|
||||
|
||||
public List<CustomLayerItem> getItemList() {
|
||||
return itemList;
|
||||
}
|
||||
|
||||
public void setItemList(List<CustomLayerItem> itemList) {
|
||||
this.itemList = itemList;
|
||||
}
|
||||
|
||||
public String getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public void setStyle(String style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public void setDescribe(String describe) {
|
||||
this.describe = describe;
|
||||
}
|
||||
|
||||
public String getDescribe() {
|
||||
return describe;
|
||||
}
|
||||
|
||||
public int getGeometryType() {
|
||||
return geometryType;
|
||||
}
|
||||
|
||||
public void setGeometryType(int geometryType) {
|
||||
this.geometryType = geometryType;
|
||||
}
|
||||
|
||||
|
||||
public String getLayerName() {
|
||||
return layerName;
|
||||
}
|
||||
|
||||
public void setLayerName(String layerName) {
|
||||
this.layerName = layerName;
|
||||
}
|
||||
|
||||
public int getZIndex() {
|
||||
return ZIndex;
|
||||
}
|
||||
|
||||
public void setZIndex(int zIndex) {
|
||||
this.ZIndex = zIndex;
|
||||
}
|
||||
|
||||
public boolean getVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
public void setVisibility(boolean visibility) {
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
public String getExportTime() {
|
||||
return exportTime;
|
||||
}
|
||||
|
||||
public void setExportTime(String exportTime) {
|
||||
this.exportTime = exportTime;
|
||||
}
|
||||
|
||||
public String getImportTime() {
|
||||
return importTime;
|
||||
}
|
||||
|
||||
public void setImportTime(String importTime) {
|
||||
this.importTime = importTime;
|
||||
}
|
||||
|
||||
public String getBundle() {
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public void setBundle(String bundle) {
|
||||
this.bundle = bundle;
|
||||
}
|
||||
|
||||
public String getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public void setProjectId(String projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LayerManager{" +
|
||||
"id='" + getId() + '\'' +
|
||||
",projectId='" + projectId + '\'' +
|
||||
", layerName='" + layerName + '\'' +
|
||||
", ZIndex=" + ZIndex +
|
||||
", visibility=" + visibility +
|
||||
", exportTime='" + exportTime + '\'' +
|
||||
", importTime='" + importTime + '\'' +
|
||||
", bundle='" + bundle + '\'' +
|
||||
", describe='" + describe + '\'' +
|
||||
", geometryType='" + geometryType + '\'' +
|
||||
", source='" + source + '\'' +
|
||||
", style='" + style + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public Map toMap() {
|
||||
Map map = new HashMap();
|
||||
map.put("uuid", getId());
|
||||
map.put("layerName", getLayerName());
|
||||
map.put("ZIndex", ZIndex);
|
||||
map.put("visibility", getVisibility());
|
||||
map.put("exportTime", exportTime);
|
||||
map.put("import_time", getImportTime());
|
||||
map.put("describe", getDescribe());
|
||||
map.put("geometryType", getGeometryType());
|
||||
map.put("source", source);
|
||||
map.put("style", style);
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import io.realm.RealmObject;
|
||||
import io.realm.annotations.PrimaryKey;
|
||||
|
||||
public class LayerProperties {
|
||||
private String name;
|
||||
private int fieldType = FieldType.STRING.getTypeCode(); /*默认是字符串类型*/
|
||||
|
||||
public LayerProperties() {
|
||||
}
|
||||
|
||||
public enum FieldType {
|
||||
STRING(0), NUM(1);
|
||||
int typeCode;
|
||||
|
||||
FieldType(int typeCode) {
|
||||
this.typeCode = typeCode;
|
||||
}
|
||||
|
||||
public int getTypeCode() {
|
||||
return typeCode;
|
||||
}
|
||||
|
||||
public FieldType getFieldType(int typeCode) {
|
||||
for (FieldType fieldType: FieldType.values()) {
|
||||
if (fieldType.getTypeCode() == typeCode) {
|
||||
return fieldType;
|
||||
}
|
||||
}
|
||||
return FieldType.STRING;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public FieldType getFieldType() {
|
||||
FieldType fieldType = FieldType.STRING;
|
||||
try {
|
||||
fieldType = fieldType.getFieldType(this.fieldType);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return fieldType;
|
||||
}
|
||||
|
||||
public void setFieldType(FieldType fieldType) {
|
||||
this.fieldType = fieldType.typeCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Index;
|
||||
|
||||
/**
|
||||
* 表示地图的地理位置类。
|
||||
*/
|
||||
@Entity(tableName = "niLocation", indices = {@Index("tilex"),@Index("tiley")})
|
||||
public class NiLocation extends Feature{
|
||||
@ColumnInfo(name = "longitude")
|
||||
private double longitude;//纬度坐标
|
||||
@ColumnInfo(name = "latitude")
|
||||
private double latitude;//经度坐标
|
||||
@ColumnInfo(name = "direction")
|
||||
private double direction;//定位方位
|
||||
@ColumnInfo(name = "altitude")
|
||||
private double altitude;//海拔高度 如果返回0.0,说明没有返回海拔高度
|
||||
@ColumnInfo(name = "radius")
|
||||
private double radius;//定位精度
|
||||
@ColumnInfo(name = "time")
|
||||
private String time;//定位时间 毫秒时间(距离1970年 1月 1日 00:00:00 GMT的时间)
|
||||
@ColumnInfo(name = "adCode")
|
||||
private String adCode;// 区域编码
|
||||
@ColumnInfo(name = "country")
|
||||
private String country;// 所属国家
|
||||
@ColumnInfo(name = "province")
|
||||
private String province;// 所属省名称
|
||||
@ColumnInfo(name = "city")
|
||||
private String city;// 所属城市名称
|
||||
@ColumnInfo(name = "district")
|
||||
private String district;// 所属区(县)名称
|
||||
@ColumnInfo(name = "cityCode")
|
||||
private String cityCode;// 城市编码
|
||||
@ColumnInfo(name = "provider")
|
||||
private String provider;// 提供者名称
|
||||
@ColumnInfo(name = "speed")
|
||||
private float speed;// 定位速度
|
||||
@ColumnInfo(name = "floor")
|
||||
private String floor;// 楼层
|
||||
@ColumnInfo(name = "poiId")
|
||||
private String poiId;// 室内地图POI的id
|
||||
@ColumnInfo(name = "satelliteNumber")
|
||||
private int satelliteNumber;// 卫星数目
|
||||
@ColumnInfo(name = "address")
|
||||
private String address;// 地址
|
||||
@ColumnInfo(name = "street")
|
||||
private String street;// 乡镇
|
||||
@ColumnInfo(name = "town")
|
||||
private String town;// 街道
|
||||
@ColumnInfo(name = "streetNumber")
|
||||
private String streetNumber;// 街道号码
|
||||
@ColumnInfo(name = "errorInfo")
|
||||
private String errorInfo;// 定位失败描述信息
|
||||
@ColumnInfo(name = "errorCode")
|
||||
private String errorCode;// 错误码
|
||||
@ColumnInfo(name = "tilex")
|
||||
private int tilex;
|
||||
@ColumnInfo(name = "tiley")
|
||||
private int tiley;
|
||||
private boolean isAccouracy;
|
||||
private boolean isSpeed;
|
||||
private boolean isAltitude;
|
||||
private boolean isBearing;
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public void setLatitude(double latitude) {
|
||||
this.latitude = latitude;
|
||||
}
|
||||
|
||||
public double getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setDirection(double direction) {
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public double getAltitude() {
|
||||
return altitude;
|
||||
}
|
||||
|
||||
public void setAltitude(double altitude) {
|
||||
this.altitude = altitude;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public void setRadius(double radius) {
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(String time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getAdCode() {
|
||||
return adCode;
|
||||
}
|
||||
|
||||
public void setAdCode(String adCode) {
|
||||
this.adCode = adCode;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getDistrict() {
|
||||
return district;
|
||||
}
|
||||
|
||||
public void setDistrict(String district) {
|
||||
this.district = district;
|
||||
}
|
||||
|
||||
public String getCityCode() {
|
||||
return cityCode;
|
||||
}
|
||||
|
||||
public void setCityCode(String cityCode) {
|
||||
this.cityCode = cityCode;
|
||||
}
|
||||
|
||||
public String getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
public void setProvider(String provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
public void setSpeed(float speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
public String getFloor() {
|
||||
return floor;
|
||||
}
|
||||
|
||||
public void setFloor(String floor) {
|
||||
this.floor = floor;
|
||||
}
|
||||
|
||||
public String getPoiId() {
|
||||
return poiId;
|
||||
}
|
||||
|
||||
public void setPoiId(String poiId) {
|
||||
this.poiId = poiId;
|
||||
}
|
||||
|
||||
public int getSatelliteNumber() {
|
||||
return satelliteNumber;
|
||||
}
|
||||
|
||||
public void setSatelliteNumber(int satelliteNumber) {
|
||||
this.satelliteNumber = satelliteNumber;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public boolean isAccouracy() {
|
||||
return isAccouracy;
|
||||
}
|
||||
|
||||
public void setAccouracy(boolean accouracy) {
|
||||
isAccouracy = accouracy;
|
||||
}
|
||||
|
||||
public boolean isSpeed() {
|
||||
return isSpeed;
|
||||
}
|
||||
|
||||
public void setSpeed(boolean speed) {
|
||||
isSpeed = speed;
|
||||
}
|
||||
|
||||
public boolean isAltitude() {
|
||||
return isAltitude;
|
||||
}
|
||||
|
||||
public void setAltitude(boolean altitude) {
|
||||
isAltitude = altitude;
|
||||
}
|
||||
|
||||
public boolean isBearing() {
|
||||
return isBearing;
|
||||
}
|
||||
|
||||
public void setBearing(boolean bearing) {
|
||||
isBearing = bearing;
|
||||
}
|
||||
|
||||
public int getTilex() {
|
||||
return tilex;
|
||||
}
|
||||
|
||||
public void setTilex(int tilex) {
|
||||
this.tilex = tilex;
|
||||
}
|
||||
|
||||
public int getTiley() {
|
||||
return tiley;
|
||||
}
|
||||
|
||||
public void setTiley(int tiley) {
|
||||
this.tiley = tiley;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getTown() {
|
||||
return town;
|
||||
}
|
||||
|
||||
public void setTown(String town) {
|
||||
this.town = town;
|
||||
}
|
||||
|
||||
public String getStreetNumber() {
|
||||
return streetNumber;
|
||||
}
|
||||
|
||||
public void setStreetNumber(String streetNumber) {
|
||||
this.streetNumber = streetNumber;
|
||||
}
|
||||
|
||||
public String getErrorInfo() {
|
||||
return errorInfo;
|
||||
}
|
||||
|
||||
public void setErrorInfo(String errorInfo) {
|
||||
this.errorInfo = errorInfo;
|
||||
}
|
||||
|
||||
public String getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public void setErrorCode(String errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
|
||||
/**
|
||||
* 项目
|
||||
*/
|
||||
@Entity(tableName = "project")
|
||||
public class Project extends Feature {
|
||||
//项目名称
|
||||
@ColumnInfo(name = "project_name")
|
||||
private String name;
|
||||
///创建时间
|
||||
@ColumnInfo(name = "project_time")
|
||||
private String createTime;
|
||||
///项目描述信息
|
||||
@ColumnInfo(name = "project_describe")
|
||||
private String describe;
|
||||
///项目是否显示
|
||||
@ColumnInfo(name = "project_visibility")
|
||||
private boolean visibility;
|
||||
///任务圈
|
||||
@ColumnInfo(name = "project_geometry")
|
||||
private String geometry;
|
||||
///任务圈显隐
|
||||
@ColumnInfo(name = "project_geometry_visibility")
|
||||
private boolean geometryVisibility;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(String createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getDescribe() {
|
||||
return describe;
|
||||
}
|
||||
|
||||
public void setDescribe(String describe) {
|
||||
this.describe = describe;
|
||||
}
|
||||
|
||||
public boolean getVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
public void setVisibility(boolean visibility) {
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
public String getGeometry() {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
public void setGeometry(String geometry) {
|
||||
this.geometry = geometry;
|
||||
}
|
||||
|
||||
public boolean getGeometryVisibility() {
|
||||
return geometryVisibility;
|
||||
}
|
||||
|
||||
public void setGeometryVisibility(boolean geometryVisibility) {
|
||||
this.geometryVisibility = geometryVisibility;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.navinfo.collect.library.data.entity;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Index;
|
||||
import androidx.room.PrimaryKey;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author qj
|
||||
* @version V1.0
|
||||
* @ClassName: TileElement
|
||||
* @Date 2022/4/14
|
||||
* @Description: ${TileElement}(关联表)
|
||||
*/
|
||||
@Entity(tableName = "tileElement",indices = {@Index("tilex"),@Index("tiley"),@Index("element_uuid")})
|
||||
public class TileElement extends Feature{
|
||||
|
||||
@ColumnInfo(name = "tilex")
|
||||
private int tilex;
|
||||
@ColumnInfo(name = "tiley")
|
||||
private int tiley;
|
||||
@ColumnInfo(name = "element_uuid")
|
||||
private String elementId;
|
||||
|
||||
public int getTilex() {
|
||||
return tilex;
|
||||
}
|
||||
|
||||
public void setTilex(int tilex) {
|
||||
this.tilex = tilex;
|
||||
}
|
||||
|
||||
public int getTiley() {
|
||||
return tiley;
|
||||
}
|
||||
|
||||
public void setTiley(int tiley) {
|
||||
this.tiley = tiley;
|
||||
}
|
||||
|
||||
public String getElementId() {
|
||||
return elementId;
|
||||
}
|
||||
|
||||
public void setElementId(String elementId) {
|
||||
this.elementId = elementId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
TileElement that = (TileElement) o;
|
||||
return tilex == that.tilex && tiley == that.tiley && Objects.equals(elementId, that.elementId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(tilex, tiley, elementId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TileElement{" +
|
||||
"tilex=" + tilex +
|
||||
", tiley=" + tiley +
|
||||
", elementId='" + elementId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.navinfo.collect.library.data.flutter
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.FlutterBaseActivity
|
||||
import com.navinfo.collect.library.data.NIDataController
|
||||
import com.navinfo.collect.library.data.flutter.flutterhandler.*
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
class FlutterDataController(
|
||||
id: Int,
|
||||
context: Context,
|
||||
binaryMessenger: BinaryMessenger,
|
||||
activity: FlutterBaseActivity,
|
||||
) : NIDataController(context, activity), MethodChannel.MethodCallHandler {
|
||||
|
||||
private val mMethodChannel: MethodChannel = MethodChannel(
|
||||
binaryMessenger,
|
||||
"com.navinfo.collect/data_$id"
|
||||
)
|
||||
|
||||
private val flutterDataLayerHandler: FlutterDataLayerHandler
|
||||
|
||||
private val flutterDataElementHandler: FlutterDataElementHandler
|
||||
|
||||
private val flutterDataProjectHandler: FlutterDataProjectHandler
|
||||
|
||||
private val flutterDataNiLocationHandler: FlutterDataNiLocationHandler
|
||||
|
||||
val flutterDataCameraHandler: FlutterDataCameraHandler
|
||||
|
||||
init {
|
||||
mMethodChannel.setMethodCallHandler(this)
|
||||
flutterDataLayerHandler = FlutterDataLayerHandler(mContext, mDateBase)
|
||||
flutterDataElementHandler = FlutterDataElementHandler(mContext, mMethodChannel, mDateBase)
|
||||
flutterDataProjectHandler = FlutterDataProjectHandler(mContext, mDateBase)
|
||||
flutterDataNiLocationHandler = FlutterDataNiLocationHandler(mContext, mDateBase)
|
||||
flutterDataCameraHandler =
|
||||
FlutterDataCameraHandler(mContext, mMethodChannel, activity, mDateBase)
|
||||
}
|
||||
|
||||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||
when (call.method) {
|
||||
/**
|
||||
* 数据图层操作部分
|
||||
*/
|
||||
//创建数据图层
|
||||
FlutterDataProtocolKeys.DateLayerProtocol.kDataCreateDataLayer -> {
|
||||
flutterDataLayerHandler.createDataLayerTable(call, result);
|
||||
}
|
||||
//获取所有数据图层
|
||||
FlutterDataProtocolKeys.DateLayerProtocol.kDataGetDataLayerList -> {
|
||||
flutterDataLayerHandler.getDataLayerList(call, result);
|
||||
}
|
||||
|
||||
//获取某个数据图层
|
||||
FlutterDataProtocolKeys.DateLayerProtocol.kDataGetDataLayer -> {
|
||||
flutterDataLayerHandler.getDataLayer(call, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据操作部分
|
||||
*/
|
||||
//保存数据
|
||||
FlutterDataProtocolKeys.DataElementProtocol.kDataSaveElementData -> {
|
||||
flutterDataElementHandler.saveElementData(call, result)
|
||||
}
|
||||
|
||||
//删除数据
|
||||
FlutterDataProtocolKeys.DataElementProtocol.kDataDeleteElementData -> {
|
||||
flutterDataElementHandler.deleteElementData(call, result)
|
||||
}
|
||||
|
||||
//捕捉数据
|
||||
FlutterDataProtocolKeys.DataElementProtocol.kDataSnapElementDataList -> {
|
||||
flutterDataElementHandler.snapElementDataList(call, result)
|
||||
}
|
||||
|
||||
// 导入Pbf数据
|
||||
FlutterDataProtocolKeys.DataElementProtocol.kImportPbfData -> {
|
||||
flutterDataElementHandler.importPbfData2Realm(call, result)
|
||||
}
|
||||
//查询数据详细信息模板
|
||||
FlutterDataProtocolKeys.DataElementProtocol.kDataQueryElementDeepInfo -> {
|
||||
flutterDataElementHandler.queryElementDeepInfo(call, result)
|
||||
}
|
||||
//数据搜索
|
||||
FlutterDataProtocolKeys.DataElementProtocol.kDataSearchData -> {
|
||||
flutterDataElementHandler.searchData(call, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目管理
|
||||
*/
|
||||
//获取项目列表
|
||||
FlutterDataProtocolKeys.DataProjectProtocol.kDataGetDataProjectList -> {
|
||||
flutterDataProjectHandler.getProjectList(call, result);
|
||||
}
|
||||
|
||||
//保存项目
|
||||
FlutterDataProtocolKeys.DataProjectProtocol.kDataSaveDataProject -> {
|
||||
flutterDataProjectHandler.saveProject(call, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 轨迹操作部分
|
||||
*/
|
||||
//保存轨迹数据
|
||||
FlutterDataProtocolKeys.DataNiLocationProtocol.kDataSaveNiLocationData -> {
|
||||
flutterDataNiLocationHandler.saveNiLocationData(call, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查项部分
|
||||
*/
|
||||
//获取所有检查项
|
||||
FlutterDataProtocolKeys.DataCheckProtocol.kDataGetCheckManagerList -> {
|
||||
flutterDataElementHandler.queryCheckManagerList(call, result)
|
||||
}
|
||||
//根据id获取检查项
|
||||
FlutterDataProtocolKeys.DataCheckProtocol.kDataGetCheckManagerListByIds -> {
|
||||
flutterDataElementHandler.queryCheckManagerListByIds(call, result)
|
||||
}
|
||||
//打开摄像头
|
||||
FlutterDataProtocolKeys.DataCameraProtocol.kDataOpenCamera -> {
|
||||
flutterDataCameraHandler.openCamera(call, result)
|
||||
}
|
||||
///ocr批量识别
|
||||
FlutterDataProtocolKeys.DataCameraProtocol.kDataOCRBatchResults -> {
|
||||
flutterDataCameraHandler.ocrBatch(call, result)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
super.release()
|
||||
mMethodChannel.setMethodCallHandler(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.navinfo.collect.library.data.flutter
|
||||
|
||||
object FlutterDataProtocolKeys {
|
||||
|
||||
/**
|
||||
* 数据图层管理
|
||||
*/
|
||||
object DateLayerProtocol {
|
||||
/**
|
||||
* 获取数据层列表
|
||||
*/
|
||||
const val kDataGetDataLayerList = "flutter_nimap/DataLayer/getDataLayerList";
|
||||
|
||||
/**
|
||||
* 获取某个数据层列表
|
||||
*/
|
||||
const val kDataGetDataLayer = "flutter_nimap/DataLayer/getDataLayer";
|
||||
|
||||
/**
|
||||
* 创建数据层
|
||||
*/
|
||||
const val kDataCreateDataLayer = "flutter_nimap/DataLayer/createDataLayer";
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据操作
|
||||
*/
|
||||
object DataElementProtocol {
|
||||
|
||||
|
||||
//保存数据
|
||||
const val kDataSaveElementData = "flutter_nimap/ElementData/saveElementData";
|
||||
|
||||
///删除数据
|
||||
const val kDataDeleteElementData = "flutter_nimap/ElementData/deleteElementData";
|
||||
|
||||
//查询数据
|
||||
const val kDataSnapElementDataList = "flutter_nimap/ElementData/snapElementDataList";
|
||||
|
||||
// 导入pbf数据
|
||||
const val kImportPbfData = "flutter_nimap/HDData/importPBF";
|
||||
|
||||
//查询数据详细信息
|
||||
const val kDataQueryElementDeepInfo = "flutter_nimap/ElementData/queryElementDeepInfo";
|
||||
|
||||
///按名称搜索数据
|
||||
const val kDataSearchData = "flutter_nimap/ElementData/queryElementByName"
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据操作
|
||||
*/
|
||||
object DataNiLocationProtocol {
|
||||
|
||||
|
||||
//保存数据
|
||||
const val kDataSaveNiLocationData = "flutter_nimap/NiLocationData/saveNiLocationData";
|
||||
|
||||
///删除数据
|
||||
const val kDataDeleteNiLocationData = "flutter_nimap/NiLocationData/deleteNiLocationData";
|
||||
}
|
||||
|
||||
object DataProjectProtocol {
|
||||
/**
|
||||
* 获取项目列表
|
||||
*/
|
||||
const val kDataGetDataProjectList = "flutter_nimap/Project/getDataProjectList";
|
||||
|
||||
/**
|
||||
* 保存项目
|
||||
*/
|
||||
const val kDataSaveDataProject = "flutter_nimap/Project/saveDataProject";
|
||||
|
||||
}
|
||||
|
||||
object DataCheckProtocol {
|
||||
///获取检查项列表
|
||||
const val kDataGetCheckManagerList = "flutter_nimap/CheckManager/getDataCheckManagerList";
|
||||
|
||||
///根据id获取检查项列表
|
||||
const val kDataGetCheckManagerListByIds =
|
||||
"flutter_nimap/CheckManager/getDataCheckManagerListByIds";
|
||||
}
|
||||
|
||||
object DataCameraProtocol {
|
||||
const val kDataOpenCamera = "flutter_nimap/openCamera";
|
||||
|
||||
const val kDataOCRResults = "flutter_nimap/ocrResults";
|
||||
///批量识别
|
||||
const val kDataOCRBatchResults = "flutter_nimap/ocrBatch";
|
||||
///ocr 批量回调进度
|
||||
const val kDataOCRBatchProgress = "flutter_nimap/ocrBatchProgress";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.navinfo.collect.library.data.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.baidu.ai.edge.ui.view.model.BasePolygonResultModel
|
||||
import com.baidu.ai.edge.ui.view.model.OcrViewResultModel
|
||||
import com.navinfo.collect.FlutterBaseActivity
|
||||
import com.navinfo.collect.library.data.DataConversion
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.flutter.FlutterDataProtocolKeys
|
||||
import com.navinfo.collect.library.data.handler.DataCameraHandler
|
||||
import com.navinfo.collect.library.data.handler.OnOCRBatchListener
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
class FlutterDataCameraHandler(
|
||||
context: Context,
|
||||
methodChannel: MethodChannel,
|
||||
activity: FlutterBaseActivity,
|
||||
dataBase: MapLifeDataBase
|
||||
) :
|
||||
DataCameraHandler(context, activity, dataBase) {
|
||||
private val _methodChannel = methodChannel
|
||||
fun openCamera(call: MethodCall, result: MethodChannel.Result) {
|
||||
super.openCamera()
|
||||
result.success(true)
|
||||
}
|
||||
|
||||
fun sendOcrResults(path: String, basePolygonResultModels: List<BasePolygonResultModel>) {
|
||||
|
||||
_methodChannel.invokeMethod(
|
||||
FlutterDataProtocolKeys.DataCameraProtocol.kDataOCRResults,
|
||||
DataConversion.toOcrList(path, basePolygonResultModels)
|
||||
)
|
||||
}
|
||||
|
||||
fun ocrBatch(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is String) {
|
||||
super.ocrBatch(
|
||||
call.arguments as String,
|
||||
object : OnOCRBatchListener {
|
||||
override fun onProgress(total: Int, current: Int) {
|
||||
Log.e("jingo", "OCRManager 线程名称2 ${Thread.currentThread().name}")
|
||||
Log.e("jingo", "OCR识别 当前第 $current 张,总共 $total 张");
|
||||
val map = mutableMapOf<String, Int>()
|
||||
map["total"] = total
|
||||
map["current"] = current + 1
|
||||
_methodChannel.invokeMethod(
|
||||
FlutterDataProtocolKeys.DataCameraProtocol.kDataOCRBatchProgress,
|
||||
map
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun onResult(list: List<Map<String, Any>>) {
|
||||
Log.e("jingo", "OCRManager 线程名称2 ${Thread.currentThread().name}")
|
||||
_methodChannel.invokeMethod(
|
||||
FlutterDataProtocolKeys.DataCameraProtocol.kDataOCRBatchResults,
|
||||
DataConversion.toFlutterOcrList(list)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
result.success(true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
package com.navinfo.collect.library.data.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.DataConversion
|
||||
import com.navinfo.collect.library.data.RealmUtils
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.entity.Element
|
||||
import com.navinfo.collect.library.data.entity.LayerManager
|
||||
import com.navinfo.collect.library.data.entity.Project
|
||||
import com.navinfo.collect.library.data.flutter.FlutterDataProtocolKeys
|
||||
import com.navinfo.collect.library.data.handler.DataElementHandler
|
||||
import com.navinfo.collect.library.data.search.*
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* 数据操作
|
||||
*/
|
||||
class FlutterDataElementHandler(
|
||||
context: Context,
|
||||
methodChannel: MethodChannel,
|
||||
dataBase: MapLifeDataBase
|
||||
) :
|
||||
DataElementHandler(context, dataBase), OnGetSearchDataResultListener {
|
||||
val _methodChannel = methodChannel
|
||||
|
||||
init {
|
||||
setListener(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
fun saveElementData(call: MethodCall, result: MethodChannel.Result) = try {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
val element = Element.fromMap(call.arguments as MutableMap<String, Any>?);
|
||||
val valueMap = call.argument<Map<String, Any>>("values")
|
||||
saveData(element, valueMap) { res, error ->
|
||||
if (res) {
|
||||
result.success("$res")
|
||||
} else {
|
||||
result.success(error)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
Log.e("jingo", e.stackTraceToString())
|
||||
Log.e("jingo", e.toString())
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*/
|
||||
fun deleteElementData(call: MethodCall, result: MethodChannel.Result) = try {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
val element = Element()
|
||||
element.layerId = call.argument("layerId")
|
||||
element.id = call.argument("uuid")
|
||||
element.geometry = call.argument("geometry")
|
||||
element.displayText = call.argument("displayText")
|
||||
element.displayStyle = call.argument("displayStyle")
|
||||
element.operationTime = call.argument("tOperateDate")
|
||||
element.tLifecycle = call.argument<Int>("tLifecycle")!!
|
||||
element.tStatus = call.argument<Int>("tStatus")!!
|
||||
deleteData(element) { res, message ->
|
||||
if (res) {
|
||||
result.success("success")
|
||||
} else {
|
||||
result.success(message)
|
||||
}
|
||||
};
|
||||
|
||||
} else {
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
Log.e("jingo", e.stackTraceToString())
|
||||
Log.e("jingo", e.toString())
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制数据
|
||||
*/
|
||||
fun copyElementData(call: MethodCall, result: MethodChannel.Result) = try {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
|
||||
} else {
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
Log.e("jingo", e.stackTraceToString())
|
||||
Log.e("jingo", e.toString())
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
|
||||
|
||||
fun importPbfData2Realm(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is List<*>) {
|
||||
val pbfFiles: List<String> = call.arguments as List<String>
|
||||
try {
|
||||
val importResult = RealmUtils.getInstance().importPbfData(pbfFiles)
|
||||
result.success(importResult)
|
||||
} catch (exeception: Exception) {
|
||||
result.error("-1", exeception.message, exeception)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 捕捉数据
|
||||
*/
|
||||
fun snapElementDataList(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is String) {
|
||||
snapElementDataList(call.arguments as String) {
|
||||
result.success(DataConversion.toElementMapList(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据深度信息模板
|
||||
*/
|
||||
fun queryElementDeepInfo(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
val id = call.argument<String>("id")
|
||||
val layerId = call.argument<String>("layerId")
|
||||
if (id != null && layerId != null) {
|
||||
queryElementDeepInfo(id, layerId) { layerManager, itemList ->
|
||||
if (layerManager != null) {
|
||||
val map = layerManager.toMap()
|
||||
map["layerItems"] = DataConversion.customLayerItemsToMapList(itemList)
|
||||
result.success(map)
|
||||
} else {
|
||||
result.error("-1","没有这条数据的拓展模板","")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据渲染名称查询数据
|
||||
*/
|
||||
fun searchData(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is String) {
|
||||
try {
|
||||
val jsonObject = JSONObject(call.arguments as String)
|
||||
val keyword = jsonObject.getString("keyword")
|
||||
val pageNum = jsonObject.getInt("pageNum")
|
||||
val pageCapacity = jsonObject.getInt("pageCapacity")
|
||||
val startTime = jsonObject.getInt("startTime")
|
||||
val endTime = jsonObject.getInt("endTime")
|
||||
val projectArray = jsonObject.getJSONArray("projectItemList")
|
||||
val layerArray = jsonObject.getJSONArray("layerItemList")
|
||||
val fieldArray = jsonObject.getJSONArray("fieldItemList")
|
||||
val projectItemList = ArrayList<OptionProjectItem>()
|
||||
val layerItemList = ArrayList<OptionLayerItem>()
|
||||
val fieldItemList = ArrayList<OptionFieldItem>()
|
||||
for (i in 0 until projectArray.length()) {
|
||||
val item = OptionProjectItem(projectArray.getString(i))
|
||||
projectItemList.add(item)
|
||||
}
|
||||
for (i in 0 until layerArray.length()) {
|
||||
val layerObject = layerArray.getJSONObject(i)
|
||||
val item = OptionLayerItem(
|
||||
layerObject.optString("projectId"),
|
||||
layerObject.optString("layerId")
|
||||
)
|
||||
layerItemList.add(item)
|
||||
}
|
||||
for (i in 0 until fieldArray.length()) {
|
||||
val fieldObject = fieldArray.getJSONObject(i)
|
||||
val item = OptionFieldItem(
|
||||
fieldObject.optString("projectId"),
|
||||
fieldObject.optString("layerId"),
|
||||
fieldObject.optString("fieldName")
|
||||
)
|
||||
fieldItemList.add(item)
|
||||
}
|
||||
val option =
|
||||
SearchDataOption.Builder().setKeyword(keyword).setStartTime(startTime)
|
||||
.setEndTime(endTime).setFieldItems(fieldItemList)
|
||||
.setLayerItems(layerItemList).setProjectItems(projectItemList)
|
||||
.setPageNum(pageNum).setPageCapacity(pageCapacity).build()
|
||||
searchData(option) {
|
||||
// result.success(DataConversion.toElementMapList(it))
|
||||
}
|
||||
result.success("");
|
||||
} catch (e: Exception) {
|
||||
println("$e")
|
||||
result.error("-1", "查询参数解析错误", "$e")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检查项列表
|
||||
*/
|
||||
fun queryCheckManagerList(call: MethodCall, result: MethodChannel.Result) {
|
||||
queryCheckManagerList() { list ->
|
||||
result.success(DataConversion.toCheckManagerMapList(list));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据id获取检查项列表
|
||||
*/
|
||||
fun queryCheckManagerListByIds(call: MethodCall, result: MethodChannel.Result) {
|
||||
queryCheckManagerList() { list ->
|
||||
result.success(DataConversion.toCheckManagerMapList(list));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun onGetElementResult(elementList: List<Element>) {
|
||||
_methodChannel.invokeMethod(
|
||||
FlutterDataProtocolKeys.DataElementProtocol.kDataSearchData,
|
||||
DataConversion.toElementMapList(elementList)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onGetLayerResult(layer: LayerManager) {
|
||||
}
|
||||
|
||||
override fun onGetProjectResult(project: Project) {
|
||||
}
|
||||
|
||||
override fun onError(msg: String, keyword: String) {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.navinfo.collect.library.data.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.DataConversion
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.entity.CustomLayerItem
|
||||
import com.navinfo.collect.library.data.entity.DataLayerItemType
|
||||
import com.navinfo.collect.library.data.handler.DataLayerHandler
|
||||
import com.navinfo.collect.library.data.entity.LayerManager
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* 数据图层管理
|
||||
*/
|
||||
class FlutterDataLayerHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
DataLayerHandler(context, dataBase) {
|
||||
|
||||
fun createDataLayerTable(call: MethodCall, result: MethodChannel.Result) {
|
||||
try {
|
||||
if (call.arguments is String) {
|
||||
val jsonObject = JSONObject(call.arguments as String)
|
||||
val layer = LayerManager()
|
||||
layer.id = jsonObject.optString("uuid")
|
||||
layer.projectId = jsonObject.optString("projectId")
|
||||
layer.geometryType = jsonObject.optInt("geometryType")
|
||||
layer.layerName = jsonObject.optString("layerName")
|
||||
layer.style = jsonObject.optString("style")
|
||||
layer.importTime = jsonObject.optString("import_time")
|
||||
layer.describe = jsonObject.optString("describe")
|
||||
layer.visibility = jsonObject.optBoolean("visibility")
|
||||
val jsonArrayItems = JSONArray(jsonObject.optString("layerItems"))
|
||||
layer.bundle = jsonArrayItems.toString()
|
||||
|
||||
var itemList = mutableListOf<CustomLayerItem>();
|
||||
for (i in 0 until jsonArrayItems.length()) {
|
||||
val jsonObjectItem: JSONObject = jsonArrayItems[i] as JSONObject;
|
||||
val item = CustomLayerItem(
|
||||
key = jsonObjectItem.optString("key"),
|
||||
type = DataLayerItemType.values()[jsonObjectItem.optInt("type")],
|
||||
title = jsonObjectItem.optString("title"),
|
||||
describe = jsonObjectItem.optString("describe"),
|
||||
itemBean = jsonObjectItem.optString("itemBean"),
|
||||
)
|
||||
itemList.add(item)
|
||||
}
|
||||
// val list = DataConversion.listMapToCustomLayerItemsList(itemList)
|
||||
createTable(layer, itemList) { res, _ ->
|
||||
result.success(res)
|
||||
}
|
||||
} else {
|
||||
result.success(false)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
Log.e("jingo", e.stackTraceToString())
|
||||
Log.e("jingo", e.toString())
|
||||
result.success(false)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部数据图层信息
|
||||
*/
|
||||
fun getDataLayerList(call: MethodCall, result: MethodChannel.Result) {
|
||||
getDataLayerList { list ->
|
||||
val newList = mutableListOf<Map<*, *>>()
|
||||
for (item in list) {
|
||||
val map = mapOf(
|
||||
"uuid" to item.id,
|
||||
"projectId" to item.projectId,
|
||||
"geometryType" to item.geometryType,
|
||||
"layerName" to item.layerName,
|
||||
"import_time" to item.importTime,
|
||||
"describe" to item.describe,
|
||||
"visibility" to item.visibility,
|
||||
"layerItems" to item.bundle,
|
||||
"style" to item.style
|
||||
)
|
||||
newList.add(map)
|
||||
}
|
||||
result.success(newList)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个数据图层
|
||||
*/
|
||||
fun getDataLayer(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is String) {
|
||||
getDataLayer(call.arguments as String) { layer ->
|
||||
result.success(
|
||||
mapOf(
|
||||
"uuid" to layer.id,
|
||||
"projectId" to layer.projectId,
|
||||
"geometryType" to layer.geometryType,
|
||||
"layerName" to layer.layerName,
|
||||
"import_time" to layer.importTime,
|
||||
"describe" to layer.describe,
|
||||
"visibility" to layer.visibility,
|
||||
"layerItems" to layer.bundle,
|
||||
"style" to layer.style
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
result.success("false")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.navinfo.collect.library.data.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.entity.NiLocation
|
||||
import com.navinfo.collect.library.data.handler.DataNiLocationHandler
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* 数据操作
|
||||
*/
|
||||
class FlutterDataNiLocationHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
DataNiLocationHandler(context, dataBase) {
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
fun saveNiLocationData(call: MethodCall, result: MethodChannel.Result) = try {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
val niLocation = NiLocation()
|
||||
niLocation.id = call.argument("uuid")
|
||||
niLocation.longitude = call.argument<Double>("longitude")!!
|
||||
niLocation.latitude = call.argument<Double>("latitude")!!
|
||||
niLocation.altitude = call.argument<Double>("altitude")!!
|
||||
niLocation.radius = call.argument<Double>("radius")!!
|
||||
niLocation.direction = call.argument<Double>("direction")!!
|
||||
niLocation.time = call.argument("time")!!
|
||||
if(niLocation.time.length==19){
|
||||
val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
|
||||
val dDate: Date = simpleDateFormat.parse(niLocation.time)
|
||||
niLocation.time = dDate.time.toString()
|
||||
}
|
||||
niLocation.speed = call.argument<Float>("speed")!!
|
||||
niLocation.country = call.argument("country")
|
||||
niLocation.province = call.argument("province")
|
||||
niLocation.city = call.argument("city")
|
||||
niLocation.district = call.argument("district")
|
||||
niLocation.street = call.argument("street")
|
||||
niLocation.town = call.argument("town")
|
||||
niLocation.adCode = call.argument("adCode")
|
||||
niLocation.cityCode = call.argument("cityCode")
|
||||
niLocation.streetNumber = call.argument("streetNumber")
|
||||
niLocation.errorCode = call.argument<String?>("errorCode").toString()
|
||||
niLocation.errorInfo = call.argument("errorInfo")
|
||||
|
||||
saveDataNiLocation(niLocation) { res, error ->
|
||||
if (res) {
|
||||
result.success("$res")
|
||||
} else {
|
||||
result.success(error)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
Log.e("jingo", e.stackTraceToString())
|
||||
Log.e("jingo", e.toString())
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*/
|
||||
fun deleteNiLocationData(call: MethodCall, result: MethodChannel.Result) = try {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
val niLocation = NiLocation()
|
||||
niLocation.id = call.argument("uuid")
|
||||
deleteData(niLocation) { res, message ->
|
||||
if (res) {
|
||||
result.success("success")
|
||||
} else {
|
||||
result.success(message)
|
||||
}
|
||||
};
|
||||
|
||||
} else {
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
Log.e("jingo", e.stackTraceToString())
|
||||
Log.e("jingo", e.toString())
|
||||
result.success("数据格式错误")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.navinfo.collect.library.data.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.handler.DataProjectHandler
|
||||
import com.navinfo.collect.library.data.entity.Project
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
/**
|
||||
* 项目管理
|
||||
*/
|
||||
class FlutterDataProjectHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
DataProjectHandler(context, dataBase) {
|
||||
|
||||
fun saveProject(call: MethodCall, result: MethodChannel.Result) {
|
||||
try {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
// "style": style,
|
||||
val project = Project();
|
||||
//项目名称
|
||||
|
||||
project.id = call.argument("uuid")
|
||||
project.name = call.argument("name")
|
||||
project.createTime = call.argument("createTime")
|
||||
project.describe = call.argument("describe")
|
||||
project.visibility = call.argument<Boolean>("visibility") == false
|
||||
project.geometry = call.argument("geometry")
|
||||
project.geometryVisibility = call.argument<Boolean>("geometryVisibility") == false
|
||||
|
||||
saveProject(project) { res, _ ->
|
||||
result.success(res)
|
||||
};
|
||||
} else {
|
||||
result.success(false)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) };
|
||||
Log.e("jingo", e.stackTraceToString());
|
||||
Log.e("jingo", e.toString());
|
||||
result.success(false)
|
||||
}
|
||||
}
|
||||
|
||||
fun getProjectList(call: MethodCall, result: MethodChannel.Result) {
|
||||
getProjectList { list ->
|
||||
val newList = mutableListOf<Map<*, *>>()
|
||||
for (item in list) {
|
||||
val map = mapOf(
|
||||
"uuid" to item.id,
|
||||
"name" to item.name,
|
||||
"createTime" to item.createTime,
|
||||
"describe" to item.describe,
|
||||
"visibility" to item.visibility,
|
||||
"geometry" to item.geometry,
|
||||
"geometryVisibility" to item.geometryVisibility
|
||||
)
|
||||
newList.add(map)
|
||||
}
|
||||
result.success(newList)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.navinfo.collect.library.data.handler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
|
||||
open class BaseDataHandler(context: Context, dataBase: MapLifeDataBase) {
|
||||
protected val mContext: Context = context;
|
||||
protected val mDataBase: MapLifeDataBase = dataBase;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
package com.navinfo.collect.library.data.handler
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.media.ExifInterface
|
||||
import android.util.Log
|
||||
import com.baidu.ai.edge.ui.util.ImageUtil
|
||||
import com.baidu.ai.edge.ui.view.model.OcrViewResultModel
|
||||
import com.navinfo.collect.FlutterBaseActivity
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.ocr.OCRManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
|
||||
interface OnOCRBatchListener {
|
||||
fun onProgress(total: Int, current: Int)
|
||||
suspend fun onResult(list: List<Map<String, Any>>)
|
||||
}
|
||||
|
||||
open class DataCameraHandler(
|
||||
context: Context,
|
||||
activity: FlutterBaseActivity,
|
||||
dataBase: MapLifeDataBase
|
||||
) :
|
||||
BaseDataHandler(context, dataBase) {
|
||||
|
||||
private val mActivity: FlutterBaseActivity = activity
|
||||
|
||||
init {
|
||||
OCRManager.instance.init(activity)
|
||||
}
|
||||
|
||||
fun openCamera() {
|
||||
OCRManager.instance.openCamera(mActivity)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量OCR识别
|
||||
*/
|
||||
fun ocrBatch(filePath: String, listener: OnOCRBatchListener) {
|
||||
mActivity.launch(Dispatchers.IO) {
|
||||
Log.e("jingo", "OCRManager 线程开始 ${Thread.currentThread().name}")
|
||||
val file = File(filePath)
|
||||
val resultList = mutableListOf<Map<String, Any>>()
|
||||
if (file.isDirectory) {
|
||||
val fileList = file.listFiles()
|
||||
val bitmapList = mutableListOf<String>()
|
||||
for (item in fileList!!) {
|
||||
if (item.isFile) {
|
||||
if (checkIsImageFile(item.name)) {
|
||||
bitmapList.add(item.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
val bfw: BufferedWriter
|
||||
val csvFile = File("$filePath/ocr.csv")
|
||||
val out: FileOutputStream
|
||||
val osw: OutputStreamWriter
|
||||
try {
|
||||
out = FileOutputStream(csvFile)
|
||||
//用excel打开,中文会乱码,所以用GBK编译
|
||||
osw = OutputStreamWriter(out, "GBK")
|
||||
bfw = BufferedWriter(osw)
|
||||
//第一行表头数据
|
||||
bfw.write("图片路径和名称,")
|
||||
bfw.write("识别结果序号,")
|
||||
bfw.write("识别结果内容,")
|
||||
bfw.write("置信度,")
|
||||
bfw.write("识别面积,")
|
||||
bfw.write("图片大小,")
|
||||
bfw.write("识别区域,")
|
||||
//写好表头后换行
|
||||
bfw.newLine()
|
||||
for (i in 0 until bitmapList.size) {
|
||||
val path = bitmapList[i]
|
||||
|
||||
val bitmap: Bitmap? = readFile(path)
|
||||
var exif = ExifInterface(path)
|
||||
val exifRotation = exif.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL
|
||||
)
|
||||
val rotation = ImageUtil.exifToDegrees(exifRotation)
|
||||
val rotateBitmap = ImageUtil.createRotateBitmap(bitmap, rotation)
|
||||
val list = OCRManager.instance.ocr(rotateBitmap)
|
||||
|
||||
|
||||
// val list = ocrBitmap(path)
|
||||
if (list != null) {
|
||||
for (o in list) {
|
||||
bfw.write("$path,")
|
||||
bfw.write("${o.index},")
|
||||
bfw.write("${o.name},")
|
||||
bfw.write("${o.confidence.toString()},")
|
||||
val pointList = o.bounds
|
||||
bfw.write("${(pointList[3].y - pointList[0].y) * (pointList[2].x - pointList[0].x)},")
|
||||
bfw.write("${rotateBitmap.width} ${rotateBitmap.height},")
|
||||
bfw.write("${o.bounds[0].x} ${o.bounds[0].y};${o.bounds[1].x} ${o.bounds[1].y};${o.bounds[2].x} ${o.bounds[2].y};${o.bounds[3].x} ${o.bounds[3].y},")
|
||||
bfw.newLine()
|
||||
}
|
||||
bfw.newLine()
|
||||
withContext(Dispatchers.Main) {
|
||||
listener.onProgress(bitmapList.size, i)
|
||||
}
|
||||
val m1 = mutableMapOf<String, Any>();
|
||||
m1["data"] = list;
|
||||
m1["width"] = rotateBitmap.width
|
||||
m1["height"] = rotateBitmap.height
|
||||
m1["path"] = path
|
||||
resultList.add(m1)
|
||||
}
|
||||
rotateBitmap.recycle()
|
||||
}
|
||||
|
||||
//将缓存数据写入文件
|
||||
bfw.flush()
|
||||
//释放缓存
|
||||
bfw.close()
|
||||
osw.close()
|
||||
out.close()
|
||||
} catch (e: Throwable) {
|
||||
|
||||
}
|
||||
//将缓存数据写入文件
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
Log.e("jingo", "OCRManager 线程名称2 ${Thread.currentThread().name}")
|
||||
listener.onResult(resultList)
|
||||
}
|
||||
} else if (file.isFile && checkIsImageFile(file.name)) {
|
||||
val list = ocrBitmap(filePath)
|
||||
if (list != null) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Log.e("jingo", "OCRManager 线程名称2 ${Thread.currentThread().name}")
|
||||
listener.onProgress(1, 1)
|
||||
}
|
||||
val m = mutableMapOf<String, List<OcrViewResultModel>>()
|
||||
m[file.name] = list
|
||||
resultList.add(m)
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
Log.e("jingo", "OCRManager 线程名称2 ${Thread.currentThread().name}")
|
||||
listener.onResult(resultList)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun ocrBitmap(path: String): List<OcrViewResultModel>? {
|
||||
try {
|
||||
val bitmap: Bitmap? = readFile(path)
|
||||
var exif = ExifInterface(path)
|
||||
val exifRotation = exif.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL
|
||||
)
|
||||
val rotation = ImageUtil.exifToDegrees(exifRotation)
|
||||
val rotateBitmap = ImageUtil.createRotateBitmap(bitmap, rotation)
|
||||
val res = OCRManager.instance.ocr(rotateBitmap)
|
||||
rotateBitmap.recycle()
|
||||
return res
|
||||
} catch (e: IOException) {
|
||||
Log.e("jingo", "图像识别,获取图像信息失败 ${e.printStackTrace()}")
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是不是bitmap文件
|
||||
*/
|
||||
private fun checkIsImageFile(fName: String): Boolean {
|
||||
val isImageFile: Boolean
|
||||
// 获取扩展名
|
||||
val fileEnd = fName.substring(
|
||||
fName.lastIndexOf(".") + 1,
|
||||
fName.length
|
||||
).lowercase(Locale.getDefault())
|
||||
isImageFile =
|
||||
fileEnd == "jpg" || fileEnd == "png" || fileEnd == "webp" || fileEnd == "jpeg" || fileEnd == "bmp"
|
||||
return isImageFile
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取bitmap文件
|
||||
*/
|
||||
private fun readFile(path: String): Bitmap? {
|
||||
var stream: FileInputStream? = null
|
||||
try {
|
||||
stream = FileInputStream(path)
|
||||
return BitmapFactory.decodeStream(stream)
|
||||
} catch (e: FileNotFoundException) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// private fun onOcrBitmap(
|
||||
// bitmap, confidence,
|
||||
// object: OcrListener {
|
||||
// override fun onResult(models: List<BasePolygonResultModel>) {
|
||||
// if (models == null) {
|
||||
// listener.onResult(null)
|
||||
// return
|
||||
// }
|
||||
// ocrResultModelCache = models
|
||||
// listener.onResult(models)
|
||||
// }
|
||||
// })
|
||||
|
||||
}
|
||||
@@ -0,0 +1,584 @@
|
||||
package com.navinfo.collect.library.data.handler
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.database.sqlite.SQLiteDatabase.CONFLICT_NONE
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.DataConversion
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.entity.*
|
||||
import com.navinfo.collect.library.data.entity.DataLayerItemType.*
|
||||
import com.navinfo.collect.library.data.search.OnGetSearchDataResultListener
|
||||
import com.navinfo.collect.library.data.search.SearchDataOption
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.collect.library.utils.GeometryToolsKt
|
||||
import io.realm.RealmSet
|
||||
import org.oscim.core.MercatorProjection
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
/**
|
||||
* 数据库操作
|
||||
*/
|
||||
|
||||
|
||||
open class
|
||||
DataElementHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
BaseDataHandler(context, dataBase) {
|
||||
private var mListener: OnGetSearchDataResultListener? = null
|
||||
|
||||
private var lastSearchTime = 0
|
||||
private var timer: Timer? = null
|
||||
|
||||
fun setListener(listener: OnGetSearchDataResultListener) {
|
||||
this.mListener = listener
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
fun saveData(
|
||||
element: Element,
|
||||
map: Map<String, Any>?,
|
||||
callback: (res: Boolean, errorString: String) -> Unit
|
||||
) {
|
||||
thread(start = true) {
|
||||
try {
|
||||
if (map != null) {
|
||||
val cursor =
|
||||
mDataBase.openHelper.writableDatabase.query(
|
||||
"Select * from \"${element.layerId}\" where uuid=?",
|
||||
arrayOf(element.id)
|
||||
)
|
||||
|
||||
val contentValues = ContentValues() //存储信息
|
||||
for ((key, value) in map) {
|
||||
when (value) {
|
||||
is String -> contentValues.put(key, value)
|
||||
is Long -> contentValues.put(key, value)
|
||||
is Int -> contentValues.put(key, value)
|
||||
is Double -> contentValues.put(key, value)
|
||||
is ByteArray -> contentValues.put(key, value)
|
||||
is Boolean -> contentValues.put(key, value)
|
||||
is Float -> contentValues.put(key, value)
|
||||
is Short -> contentValues.put(key, value)
|
||||
is Byte -> contentValues.put(key, value)
|
||||
}
|
||||
}
|
||||
contentValues.put("uuid", element.id);
|
||||
cursor.moveToFirst()
|
||||
if (cursor.count > 0) {
|
||||
mDataBase.openHelper.writableDatabase.update(
|
||||
"'${element.layerId}'",
|
||||
CONFLICT_NONE,
|
||||
contentValues,
|
||||
"uuid = ? ",
|
||||
arrayOf(element.id)
|
||||
)
|
||||
} else {
|
||||
mDataBase.openHelper.writableDatabase.insert(
|
||||
"'${element.layerId}'",//element.layerId,
|
||||
CONFLICT_NONE,
|
||||
contentValues
|
||||
).toInt()
|
||||
}
|
||||
cursor.close()
|
||||
}
|
||||
|
||||
//resetCoordinate(element)
|
||||
element.tLifecycle = 2
|
||||
|
||||
//优先删除已有数据,下面会重新计算最新的tile
|
||||
mDataBase.tileElementDao.deleteElementId(element.id)
|
||||
|
||||
val list = ArrayList<TileElement>()
|
||||
|
||||
try {
|
||||
|
||||
if (element.geometry != null) {
|
||||
val tileX = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileXByGeometry(element.geometry, tileX)
|
||||
val tileY = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileYByGeometry(element.geometry, tileY)
|
||||
|
||||
//遍历存储tile对应的x与y的值
|
||||
tileX.forEach { x ->
|
||||
|
||||
tileY.forEach { y ->
|
||||
val tile = TileElement()
|
||||
tile.elementId = element.id
|
||||
tile.tilex = x
|
||||
tile.tiley = y
|
||||
list.add(tile)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mDataBase.tileElementDao.insertList(list)
|
||||
|
||||
mDataBase.elementDao.insert(element)
|
||||
|
||||
} catch (e: java.lang.Exception) {
|
||||
|
||||
}
|
||||
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*/
|
||||
|
||||
fun deleteData(element: Element, callback: (res: Boolean, errorString: String) -> Unit) {
|
||||
thread(start = true) {
|
||||
try {
|
||||
mDataBase.openHelper.writableDatabase.delete(
|
||||
"'${element.layerId}'",
|
||||
"uuid=?",
|
||||
arrayOf("'${element.id}'")
|
||||
)
|
||||
mDataBase.elementDao.delete(element);
|
||||
} catch (e: Throwable) {
|
||||
Log.e("jingo", "删除数据报错 ${e.message}");
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "${e.message}")
|
||||
}
|
||||
}
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 根据给定的geometry计算其横跨的20级瓦片Y值
|
||||
// */
|
||||
// private fun getTileYByGeometry(geometry: Geometry, tileYSet: MutableSet<Int?>): Set<Int?>? {
|
||||
// var tileYSet: MutableSet<Int?>? = tileYSet
|
||||
// val startTime = System.currentTimeMillis()
|
||||
// if (tileYSet == null) {
|
||||
// tileYSet = RealmSet()
|
||||
// }
|
||||
// val envelope = geometry.envelope
|
||||
// if (envelope != null) {
|
||||
// val coordinates = envelope.coordinates
|
||||
// // 最小最大x轴坐标,索引0位最小x值,索引1位最大y值
|
||||
// if (coordinates != null && coordinates.isNotEmpty()) {
|
||||
// val minMaxY = doubleArrayOf(coordinates[0].y, coordinates[0].y)
|
||||
// for (coordinate in coordinates) {
|
||||
// // 获取最大和最小y的值
|
||||
// if (coordinate.y < minMaxY[0]) {
|
||||
// minMaxY[0] = coordinate.y
|
||||
// }
|
||||
// if (coordinate.y > minMaxY[1]) {
|
||||
// minMaxY[1] = coordinate.y
|
||||
// }
|
||||
// }
|
||||
// // 分别计算最大和最小x值对应的tile号
|
||||
// val tileY0 = MercatorProjection.latitudeToTileY(minMaxY[0], 20.toByte())
|
||||
// val tileY1 = MercatorProjection.latitudeToTileY(minMaxY[1], 20.toByte())
|
||||
// val minTileY = if (tileY0 <= tileY1) tileY0 else tileY1
|
||||
// val maxTileY = if (tileY0 <= tileY1) tileY1 else tileY0
|
||||
// println("getTileYByGeometry$envelope===$minTileY===$maxTileY")
|
||||
//
|
||||
// for (i in minTileY..maxTileY) {
|
||||
// tileYSet.add(i)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// println("YGeometry-time:" + (System.currentTimeMillis() - startTime))
|
||||
// return tileYSet
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 计算数据最大最小坐标
|
||||
*/
|
||||
private fun resetCoordinate(element: Element) {
|
||||
when {
|
||||
element.geometry.startsWith("POINT") -> {
|
||||
var geoPoint = GeometryTools.createGeoPoint(element.geometry)
|
||||
val tile = TileElement()
|
||||
tile.elementId = element.id
|
||||
val minLatitude = Math.max(
|
||||
MercatorProjection.LATITUDE_MIN,
|
||||
MercatorProjection.tileYToLatitude(
|
||||
(geoPoint.latitude.toLong() + 1).toLong(),
|
||||
20
|
||||
)
|
||||
)
|
||||
val minLongitude = Math.max(
|
||||
-180.0,
|
||||
MercatorProjection.tileXToLongitude(geoPoint.longitude.toLong(), 20)
|
||||
)
|
||||
/* element.maxx = (geoPoint.longitude * Constant.CONVERSION_FACTOR).toFloat()
|
||||
element.minx = element.maxx
|
||||
element.maxy = (geoPoint.latitude * Constant.CONVERSION_FACTOR).toFloat()
|
||||
element.miny = element.maxy*/
|
||||
}
|
||||
element.geometry.startsWith("LINESTRING") -> {
|
||||
|
||||
}
|
||||
element.geometry.startsWith("POLYGON") -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 捕捉数据
|
||||
*/
|
||||
fun snapElementDataList(
|
||||
polygon: String,
|
||||
callback: (list: List<Element>) -> Unit
|
||||
) {
|
||||
thread(start = true) {
|
||||
|
||||
val geometry = GeometryTools.createGeometry(polygon)
|
||||
|
||||
if (geometry != null) {
|
||||
//计算tileX号
|
||||
val tileX = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileXByGeometry(polygon, tileX)
|
||||
|
||||
//计算tileY号
|
||||
val tileY = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileYByGeometry(polygon, tileY)
|
||||
|
||||
//读取数据库获取数据
|
||||
val list = mDataBase.elementDao.findList(tileX, tileY)
|
||||
val elements = java.util.ArrayList<Element>()
|
||||
|
||||
//几何遍历判断数据包括或者相交
|
||||
list.forEach { element ->
|
||||
if (element != null && element.geometry != null) {
|
||||
val geometryTemp = GeometryTools.createGeometry(element.geometry)
|
||||
if (geometryTemp != null && geometry.contains(geometryTemp) || geometry.intersects(
|
||||
geometryTemp
|
||||
)
|
||||
) {
|
||||
elements.add(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
var cursor: Cursor? = null
|
||||
try {
|
||||
for (e in elements) {
|
||||
// val layer: LayerManager =
|
||||
// mDataBase.layerManagerDao.findLayerManager(e.layerId)
|
||||
e.values = mutableMapOf<String, String>()
|
||||
// MoshiUtil.fromJson<List<CustomLayerItem>>(layer.bundle)
|
||||
cursor =
|
||||
mDataBase.openHelper.readableDatabase.query("select * from \"${e.layerId}\" where uuid = \"${e.id}\"")
|
||||
while (cursor.moveToNext()) {
|
||||
for (index in 0 until cursor.columnNames.size) {
|
||||
val key = cursor.getColumnName(index)
|
||||
val value = cursor.getString(index)
|
||||
e.values[key] = value
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(elements)
|
||||
}
|
||||
} else {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(listOfNotNull())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据深度信息模板
|
||||
*/
|
||||
fun queryElementDeepInfo(
|
||||
id: String,
|
||||
layerId: String,
|
||||
callback: (layer: LayerManager?, itemList: List<CustomLayerItem>?) -> Unit
|
||||
) {
|
||||
thread(start = true) {
|
||||
val layerManager = mDataBase.layerManagerDao.findLayerManager(layerId)
|
||||
var layerItems = listOf<CustomLayerItem>()
|
||||
if (layerManager != null) {
|
||||
layerItems = DataConversion.jsonToLayerItemsList(layerManager.bundle)
|
||||
var cursor: Cursor? = null
|
||||
try {
|
||||
cursor =
|
||||
mDataBase.openHelper.readableDatabase.query("select * from \"$layerId\" where uuid = \"$id\"")
|
||||
while (cursor.moveToNext()) {
|
||||
for (layerItem in layerItems) {
|
||||
val index = cursor.getColumnIndex(layerItem.key)
|
||||
when (layerItem.type) {
|
||||
DataLayerItemTypeInput -> {
|
||||
// layerItem.value = cursor.getString(index)
|
||||
}
|
||||
DataLayerItemTypeInputArray -> TODO()
|
||||
DataLayerItemTypeText -> TODO()
|
||||
DataLayerItemTypeSingleSelection -> {
|
||||
// layerItem.value = cursor.getString(index)
|
||||
}
|
||||
DataLayerItemTypeMultipleSelection -> TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
}
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(layerManager, layerItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fun queryElementByName(
|
||||
// name: String,
|
||||
// start: Int,
|
||||
// total: Int,
|
||||
// callback: (list: List<Element>) -> Unit
|
||||
// ) {
|
||||
// thread(start = true) {
|
||||
// if (name.isNotEmpty()) {
|
||||
// //读取数据库获取数据
|
||||
// val elements = mDataBase.elementDao.findListByKeyword(name, start, total)
|
||||
// var cursor: Cursor? = null
|
||||
// try {
|
||||
// for (e in elements) {
|
||||
//// val layer: LayerManager =
|
||||
//// mDataBase.layerManagerDao.findLayerManager(e.layerId)
|
||||
// e.values = mutableMapOf<String, String>()
|
||||
//// MoshiUtil.fromJson<List<CustomLayerItem>>(layer.bundle)
|
||||
// cursor =
|
||||
// mDataBase.openHelper.readableDatabase.query("select * from \"${e.layerId}\" where uuid = \"${e.id}\"")
|
||||
// while (cursor.moveToNext()) {
|
||||
// for (index in 0 until cursor.columnNames.size) {
|
||||
// val key = cursor.getColumnName(index)
|
||||
// val value = cursor.getString(index)
|
||||
// e.values[key] = value
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// } catch (e: Throwable) {
|
||||
// Log.e("jingo", e.message)
|
||||
// } finally {
|
||||
// cursor?.close()
|
||||
// }
|
||||
// Handler(Looper.getMainLooper()).post {
|
||||
// callback.invoke(elements)
|
||||
// }
|
||||
// } else {
|
||||
// Handler(Looper.getMainLooper()).post {
|
||||
// callback.invoke(listOfNotNull())
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
fun searchData(option: SearchDataOption, callback: (list: List<Element>) -> Unit) {
|
||||
val nowTime = System.currentTimeMillis()
|
||||
if (nowTime - lastSearchTime < 1500 && timer != null) {
|
||||
timer?.cancel()
|
||||
timer = null
|
||||
}
|
||||
timer = fixedRateTimer("", false, 1500, 10000) {
|
||||
thread(start = true) {
|
||||
var cursor: Cursor? = null
|
||||
try {
|
||||
val db = mDataBase.openHelper.readableDatabase;
|
||||
|
||||
val elementList = mutableListOf<Element>()
|
||||
if (option.layerItemList.isEmpty() && option.projectItemList.isEmpty() && option.fieldItemList.isEmpty()) {
|
||||
elementList.addAll(
|
||||
mDataBase.elementDao.findListByKeyword(
|
||||
option.keyword,
|
||||
option.pageNum * option.pageCapacity,
|
||||
option.pageCapacity
|
||||
)
|
||||
)
|
||||
for (e in elementList) {
|
||||
e.values = mutableMapOf<String, String>()
|
||||
if (cursor != null && !cursor.isClosed) {
|
||||
cursor.close()
|
||||
}
|
||||
cursor =
|
||||
db.query("select * from \"${e.layerId}\" where uuid = \"${e.id}\"")
|
||||
while (cursor.moveToNext()) {
|
||||
for (index in 0 until cursor.columnNames.size) {
|
||||
val key = cursor.getColumnName(index)
|
||||
val value = cursor.getString(index)
|
||||
e.values[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (option.fieldItemList.isNotEmpty()) {
|
||||
for (item in option.fieldItemList) {
|
||||
val valuesMap = mutableMapOf<String, String>()
|
||||
if (cursor != null && !cursor.isClosed) {
|
||||
cursor.close()
|
||||
}
|
||||
val sql =
|
||||
"select * from \"${item.layerId}\" where ${item.fieldName} like '%${option.keyword}%' limit ${option.pageNum * option.pageCapacity},${option.pageCapacity} "
|
||||
cursor = db.query(sql)
|
||||
var uuid = ""
|
||||
while (cursor.moveToNext()) {
|
||||
for (index in 0 until cursor.columnNames.size) {
|
||||
val key = cursor.getColumnName(index)
|
||||
val value = cursor.getString(index)
|
||||
if (key == "uuid") {
|
||||
uuid = value;
|
||||
}
|
||||
valuesMap[key] = value
|
||||
}
|
||||
val e = mDataBase.elementDao.findById(uuid);
|
||||
e.values = valuesMap
|
||||
elementList.add(e)
|
||||
for (layer in option.layerItemList) {
|
||||
if (layer.layerId == item.layerId) {
|
||||
option.layerItemList.remove(layer)
|
||||
break
|
||||
}
|
||||
}
|
||||
for (project in option.projectItemList) {
|
||||
if (project.projectId == item.projectId) {
|
||||
var his = false;
|
||||
for (layer in option.layerItemList) {
|
||||
if (layer.projectId == project.projectId) {
|
||||
his = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!his) {
|
||||
option.projectItemList.remove(project)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (option.layerItemList.isNotEmpty()) {
|
||||
val layerSet = RealmSet<String>();
|
||||
for (layer in option.layerItemList) {
|
||||
layerSet.add(layer.layerId)
|
||||
for (project in option.projectItemList) {
|
||||
if (project.projectId == layer.projectId) {
|
||||
option.projectItemList.remove(project)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
val elements = mDataBase.elementDao.findListByKeywordLimitLayer(
|
||||
option.keyword,
|
||||
layerSet,
|
||||
option.pageNum * option.pageCapacity,
|
||||
option.pageCapacity
|
||||
)
|
||||
for (e in elements) {
|
||||
e.values = mutableMapOf<String, String>()
|
||||
if (cursor != null && !cursor.isClosed) {
|
||||
cursor.close()
|
||||
}
|
||||
cursor =
|
||||
db.query("select * from \"${e.layerId}\" where uuid = \"${e.id}\"")
|
||||
while (cursor.moveToNext()) {
|
||||
for (index in 0 until cursor.columnNames.size) {
|
||||
val key = cursor.getColumnName(index)
|
||||
val value = cursor.getString(index)
|
||||
e.values[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
elementList.addAll(elements)
|
||||
}
|
||||
if (option.projectItemList.isNotEmpty()) {
|
||||
val projectSet = RealmSet<String>();
|
||||
for (project in option.projectItemList) {
|
||||
projectSet.add(project.projectId)
|
||||
}
|
||||
val elements = mDataBase.elementDao.findListByKeywordLimitProject(
|
||||
option.keyword,
|
||||
projectSet,
|
||||
option.pageNum * option.pageCapacity,
|
||||
option.pageCapacity
|
||||
)
|
||||
elementList.addAll(elements)
|
||||
for (e in elementList) {
|
||||
e.values = mutableMapOf<String, String>()
|
||||
if (cursor != null && !cursor.isClosed) {
|
||||
cursor.close()
|
||||
}
|
||||
cursor =
|
||||
db.query("select * from \"${e.layerId}\" where uuid = \"${e.id}\"")
|
||||
while (cursor.moveToNext()) {
|
||||
for (index in 0 until cursor.columnNames.size) {
|
||||
val key = cursor.getColumnName(index)
|
||||
val value = cursor.getString(index)
|
||||
e.values[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
mListener?.onGetElementResult(elementList)
|
||||
// callback.invoke(elementList)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
println(e)
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
|
||||
}
|
||||
timer?.cancel();
|
||||
timer = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有检查项标签
|
||||
*/
|
||||
fun queryCheckManagerList(callback: (list: List<CheckManager>) -> Unit) {
|
||||
thread(start = true) {
|
||||
val list = mDataBase.checkManagerDao.findList()
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
package com.navinfo.collect.library.data.handler
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.navinfo.collect.library.data.DataConversion
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.entity.CheckManager
|
||||
import com.navinfo.collect.library.data.entity.CustomLayerItem
|
||||
import com.navinfo.collect.library.data.entity.DataLayerItemType
|
||||
import com.navinfo.collect.library.data.entity.LayerManager
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
/**
|
||||
* 数据库操作
|
||||
*/
|
||||
|
||||
|
||||
open class DataLayerHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
BaseDataHandler(context, dataBase) {
|
||||
|
||||
/**
|
||||
* 根据json创建数据库
|
||||
* [
|
||||
* {"key":"name","type":"TEXT","nullable":true},
|
||||
* {"key":"address","type":"TEXT","nullable":true},
|
||||
* {"key":"type","type":"INTEGER","nullable":false},
|
||||
* {"key":"longitude","type":"REAL","nullable":false},
|
||||
* {"key":"latitude","type":"REAL","nullable":false},
|
||||
* {"key":"id","type":"INTEGER","nullable":false,"primaryKey":true}
|
||||
* ]
|
||||
*
|
||||
*
|
||||
* _db.execSQL("CREATE TABLE IF NOT EXISTS `edit_pois` (`rowId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `postCode` TEXT, `address` TEXT, `kindCode` TEXT, `uuid` TEXT, `geometry` TEXT, `maxx` REAL NOT NULL, `minx` REAL NOT NULL, `maxy` REAL NOT NULL, `miny` REAL NOT NULL)");
|
||||
_db.execSQL("CREATE TABLE IF NOT EXISTS `element` (`rowId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `display_style` TEXT, `display_text` TEXT, `start_level` INTEGER NOT NULL, `end_level` INTEGER NOT NULL, `zindex` INTEGER NOT NULL, `visibility` INTEGER NOT NULL, `operation_time` TEXT, `export_time` TEXT, `t_lifecycle` INTEGER NOT NULL, `t_status` INTEGER NOT NULL, `bundle` TEXT, `uuid` TEXT, `geometry` TEXT, `maxx` REAL NOT NULL, `minx` REAL NOT NULL, `maxy` REAL NOT NULL, `miny` REAL NOT NULL)");
|
||||
_db.execSQL("CREATE TABLE IF NOT EXISTS `layerElement` (`rowId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `uuid` TEXT, `layer_uuid` TEXT, `element_uuid` TEXT)");
|
||||
_db.execSQL("CREATE TABLE IF NOT EXISTS `layerManager` (`rowId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `uuid` TEXT, `layer_name` TEXT, `zindex` INTEGER NOT NULL, `visibility` INTEGER NOT NULL, `export_time` TEXT, `import_time` TEXT, `bundle` TEXT)");
|
||||
_db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
|
||||
_db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7a041262c922535fc32b56d4dd16ea92')");
|
||||
*
|
||||
*/
|
||||
|
||||
fun createTable(
|
||||
layer: LayerManager,
|
||||
list: List<CustomLayerItem>,
|
||||
callback: (res: Boolean, errorString: String) -> Unit
|
||||
) {
|
||||
thread(start = true) {
|
||||
try {
|
||||
val sql = StringBuffer();
|
||||
val database: SupportSQLiteDatabase = mDataBase.openHelper.writableDatabase
|
||||
val locLayer = mDataBase.layerManagerDao.findLayerManager(layer.id);
|
||||
if (locLayer != null) {
|
||||
sql.append("CREATE TABLE IF NOT EXISTS '${layer.id}temp' ( uuid TEXT NOT NULL, ")
|
||||
val columnBuffer = StringBuffer()
|
||||
columnBuffer.append("uuid")
|
||||
var count = 0;
|
||||
//比对旧的数据库表,看看哪些字段需要更改
|
||||
val items = DataConversion.jsonToLayerItemsList(locLayer.bundle)
|
||||
for (i in list.indices) {
|
||||
if (i > 0) {
|
||||
sql.append(", ")
|
||||
}
|
||||
sql.append("'${list[i].key}' ")
|
||||
sql.append(layerItemTypeToDBType(list[i].type))
|
||||
for (j in items.indices) {
|
||||
//这里只根据id是否相同进行了判断,如果类型变换了话会有风险,需要应用层做限制
|
||||
if (items[j].key == list[i].key) {
|
||||
columnBuffer.append(",")
|
||||
columnBuffer.append(items[j].key)
|
||||
count++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
sql.append(")")
|
||||
|
||||
if (count == items.size && count == list.size) {
|
||||
mDataBase.layerManagerDao.update(layer)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
} else {
|
||||
var b = true
|
||||
val sql2 =
|
||||
"insert into \"${layer.id}temp\"($columnBuffer) select $columnBuffer from \"${layer.id}\""
|
||||
try {
|
||||
database.beginTransaction()
|
||||
database.execSQL(sql.toString())
|
||||
database.execSQL(sql2)
|
||||
database.execSQL("drop TABLE \"${layer.id}\"")
|
||||
database.execSQL("ALTER TABLE \"${layer.id}temp\" RENAME TO \"${layer.id}\"")
|
||||
database.setTransactionSuccessful()
|
||||
} catch (e: Throwable) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "${e.message}")
|
||||
}
|
||||
b = false
|
||||
} finally {
|
||||
database.endTransaction()
|
||||
}
|
||||
if (b) {
|
||||
mDataBase.layerManagerDao.update(layer)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sql.append("CREATE TABLE IF NOT EXISTS '${layer.id}' ( uuid TEXT NOT NULL, ")
|
||||
for (i in list.indices) {
|
||||
if (i > 0) {
|
||||
sql.append(", ")
|
||||
}
|
||||
sql.append("'${list[i].key}' ")
|
||||
sql.append(layerItemTypeToDBType(list[i].type))
|
||||
}
|
||||
sql.append(")")
|
||||
mDataBase.layerManagerDao.insert(layer)
|
||||
mDataBase.openHelper.writableDatabase.execSQL(sql.toString())
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据图层自定义子表所有配置转成JSON形式
|
||||
* (现在用在向数据库插入数据图层表时,主要用于原生层)
|
||||
*/
|
||||
private fun customLayerItemListToBundle(list: List<CustomLayerItem>): String {
|
||||
val jsonArray = JSONArray()
|
||||
for (item in list) {
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("key", item.key)
|
||||
jsonObject.put("title", item.title)
|
||||
jsonObject.put("type", item.type.ordinal)
|
||||
// jsonObject.put("nullable", item.nullable)
|
||||
// jsonObject.put("primaryKey", item.primaryKey)
|
||||
// jsonObject.put("value", item.value)
|
||||
// jsonObject.put("selectOptions", item.selectOptions)
|
||||
// jsonObject.put("isMainName", item.isMainName)
|
||||
jsonObject.put("describe", item.describe)
|
||||
val checkIdsArray = JSONArray()
|
||||
// for (c in item.checkManagerList) {
|
||||
// checkIdsArray.put(c.id)
|
||||
// }
|
||||
jsonObject.put(
|
||||
"checkManagerIds", checkIdsArray
|
||||
)
|
||||
jsonArray.put(jsonObject)
|
||||
}
|
||||
return jsonArray.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字段的控件类型,转换成数据库字段类型
|
||||
*
|
||||
* enum LayerItemType {
|
||||
///输入框
|
||||
layerItemTypeInput,
|
||||
|
||||
///输入框集合
|
||||
layerItemTypeInputArray,
|
||||
|
||||
///纯展示文本
|
||||
layerItemTypeText,
|
||||
|
||||
///单选框
|
||||
layerItemTypeSingleSelection,
|
||||
|
||||
///多选框
|
||||
layerItemTypeMultipleSelection,
|
||||
|
||||
///菜单
|
||||
layerItemTypeMultiLevelMenu
|
||||
}
|
||||
*/
|
||||
private fun layerItemTypeToDBType(type: DataLayerItemType): String {
|
||||
when (type) {
|
||||
DataLayerItemType.DataLayerItemTypeInput -> return "TEXT"
|
||||
}
|
||||
return "TEXT";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询获取图层列表
|
||||
*/
|
||||
fun getDataLayerList(callback: (list: List<LayerManager>) -> Unit) {
|
||||
thread(start = true) {
|
||||
val list = mDataBase.layerManagerDao.findList();
|
||||
// ///获取拓展部分
|
||||
// for (l in list) {
|
||||
// l.itemList = getItemList(l.bundle);
|
||||
// }
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析dataLayer的bundle部分
|
||||
*/
|
||||
private fun getItemList(bundle: String): List<CustomLayerItem>? {
|
||||
val itemList: MutableList<CustomLayerItem> = ArrayList()
|
||||
if (bundle != null) {
|
||||
try {
|
||||
val jsonArray = JSONArray(bundle)
|
||||
for (i in 0 until jsonArray.length()) {
|
||||
val itemObject = jsonArray.getJSONObject(i)
|
||||
val checkManagerList = mutableListOf<CheckManager>()
|
||||
val idArray = itemObject.optJSONArray("checkManagerIds")
|
||||
if (idArray != null) {
|
||||
for (j in 0 until idArray.length()) {
|
||||
val id = idArray[j] as Int
|
||||
val check = mDataBase.checkManagerDao.findCheckManagerById(id.toLong())
|
||||
if (check != null)
|
||||
checkManagerList.add(check)
|
||||
}
|
||||
}
|
||||
val item = CustomLayerItem(
|
||||
key = itemObject.optString("key"),
|
||||
title = itemObject.optString("title"),
|
||||
type = DataLayerItemType.values()[itemObject.optInt("type")],
|
||||
// nullable = itemObject.optBoolean("nullable", true),
|
||||
// primaryKey = itemObject.optBoolean("primaryKey", false),
|
||||
// value = itemObject.opt("value"),
|
||||
// selectOptions = itemObject.optString("selectOptions"),
|
||||
// isMainName = itemObject.optBoolean("isMainName"),
|
||||
describe = itemObject.optString("describe"),
|
||||
// checkManagerList =
|
||||
itemBean = ""
|
||||
)
|
||||
itemList.add(item)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("jingo", "CustomLayerItem 列表创建失败 " + e.message)
|
||||
}
|
||||
}
|
||||
return itemList
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某个获取图层
|
||||
*/
|
||||
fun getDataLayer(layerId: String, callback: (layer: LayerManager) -> Unit) {
|
||||
thread(start = true) {
|
||||
val layer = mDataBase.layerManagerDao.findLayerManager(layerId);
|
||||
layer.itemList = getItemList(layer.bundle);
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(layer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.navinfo.collect.library.data.handler
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.database.sqlite.SQLiteDatabase.CONFLICT_NONE
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.DataConversion
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.entity.*
|
||||
import com.navinfo.collect.library.data.entity.DataLayerItemType.*
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.collect.library.utils.GeometryToolsKt
|
||||
import io.realm.RealmSet
|
||||
import org.locationtech.jts.geom.Geometry
|
||||
import org.locationtech.jts.io.WKTReader
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.MercatorProjection
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
/**
|
||||
* 数据库操作
|
||||
*/
|
||||
|
||||
|
||||
open class
|
||||
DataNiLocationHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
BaseDataHandler(context, dataBase) {
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
fun saveDataNiLocation(
|
||||
niLocation: NiLocation,
|
||||
callback: (res: Boolean, errorString: String) -> Unit
|
||||
) {
|
||||
thread(start = true) {
|
||||
try {
|
||||
|
||||
val geometry = GeometryTools.createGeometry(
|
||||
GeoPoint(
|
||||
niLocation.latitude,
|
||||
niLocation.longitude
|
||||
)
|
||||
)
|
||||
val tileX = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
|
||||
val tileY = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
|
||||
|
||||
//遍历存储tile对应的x与y的值
|
||||
tileX.forEach { x ->
|
||||
|
||||
tileY.forEach { y ->
|
||||
niLocation.tilex = x
|
||||
niLocation.tiley = y
|
||||
}
|
||||
|
||||
}
|
||||
val niLocationLoad = mDataBase.niLocationDao.find(niLocation.id);
|
||||
if(niLocationLoad!=null){
|
||||
mDataBase.niLocationDao.update(niLocation)
|
||||
}else{
|
||||
mDataBase.niLocationDao.insert(niLocation)
|
||||
}
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.message?.let { Log.e("qj", it) }
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*/
|
||||
|
||||
fun deleteData(niLocation: NiLocation, callback: (res: Boolean, errorString: String) -> Unit) {
|
||||
thread(start = true) {
|
||||
try {
|
||||
mDataBase.openHelper.writableDatabase.delete(
|
||||
"'niLocation'",
|
||||
"uuid=?",
|
||||
arrayOf("'${niLocation.id}'")
|
||||
)
|
||||
mDataBase.niLocationDao.delete(niLocation);
|
||||
} catch (e: Throwable) {
|
||||
Log.e("jingo", "删除数据报错 ${e.message}");
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "${e.message}")
|
||||
}
|
||||
}
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.navinfo.collect.library.data.handler
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.entity.Project
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
/**
|
||||
* 数据库操作
|
||||
*/
|
||||
|
||||
|
||||
open class DataProjectHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
BaseDataHandler(context, dataBase) {
|
||||
|
||||
|
||||
fun saveProject(
|
||||
project: Project,
|
||||
callback: (res: Boolean, errorString: String) -> Unit
|
||||
) {
|
||||
thread(start = true) {
|
||||
try {
|
||||
mDataBase.projectManagerDao.insert(project)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询获取图层列表
|
||||
*/
|
||||
fun getProjectList(callback: (list: List<Project>) -> Unit) {
|
||||
thread(start = true) {
|
||||
val list = mDataBase.projectManagerDao.findList();
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.navinfo.collect.library.data.search
|
||||
|
||||
import com.navinfo.collect.library.data.entity.Element
|
||||
import com.navinfo.collect.library.data.entity.LayerManager
|
||||
import com.navinfo.collect.library.data.entity.Project
|
||||
|
||||
interface OnGetSearchDataResultListener {
|
||||
fun onGetElementResult(elementList: List<Element>)
|
||||
fun onGetLayerResult(layer: LayerManager)
|
||||
fun onGetProjectResult(project: Project)
|
||||
fun onError(msg:String,keyword:String)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.navinfo.collect.library.data.search
|
||||
|
||||
class OptionFieldItem constructor(
|
||||
val projectId: String,
|
||||
val layerId: String,
|
||||
val fieldName: String
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.navinfo.collect.library.data.search
|
||||
|
||||
class OptionLayerItem constructor(val projectId: String, val layerId: String) {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.navinfo.collect.library.data.search
|
||||
|
||||
class OptionProjectItem constructor(val projectId: String) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.navinfo.collect.library.data.search
|
||||
|
||||
class SearchDataOption private constructor(
|
||||
/**
|
||||
* 关键字
|
||||
*/
|
||||
val keyword: String,
|
||||
|
||||
/**
|
||||
* 当前页数
|
||||
*/
|
||||
val pageNum: Int,
|
||||
|
||||
/**
|
||||
* 每页最多数量
|
||||
*/
|
||||
val pageCapacity: Int,
|
||||
/**
|
||||
* 在工程级别范围内搜索
|
||||
*/
|
||||
val projectItemList: ArrayList<OptionProjectItem>,
|
||||
|
||||
/**
|
||||
* 在图层级别范围内搜
|
||||
*/
|
||||
val layerItemList: ArrayList<OptionLayerItem>,
|
||||
|
||||
/**
|
||||
* 搜索某个工程下,某个图层下的,某个字段
|
||||
*/
|
||||
val fieldItemList: ArrayList<OptionFieldItem>,
|
||||
|
||||
/**
|
||||
* 时间范围,开始时间
|
||||
*/
|
||||
val startTime: Int,
|
||||
|
||||
/**
|
||||
* 时间范围,结束时间
|
||||
*/
|
||||
val endTime: Int
|
||||
|
||||
) {
|
||||
private constructor (builder: Builder) : this(
|
||||
builder.keyword,
|
||||
builder.pageNum,
|
||||
builder.pageCapacity,
|
||||
builder.projectItemList,
|
||||
builder.layerItemList,
|
||||
builder.fieldItemList,
|
||||
builder.startTime,
|
||||
builder.endTime,
|
||||
)
|
||||
|
||||
class Builder {
|
||||
var keyword: String = ""
|
||||
private set
|
||||
var pageNum: Int = 0
|
||||
private set
|
||||
var pageCapacity: Int = 20
|
||||
private set
|
||||
var projectItemList = ArrayList<OptionProjectItem>()
|
||||
private set
|
||||
var layerItemList = ArrayList<OptionLayerItem>()
|
||||
private set
|
||||
var fieldItemList = ArrayList<OptionFieldItem>()
|
||||
private set
|
||||
var startTime: Int = -1
|
||||
private set
|
||||
var endTime: Int = -1
|
||||
private set
|
||||
|
||||
|
||||
fun build() = SearchDataOption(this)
|
||||
|
||||
fun setKeyword(id: String) = apply {
|
||||
this.keyword = id;
|
||||
}
|
||||
|
||||
fun setStartTime(time: Int) = apply {
|
||||
this.startTime = time;
|
||||
}
|
||||
|
||||
fun setEndTime(time: Int) = apply {
|
||||
this.endTime = time;
|
||||
}
|
||||
|
||||
fun setPageNum(num: Int) = apply {
|
||||
this.pageNum = num;
|
||||
}
|
||||
|
||||
fun setPageCapacity(capacity: Int) = apply {
|
||||
this.pageCapacity = capacity;
|
||||
}
|
||||
|
||||
fun setLayerItems(list: ArrayList<OptionLayerItem>) = apply {
|
||||
this.layerItemList = list
|
||||
}
|
||||
|
||||
|
||||
fun setProjectItems(list: ArrayList<OptionProjectItem>) = apply {
|
||||
this.projectItemList = list
|
||||
}
|
||||
|
||||
fun setFieldItems(list: ArrayList<OptionFieldItem>) = apply {
|
||||
this.fieldItemList = list
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.navinfo.collect.library.importExport
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
|
||||
open class ImportExportController(context: Context, dataBase: MapLifeDataBase) {
|
||||
protected val mContext: Context = context;
|
||||
protected val mDataBase: MapLifeDataBase = dataBase;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.navinfo.collect.library.importExport.flutter
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.importExport.ImportExportController
|
||||
import com.navinfo.collect.library.importExport.flutter.flutterhandler.FlutterImportFileHandler
|
||||
import com.navinfo.collect.library.importExport.flutter.flutterhandler.FlutterShpFileHandler
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
class FlutterImportExportController(
|
||||
id: Int,
|
||||
context: Context,
|
||||
binaryMessenger: BinaryMessenger,
|
||||
dataBase: MapLifeDataBase,
|
||||
) : ImportExportController(context, dataBase), MethodChannel.MethodCallHandler {
|
||||
|
||||
private val mMethodChannel: MethodChannel = MethodChannel(
|
||||
binaryMessenger,
|
||||
"com.navinfo.collect/importOrExport_$id"
|
||||
)
|
||||
|
||||
private val flutterShpFileHandler: FlutterShpFileHandler =
|
||||
FlutterShpFileHandler(context, mMethodChannel, mDataBase)
|
||||
|
||||
private val flutterImportFileHandler: FlutterImportFileHandler =
|
||||
FlutterImportFileHandler(context, mMethodChannel, mDataBase)
|
||||
|
||||
init {
|
||||
mMethodChannel.setMethodCallHandler(this)
|
||||
}
|
||||
|
||||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||
when (call.method) {
|
||||
/**
|
||||
* shp文件操作
|
||||
*/
|
||||
//获取shp文件信息
|
||||
FlutterImportExportProtocolKeys.ShpFileProtocol.kGetImportShpFileInfo -> {
|
||||
flutterShpFileHandler.getImportShpFileInfo(call, result)
|
||||
}
|
||||
//导入shp数据
|
||||
FlutterImportExportProtocolKeys.ShpFileProtocol.kImportShpData -> {
|
||||
flutterShpFileHandler.importShpData(call, result)
|
||||
}
|
||||
|
||||
//导入检查项数据
|
||||
FlutterImportExportProtocolKeys.MainProtocol.kGetImportCheckFileInfo ->{
|
||||
flutterImportFileHandler.importCheckData(call,result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.navinfo.collect.library.importExport.flutter
|
||||
|
||||
class FlutterImportExportProtocolKeys {
|
||||
/**
|
||||
* SHP文件操作
|
||||
*/
|
||||
object ShpFileProtocol {
|
||||
/**
|
||||
* 获取SHP文件信息
|
||||
*/
|
||||
const val kGetImportShpFileInfo = "flutter_nimap/ShpFile/getImportShpFileInfo";
|
||||
|
||||
|
||||
/**
|
||||
* 导入SHP数据
|
||||
*/
|
||||
const val kImportShpData = "flutter_nimap/ShpFile/ImportShpData";
|
||||
|
||||
|
||||
}
|
||||
|
||||
object MainProtocol{
|
||||
/**
|
||||
* 导入检查项数据
|
||||
*/
|
||||
const val kGetImportCheckFileInfo =
|
||||
"flutter_nimap/ShpFile/getImportCheckFileInfo";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.navinfo.collect.library.importExport.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.importExport.handler.ImportFileHandler
|
||||
import com.navinfo.collect.library.system.Constant
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
class FlutterImportFileHandler(
|
||||
context: Context,
|
||||
methodChannel: MethodChannel,
|
||||
dataBase: MapLifeDataBase,
|
||||
) : ImportFileHandler(context, dataBase) {
|
||||
/**
|
||||
* 获取shp文件属性信息
|
||||
*/
|
||||
fun importCheckData(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is String) {
|
||||
importCheckFileInfo("${call.arguments}") { bSuccess, message ->
|
||||
if (bSuccess) {
|
||||
result.success(message)
|
||||
} else {
|
||||
result.error("1", message, "")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.navinfo.collect.library.importExport.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Environment
|
||||
import com.navinfo.collect.library.data.DataConversion
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.importExport.handler.ShpFileHandler
|
||||
import com.navinfo.collect.library.system.Constant
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
class FlutterShpFileHandler(
|
||||
context: Context,
|
||||
methodChannel: MethodChannel,
|
||||
dataBase: MapLifeDataBase,
|
||||
) : ShpFileHandler(context, dataBase) {
|
||||
/**
|
||||
* 获取shp文件属性信息
|
||||
*/
|
||||
fun getImportShpFileInfo(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is String) {
|
||||
// .path + "/yongfeng/yongfengpolygon.shp"
|
||||
// val path = call.arguments["path"];
|
||||
getImportShpFileInfo("${call.arguments}") { bSuccess, message ->
|
||||
if (bSuccess) {
|
||||
result.success(message)
|
||||
} else {
|
||||
result.error("1", message, "")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入shp文件数据
|
||||
*/
|
||||
fun importShpData(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
var path = "";
|
||||
var layerId = "";
|
||||
if (call.hasArgument("path")) {
|
||||
path = call.argument<String>("path").toString()
|
||||
// path = Environment.getExternalStorageDirectory()
|
||||
// .path + "/yongfeng/yongfengpolygon.shp"
|
||||
}
|
||||
if (call.hasArgument("layerId")) {
|
||||
layerId = call.argument<String>("layerId").toString()
|
||||
}
|
||||
if (path.isNotEmpty() && layerId.isNotEmpty()) {
|
||||
importShpData("$path", layerId) { bSuccess, message ->
|
||||
if (bSuccess) {
|
||||
result.success(true)
|
||||
} else {
|
||||
result.error("-1", message, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.navinfo.collect.library.importExport.handler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
|
||||
open class ImportExportBaseHandler(context: Context, dataBase: MapLifeDataBase) {
|
||||
protected val mContext: Context = context
|
||||
protected val mDataBase: MapLifeDataBase = dataBase
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.navinfo.collect.library.importExport.handler
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.entity.CheckManager
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
open class ImportFileHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
ImportExportBaseHandler(context, dataBase) {
|
||||
|
||||
init {
|
||||
}
|
||||
|
||||
fun importCheckFileInfo(path: String, callback: (bSuccess: Boolean, message: String) -> Unit) {
|
||||
thread(start = true) {
|
||||
try {
|
||||
val file = File(path)
|
||||
if (file.exists()) {
|
||||
val inputStream = file.inputStream()
|
||||
inputStream.bufferedReader().useLines { lines ->
|
||||
try {
|
||||
val iterator = lines.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
var json = iterator.next();
|
||||
val jsonObject = JSONObject(json)
|
||||
val type = jsonObject.optInt("type", 0)
|
||||
val tag = jsonObject.optString("tag", "未命名")
|
||||
var regex = jsonObject.optString("regexStr")
|
||||
if (regex.startsWith("/") && regex.endsWith("/")) {
|
||||
regex = regex.substring(1, regex.length - 1)
|
||||
}
|
||||
val check = CheckManager(type = type, tag = tag, regexStr = regex)
|
||||
mDataBase.checkManagerDao.insert(check)
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
}
|
||||
}
|
||||
// inputStream.close()
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.message?.let { Log.e("jingo", it) }
|
||||
}
|
||||
android.os.Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
package com.navinfo.collect.library.importExport.handler
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Environment
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.DataConversion
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.entity.TileElement
|
||||
import com.navinfo.collect.library.utils.GeometryToolsKt
|
||||
import com.navinfo.collect.library.utils.StringUtil
|
||||
import io.realm.RealmSet
|
||||
import org.gdal.gdal.gdal
|
||||
import org.gdal.ogr.*
|
||||
import org.gdal.osr.SpatialReference
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
open class ShpFileHandler(context: Context, dataBase: MapLifeDataBase) :
|
||||
ImportExportBaseHandler(context, dataBase) {
|
||||
val strDriverName = "ESRI Shapefile"
|
||||
|
||||
init {
|
||||
Log.e("jingo", "ShpFileHandler 初始化!!!!!")
|
||||
ogr.RegisterAll()
|
||||
gdal.AllRegister()
|
||||
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")
|
||||
// 为了使属性表字段支持中文,请添加下面这句
|
||||
gdal.SetConfigOption("SHAPE_ENCODING", "CP936")
|
||||
}
|
||||
|
||||
fun getImportShpFileInfo(path: String, callback: (bSuccess: Boolean, message: String) -> Unit) {
|
||||
try {
|
||||
val file: File = File(path);
|
||||
if (file.exists()) {
|
||||
//创建一个文件,根据strDriverName扩展名自动判断驱动类型
|
||||
val oDriver: org.gdal.ogr.Driver = ogr.GetDriverByName(strDriverName)
|
||||
if (oDriver == null) {
|
||||
Log.e("jingo", "$strDriverName 驱动不可用!");
|
||||
callback(false, "$strDriverName 驱动不可用!")
|
||||
}
|
||||
val dataSource: DataSource = oDriver.Open(path)
|
||||
val layer: Layer = dataSource.GetLayer(0)
|
||||
// for (i in 0 until dataSource.GetLayerCount()) {
|
||||
val layerItem = dataSource.GetLayer(0);
|
||||
// Log.e("jingo", "图层名称:${layerItem.GetName()}")
|
||||
//空间参考坐标系
|
||||
// val spatialReference:SpatialReference = layerItem.GetSpatialRef()
|
||||
//图层范围
|
||||
// val layerExtent: DoubleArray = layerItem.GetExtent()
|
||||
// }
|
||||
val geomType = getGeomType(layerItem.GetGeomType())
|
||||
Log.e("jingo", "图层数据类型:${layerItem.GetGeomType()}")
|
||||
//获取图层信息
|
||||
val featureDefn: FeatureDefn = layer.GetLayerDefn()
|
||||
val fieldCount = featureDefn.GetFieldCount()
|
||||
val stringBuffer = StringBuffer()
|
||||
for (i in 0 until fieldCount) {
|
||||
val fieldDefn: FieldDefn = featureDefn.GetFieldDefn(i)
|
||||
//得到属性字段类型
|
||||
// val fieldType = fieldDefn.GetFieldType()
|
||||
// val fieldTypeName = fieldDefn.GetFieldTypeName(fieldType)
|
||||
//得到属性字段名称
|
||||
val fieldName = fieldDefn.GetName()
|
||||
if (stringBuffer.isNotEmpty()) {
|
||||
stringBuffer.append(";")
|
||||
}
|
||||
stringBuffer.append(fieldName)
|
||||
}
|
||||
|
||||
val jsonString =
|
||||
"{\"layerName\":\"${layerItem.GetName()}\",\"geomType\":$geomType,\"keys\":\"$stringBuffer\"}"
|
||||
callback(true, jsonString)
|
||||
// //读取空间信息及属性列表
|
||||
// for (i in 0 until fieldCount) {
|
||||
// val feature: Feature = layer.GetFeature(i.toLong())
|
||||
// for ((key, value) in map) {
|
||||
// val fvalue = feature.GetFieldAsString(value)
|
||||
// Log.e("jingo", "属性名称:$value 属性值:$fvalue")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
callback(false, "${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGeomType(type: Int): Int {
|
||||
when (type) {
|
||||
ogr.wkbPoint -> return 0
|
||||
ogr.wkbPolygon -> return 2
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
fun importShpData(
|
||||
path: String,
|
||||
mapLayerId: String,
|
||||
callback: (bSuccess: Boolean, message: String) -> Unit
|
||||
) {
|
||||
thread(start = true) {
|
||||
try {
|
||||
val mapLayer = mDataBase.layerManagerDao.findLayerManager(mapLayerId)
|
||||
if (mapLayer != null) {
|
||||
|
||||
val mapLayerItemList = DataConversion.jsonToLayerItemsList(mapLayer.bundle)
|
||||
var mainName = ""
|
||||
// for (item in mapLayerItemList) {
|
||||
// if (item.isMainName) {
|
||||
// mainName = item.key
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
val file = File(path);
|
||||
if (file.exists()) {
|
||||
val oDriver: org.gdal.ogr.Driver = ogr.GetDriverByName(strDriverName)
|
||||
if (oDriver == null) {
|
||||
Log.e("jingo", "$strDriverName 驱动不可用!");
|
||||
callback(false, "$strDriverName 驱动不可用!")
|
||||
}
|
||||
val dataSource: DataSource = oDriver.Open(path)
|
||||
val layer: Layer = dataSource.GetLayer(0)
|
||||
val layerItem = dataSource.GetLayer(0)
|
||||
//获取图层信息
|
||||
val featureDefn: FeatureDefn = layer.GetLayerDefn()
|
||||
val fieldCount = featureDefn.GetFieldCount()
|
||||
val db = mDataBase.openHelper.readableDatabase
|
||||
db.beginTransaction()
|
||||
for (i in 0 until layer.GetFeatureCount()) {
|
||||
val feature = layer.GetFeature(i)
|
||||
val geometry = feature.GetGeometryRef()
|
||||
val stringNameBuffer = StringBuffer()
|
||||
val stringValueBuffer = StringBuffer()
|
||||
var displayText = ""
|
||||
for (i in 0 until fieldCount) {
|
||||
val fieldDefn: FieldDefn = featureDefn.GetFieldDefn(i)
|
||||
//得到属性字段名称
|
||||
val fieldName = fieldDefn.GetName()
|
||||
val fieldValue = feature.GetFieldAsString(fieldName)
|
||||
stringNameBuffer.append(",'")
|
||||
stringNameBuffer.append(fieldName)
|
||||
stringNameBuffer.append("'")
|
||||
|
||||
stringValueBuffer.append(",'")
|
||||
stringValueBuffer.append(fieldValue)
|
||||
stringValueBuffer.append("'")
|
||||
if (mainName == fieldName) {
|
||||
displayText = fieldValue
|
||||
}
|
||||
}
|
||||
val uuid = StringUtil.createUUID()
|
||||
val wkt = geometry.ExportToWkt()
|
||||
val nowTime = StringUtil.getYYYYMMDDHHMMSSS();
|
||||
val masterPoint = GeometryToolsKt.getMasterPoint(wkt)
|
||||
var jsonObject = JSONObject(mapLayer.style)
|
||||
jsonObject.put(
|
||||
"masterPoint",
|
||||
masterPoint
|
||||
)
|
||||
val style = jsonObject.toString()
|
||||
val sql =
|
||||
"insert into '$mapLayerId' ('uuid'${stringNameBuffer}) values ('$uuid'${stringValueBuffer})"
|
||||
val sql2 =
|
||||
"insert into 'element' ('layer_id','display_style','display_text','visibility','export_time','t_lifecycle','t_status','geometry','uuid','start_level','end_level','zindex','operation_time') values ('$mapLayerId','$style','$displayText','0','$nowTime','2','1','${wkt}','$uuid',0,0,0,'$nowTime')"
|
||||
Log.e("jingo",sql)
|
||||
Log.e("jingo",sql2)
|
||||
db.execSQL(sql)
|
||||
db.execSQL(sql2)
|
||||
if (geometry != null) {
|
||||
val tileX = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileXByGeometry(wkt, tileX)
|
||||
val tileY = RealmSet<Int>()
|
||||
GeometryToolsKt.getTileYByGeometry(wkt, tileY)
|
||||
|
||||
//遍历存储tile对应的x与y的值
|
||||
tileX.forEach { x ->
|
||||
|
||||
tileY.forEach { y ->
|
||||
val sql3 =
|
||||
"insert into 'tileElement' ('tilex','tiley','element_uuid','uuid') values ('$x','$y','$uuid','${StringUtil.createUUID()}')"
|
||||
db.execSQL(sql3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
db.setTransactionSuccessful()
|
||||
db.endTransaction()
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(true, "SHP导入成功")
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "没有对应的图层")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("导入数据出错", e.toString());
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
callback.invoke(false, "SHP导入失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
package com.navinfo.collect.library.map;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.location.Location;
|
||||
import android.os.Environment;
|
||||
import android.text.TextPaint;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.badlogic.gdx.maps.MapGroupLayer;
|
||||
import com.navinfo.collect.library.R;
|
||||
import com.navinfo.collect.library.map.layers.NIPolygonLayer;
|
||||
import com.navinfo.collect.library.map.source.NavinfoMapRastorTileSource;
|
||||
import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource;
|
||||
import com.navinfo.collect.library.utils.DistanceUtil;
|
||||
import com.navinfo.collect.library.utils.GeometryTools;
|
||||
import com.navinfo.collect.library.utils.StringUtil;
|
||||
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.Polygon;
|
||||
import org.oscim.android.canvas.AndroidBitmap;
|
||||
import org.oscim.backend.CanvasAdapter;
|
||||
import org.oscim.backend.canvas.Bitmap;
|
||||
import org.oscim.core.GeoPoint;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.event.Event;
|
||||
import org.oscim.layers.Layer;
|
||||
import org.oscim.layers.LocationLayer;
|
||||
import org.oscim.layers.marker.ItemizedLayer;
|
||||
import org.oscim.layers.marker.MarkerInterface;
|
||||
import org.oscim.layers.marker.MarkerItem;
|
||||
import org.oscim.layers.marker.MarkerSymbol;
|
||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||
import org.oscim.layers.vector.geometries.Drawable;
|
||||
import org.oscim.layers.vector.geometries.PointDrawable;
|
||||
import org.oscim.layers.vector.geometries.PolygonDrawable;
|
||||
import org.oscim.layers.vector.PathLayer;
|
||||
import org.oscim.layers.vector.geometries.Style;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.tiling.source.OkHttpEngine;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public class NILayerManager implements ItemizedLayer.OnItemGestureListener {
|
||||
private Map vtmMap;
|
||||
public static String defaultDir = Environment.getExternalStorageDirectory() + "/" + "NavinfoCollect";
|
||||
private String defaultLocalMapPath = defaultDir + "/maps/";
|
||||
//图层管理
|
||||
private java.util.Map<String, Layer> layersMap = new HashMap<String, Layer>();
|
||||
//默认marker图层
|
||||
private ItemizedLayer mDefaultMarkerLayer;
|
||||
//定位图层
|
||||
private LocationLayer mLocationLayer;
|
||||
private NIPolygonLayer mPolygonLayer;
|
||||
private List<MarkerItem> mPathMakers = new ArrayList<>();
|
||||
private Location mCurrentLocation; // 当前位置信息
|
||||
|
||||
public static final String MARQUEE_MARKER_LAYER = "MarqueeMarker";
|
||||
|
||||
private Context mCon;
|
||||
|
||||
private java.util.Map<String, Layer> vectorLayerMap; // 维护vector图层的map数据,key为图层名称(一般对应为矢量数据的数据源),value为图层
|
||||
|
||||
public NILayerManager(Context context, Map vtmMap) {
|
||||
this.vtmMap = vtmMap;
|
||||
this.mCon = context;
|
||||
|
||||
//新增marker图标样式
|
||||
AndroidBitmap mDefaultBitmap =
|
||||
new AndroidBitmap(BitmapFactory.decodeResource(context.getResources(), R.mipmap.marker));
|
||||
MarkerSymbol markerSymbol = new MarkerSymbol(mDefaultBitmap, MarkerSymbol.HotspotPlace.BOTTOM_CENTER);
|
||||
//新增marker图层
|
||||
mDefaultMarkerLayer = new ItemizedLayer(
|
||||
vtmMap,
|
||||
new ArrayList<MarkerInterface>(),
|
||||
markerSymbol,
|
||||
this
|
||||
);
|
||||
addLayer("defaultMarkerLayer", mDefaultMarkerLayer, NIMapView.LAYER_GROUPS.VECTOR.ordinal());
|
||||
|
||||
//定位图层
|
||||
mLocationLayer = new LocationLayer(vtmMap);
|
||||
addLayer("locationLayer", mLocationLayer, NIMapView.LAYER_GROUPS.ALLWAYS_SHOW_GROUP.ordinal());
|
||||
|
||||
if (this.vectorLayerMap == null) {
|
||||
this.vectorLayerMap = new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
public Layer getRasterTileLayer(Context mContext, String url, String tilePath, boolean useCache) {
|
||||
if (this.vtmMap == null) {
|
||||
throw new IllegalStateException("无法获取到map对象");
|
||||
}
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
NavinfoMapRastorTileSource mTileSource = NavinfoMapRastorTileSource.builder(url).tilePath(tilePath).httpFactory(new OkHttpEngine.OkHttpFactory(builder)).build();
|
||||
// 如果使用缓存
|
||||
if (useCache) {
|
||||
File cacheDirectory = new File(defaultDir, "tiles-raster");
|
||||
int cacheSize = 300 * 1024 * 1024; // 300 MB
|
||||
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||
builder.cache(cache);
|
||||
}
|
||||
|
||||
// mTileSource.setHttpEngine(new OkHttpEngine.OkHttpFactory(builder));
|
||||
// mTileSource.setHttpRequestHeaders(Collections.singletonMap("User-Agent", "vtm-android-example"));
|
||||
// mTileSource.setCache(new TileCache(mContext, defaultDir, url.substring(url.indexOf(":")+1)));
|
||||
|
||||
BitmapTileLayer rasterLayer = new BitmapTileLayer(this.vtmMap, mTileSource);
|
||||
return rasterLayer;
|
||||
}
|
||||
|
||||
// 初始化请求在线底图数据
|
||||
public Layer getDefaultVectorLayer(boolean useCache) {
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
if (useCache) {
|
||||
// Cache the tiles into file system
|
||||
File cacheDirectory = new File(defaultDir, "tiles-vector");
|
||||
int cacheSize = 200 * 1024 * 1024; // 200 MB
|
||||
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||
builder.cache(cache);
|
||||
}
|
||||
|
||||
NavinfoMultiMapFileTileSource tileSource = NavinfoMultiMapFileTileSource.builder()
|
||||
.apiKey("4wTLZyXcQym31pxC_HGy7Q") // Put a proper API key
|
||||
.httpFactory(new OkHttpEngine.OkHttpFactory(builder))
|
||||
//.locale("en")
|
||||
.build();
|
||||
HashMap<String, String> headerMap = new HashMap<>();
|
||||
headerMap.put("token", "eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnRJZCI6MTAzLCJ1c2VyTmFtZSI6ImFkbWluIiwidXNlcklkIjoxLCJ1c2VyR3JvdXAiOiLnoJTlj5Hpg6giLCJvcmdJZCI6MSwiaWF0IjoxNjMwOTk4MzI5LCJleHAiOjE2MzEwODQ3Mjl9.0wFm8mAA9dCC2FmZj-u1dhxTFDRYx8AqVnh2C88hitk");
|
||||
tileSource.setHttpRequestHeaders(headerMap);
|
||||
VectorTileLayer l = new VectorTileLayer(this.vtmMap, tileSource);
|
||||
return l;
|
||||
}
|
||||
|
||||
public void addLayer(String tag, Layer layer) {
|
||||
if (!layersMap.containsKey(tag)) {
|
||||
layersMap.put(tag, layer);
|
||||
vtmMap.layers().add(layer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addLayer(String tag, Layer layer, int group) {
|
||||
if (!layersMap.containsKey(tag)) {
|
||||
layersMap.put(tag, layer);
|
||||
vtmMap.layers().add(layer, group);
|
||||
}
|
||||
}
|
||||
|
||||
public void addLayer(int index, String tag, Layer layer) {
|
||||
if (!layersMap.containsKey(tag)) {
|
||||
layersMap.put(tag, layer);
|
||||
vtmMap.layers().add(index, layer);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsLayer(String tag) {
|
||||
return layersMap.containsKey(tag);
|
||||
}
|
||||
|
||||
public Layer getLayer(String tag) {
|
||||
return layersMap.get(tag);
|
||||
}
|
||||
|
||||
public void removeLayer(String tag) {
|
||||
if (layersMap.containsKey(tag)) {
|
||||
Layer layer = layersMap.remove(tag);
|
||||
vtmMap.layers().remove(layer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回默认marker图层
|
||||
*
|
||||
* @return mDefaultMarkerLayer
|
||||
*/
|
||||
public ItemizedLayer getDefaultMarkerLayer() {
|
||||
return mDefaultMarkerLayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回定位图层
|
||||
*
|
||||
* @return mLocationLayer
|
||||
*/
|
||||
public LocationLayer getLocationLayer() {
|
||||
return mLocationLayer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onItemSingleTapUp(int index, Object item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongPress(int index, Object item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 定位
|
||||
* @param lon
|
||||
* @param lat
|
||||
* @param time
|
||||
*/
|
||||
public void jumpToPosition(double lon, double lat, long time) {
|
||||
MapPosition mapPosition = vtmMap.getMapPosition();
|
||||
mapPosition.setPosition(lat, lon);
|
||||
vtmMap.animator().animateTo(time, mapPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* 定位
|
||||
* @param lon
|
||||
* @param lat
|
||||
* @param zoomLevel
|
||||
*/
|
||||
public void jumpToPosition(double lon, double lat, int zoomLevel) {
|
||||
MapPosition mapPosition = vtmMap.getMapPosition();
|
||||
if (mapPosition.getZoomLevel() < zoomLevel) {
|
||||
mapPosition.setZoomLevel(zoomLevel);
|
||||
}
|
||||
mapPosition.setPosition(lat, lon);
|
||||
vtmMap.animator().animateTo(300, mapPosition);
|
||||
}
|
||||
|
||||
public void addMarker2MarkerLayer(MarkerInterface markerItem, Bitmap defaultBitmap, String layerName, int layerGroup) {
|
||||
if (markerItem == null) {
|
||||
return;
|
||||
}
|
||||
if (vectorLayerMap != null) {
|
||||
if (!vectorLayerMap.containsKey(layerName) || vectorLayerMap.get(layerName) == null) {
|
||||
MarkerSymbol symbol = new MarkerSymbol(defaultBitmap, MarkerSymbol.HotspotPlace.BOTTOM_CENTER);
|
||||
vectorLayerMap.put(layerName, new ItemizedLayer(vtmMap, symbol));
|
||||
}
|
||||
|
||||
ItemizedLayer itemizedLayer = (ItemizedLayer) vectorLayerMap.get(layerName);
|
||||
itemizedLayer.addItem(markerItem);
|
||||
if (!vtmMap.layers().contains(itemizedLayer)) {
|
||||
vtmMap.layers().add(itemizedLayer, layerGroup);
|
||||
}
|
||||
itemizedLayer.update();
|
||||
}
|
||||
}
|
||||
|
||||
public void addMarker2MarkerLayer(MarkerInterface markerItem, Bitmap defaultBitmap, String layerName, int layerGroup, ItemizedLayer.OnItemGestureListener listener) {
|
||||
if (markerItem == null) {
|
||||
return;
|
||||
}
|
||||
if (vectorLayerMap != null) {
|
||||
if (!vectorLayerMap.containsKey(layerName) || vectorLayerMap.get(layerName) == null) {
|
||||
MarkerSymbol symbol = new MarkerSymbol(defaultBitmap, MarkerSymbol.HotspotPlace.BOTTOM_CENTER);
|
||||
vectorLayerMap.put(layerName, new ItemizedLayer(vtmMap, new ArrayList<MarkerInterface>(), symbol, listener));
|
||||
}
|
||||
|
||||
ItemizedLayer itemizedLayer = (ItemizedLayer) vectorLayerMap.get(layerName);
|
||||
itemizedLayer.addItem(markerItem);
|
||||
if (!vtmMap.layers().contains(itemizedLayer)) {
|
||||
vtmMap.layers().add(itemizedLayer, layerGroup);
|
||||
}
|
||||
itemizedLayer.update();
|
||||
}
|
||||
}
|
||||
|
||||
//删除marker
|
||||
public void removeMarker(MarkerItem markerItem) {
|
||||
if (vectorLayerMap != null && vectorLayerMap.containsKey("Marker")) {
|
||||
ItemizedLayer itemizedLayer = (ItemizedLayer) vectorLayerMap.get("Marker");
|
||||
if (itemizedLayer.getItemList() != null && itemizedLayer.getItemList().size() > 0) {
|
||||
itemizedLayer.removeItem(markerItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param markerItem marker
|
||||
* @param layerName 图层
|
||||
*/
|
||||
public void removeMarker(MarkerItem markerItem, String layerName) {
|
||||
if (vectorLayerMap != null && layerName != null && vectorLayerMap.containsKey(layerName)) {
|
||||
ItemizedLayer itemizedLayer = (ItemizedLayer) vectorLayerMap.get(layerName);
|
||||
if (itemizedLayer.getItemList() != null && itemizedLayer.getItemList().size() > 0) {
|
||||
itemizedLayer.removeItem(markerItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 在地图中心增加marker
|
||||
*/
|
||||
public void showEditMapGraphical(String geometry, int type) {
|
||||
|
||||
}
|
||||
|
||||
//增加marker
|
||||
public MarkerItem addMarker(GeoPoint geopoint, Bitmap bitmap) {
|
||||
if (geopoint != null && bitmap != null) {
|
||||
|
||||
MarkerItem markerItem = new MarkerItem(StringUtil.Companion.createUUID(), "", geopoint.getLatitude() + "," + geopoint.getLongitude(), geopoint);
|
||||
|
||||
MarkerSymbol markerSymbol = new MarkerSymbol(bitmap, MarkerSymbol.HotspotPlace.BOTTOM_CENTER);
|
||||
|
||||
markerItem.setMarker(markerSymbol);
|
||||
|
||||
addMarker2MarkerLayer(markerItem, bitmap, "", NIMapView.LAYER_GROUPS.OTHER.ordinal());
|
||||
|
||||
return markerItem;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Location getCurrentLocation() {
|
||||
return mCurrentLocation;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.navinfo.collect.library.map
|
||||
|
||||
import android.location.Location
|
||||
|
||||
|
||||
class NILocation(provider: String) : Location(provider) {
|
||||
var radius = 0f
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
package com.navinfo.collect.library.map;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.navinfo.collect.library.utils.CacheTileProgress;
|
||||
import com.navinfo.collect.library.utils.TileDownloader;
|
||||
import com.yanzhenjie.kalle.Kalle;
|
||||
import com.yanzhenjie.kalle.download.Download;
|
||||
|
||||
import org.oscim.core.GeoPoint;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.layers.Layer;
|
||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.tiling.source.UrlTileSource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* 定义 NavinfoMap 地图对象的操作方法与接口
|
||||
*/
|
||||
public class NIMap {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Map map;
|
||||
/**
|
||||
* 地图控件
|
||||
*/
|
||||
private NIMapView mMapView;
|
||||
/**
|
||||
* 指北针显隐
|
||||
*/
|
||||
private boolean enableCompassImage = true;
|
||||
|
||||
/**
|
||||
* 用户位置显示图层
|
||||
* */
|
||||
// private NaviLocationLayer locationLayer;
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public NIMap(NIMapView niMapView) {
|
||||
this.mMapView = niMapView;
|
||||
this.map = mMapView.getVtmMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地图的当前状态
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map getVtmMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地图最大缩放级别
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getMaxZoomLevel() {
|
||||
return map.viewport().getMaxZoomLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地图最小缩放级别
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getMinZoomLevel() {
|
||||
|
||||
return map.viewport().getMinZoomLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置指南针是否显示
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
public void setCompassEnable(boolean enable) {
|
||||
this.enableCompassImage = enable;
|
||||
if (mMapView != null && mMapView.getCompassImage() != null) {
|
||||
mMapView.getCompassImage().setVisibility(enable ? View.VISIBLE : View.GONE);
|
||||
mMapView.getCompassImage().setEnabled(enable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指北针显隐控制
|
||||
*
|
||||
* @return true 显示 false 隐藏
|
||||
*/
|
||||
public boolean isEnableCompassImage() {
|
||||
return enableCompassImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置指南针自定义图标
|
||||
*
|
||||
* @param icon
|
||||
*/
|
||||
public void setCompassIcon(Bitmap icon) {
|
||||
if (mMapView != null && mMapView.getCompassImage() != null) {
|
||||
mMapView.getCompassImage().setImageBitmap(icon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置地图显示大小等级
|
||||
*
|
||||
* @param level
|
||||
*/
|
||||
public void setFontSizeLevel(int level) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图最大以及最小缩放级别
|
||||
*
|
||||
* @param max
|
||||
* @param min
|
||||
*/
|
||||
public void setMaxAndMinZoomLevel(int max, int min) {
|
||||
map.viewport().setMaxZoomLevel(max);
|
||||
map.viewport().setMinZoomLevel(min);
|
||||
}
|
||||
|
||||
/**
|
||||
* 放大
|
||||
*
|
||||
* @param animate 是否动画过渡
|
||||
*/
|
||||
public void zoomIn(boolean animate) {
|
||||
MapPosition mapPosition = map.getMapPosition();
|
||||
mapPosition.setZoom(mapPosition.getZoom() + 1);
|
||||
if (animate) {
|
||||
map.animator().animateTo(mapPosition);
|
||||
} else {
|
||||
map.setMapPosition(mapPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩小地图
|
||||
*
|
||||
* @param animate 是否动画过渡
|
||||
*/
|
||||
public void zoomOut(boolean animate) {
|
||||
MapPosition mapPosition = map.getMapPosition();
|
||||
mapPosition.setZoom(mapPosition.getZoom() - 1);
|
||||
if (animate) {
|
||||
map.animator().animateTo(mapPosition);
|
||||
} else {
|
||||
map.setMapPosition(mapPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置定位数据, 只有先允许定位图层后设置数据才会生效,参见 setMyLocationEnabled(boolean)
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
// public void setMyLocationData(Location data) {
|
||||
// if (locationLayer == null) {
|
||||
// return;
|
||||
// }
|
||||
// locationLayer.setPosition(data.getLatitude(), data.getLongitude(), data.getAccuracy());
|
||||
// }
|
||||
|
||||
// public void setMyLocationData(double lat, double lon, float accuracy) {
|
||||
// if (locationLayer == null) {
|
||||
// return;
|
||||
// }
|
||||
// locationLayer.setPosition(lat, lon, accuracy);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 设置是否允许定位图层
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
// public void setMyLocationEnabled(Context mContext, boolean enabled) {
|
||||
// initLocaitonLayer(mContext);
|
||||
// locationLayer.setEnabled(enabled);
|
||||
// }
|
||||
|
||||
// private void initLocaitonLayer(Context mContext) {
|
||||
// if (map == null) {
|
||||
// throw new IllegalStateException("map不可用,无法显示当前位置!");
|
||||
// }
|
||||
// if (locationLayer == null) {
|
||||
// locationLayer = new NaviLocationLayer(mContext, map);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 设置地图
|
||||
* */
|
||||
public void setMapPosition(double latitude, double longitude, int zoomLevel) {
|
||||
double scale = 1 << zoomLevel;
|
||||
getVtmMap().setMapPosition(latitude, longitude, scale);
|
||||
}
|
||||
|
||||
public void animateMapPosition(double latitude, double longitude, int zoomLevel, int duration) {
|
||||
if (duration < 0) {
|
||||
duration = 500;
|
||||
}
|
||||
if (zoomLevel <= 0) {
|
||||
zoomLevel = getVtmMap().getMapPosition().zoomLevel;
|
||||
}
|
||||
double scale = 1 << zoomLevel;
|
||||
MapPosition mapPosition = new MapPosition(latitude, longitude, scale);
|
||||
getVtmMap().animator().animateTo(duration, mapPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载离线矢量地图
|
||||
* */
|
||||
public void downloadVectorMap(String url, DownloadProgress downloadProgress) {
|
||||
Kalle.Download.get(url).directory(NILayerManager.defaultDir).onProgress(new Download.ProgressBar() {
|
||||
@Override
|
||||
public void onProgress(int progress, long byteCount, long speed) {
|
||||
downloadProgress.onProgress(progress, byteCount, speed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存urlTilesource对应的数据
|
||||
* */
|
||||
public List<FutureTask> cacheUrlTileMap(Rect rect, int minZoomLevel, int maxZoomLevel, CacheTileProgress progress) {
|
||||
List<Layer> layerList = getVtmMap().layers();
|
||||
List<UrlTileSource> urlTileSourceList = new ArrayList<>();
|
||||
if (layerList!=null&&!layerList.isEmpty()) {
|
||||
for (int i = 0; i < layerList.size(); i++) {
|
||||
Layer layer = layerList.get(i);
|
||||
if (layer instanceof BitmapTileLayer && ((BitmapTileLayer) layer).getTileSource() instanceof UrlTileSource) {
|
||||
UrlTileSource urlTileSource = (UrlTileSource) ((BitmapTileLayer) layer).getTileSource();
|
||||
urlTileSourceList.add(urlTileSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 根据rect获取对应的地理坐标
|
||||
GeoPoint leftTopGeoPoint = map.viewport().fromScreenPoint(rect.left, rect.top);
|
||||
GeoPoint rightBottomGeoPoint = map.viewport().fromScreenPoint(rect.right, rect.bottom);
|
||||
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
|
||||
List<FutureTask> futureTaskList = new ArrayList<>();
|
||||
progress.setLayerCount(urlTileSourceList.size());
|
||||
for (int i = 0; i < urlTileSourceList.size(); i++) {
|
||||
UrlTileSource urlTileSource = urlTileSourceList.get(i);
|
||||
int finalI = i;
|
||||
progress.setLayerId(i);
|
||||
Callable callable = TileDownloader.getInstance().downloadRasterTile(urlTileSource, leftTopGeoPoint, rightBottomGeoPoint, (byte) minZoomLevel, (byte) maxZoomLevel, progress);
|
||||
FutureTask futureTask = new FutureTask(callable);
|
||||
futureTaskList.add(futureTask);
|
||||
}
|
||||
|
||||
if (futureTaskList!=null&&!futureTaskList.isEmpty()){
|
||||
for (int i = 0; i < futureTaskList.size(); i++) {
|
||||
scheduledExecutorService.submit(futureTaskList.get(i));
|
||||
}
|
||||
scheduledExecutorService.shutdown();
|
||||
}
|
||||
return futureTaskList;
|
||||
}
|
||||
|
||||
public void cancelCacheTileMap() {
|
||||
TileDownloader.getInstance().setCanDownloadRasterTile(false);
|
||||
}
|
||||
|
||||
public interface DownloadProgress {
|
||||
|
||||
Download.ProgressBar DEFAULT = new Download.ProgressBar() {
|
||||
@Override
|
||||
public void onProgress(int progress, long byteCount, long speed) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Download onProgress changes.
|
||||
*/
|
||||
void onProgress(int progress, long byteCount, long speed);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图单击事件监听者
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnMapClickListener(OnMapClickListener listener) {
|
||||
mMapView.setOnMapClickListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图双击事件监听者
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnMapDoubleClickListener(OnMapDoubleClickListener listener) {
|
||||
mMapView.setOnMapDoubleClickListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图长按事件监听者
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnMapLongClickListener(OnMapLongClickListener listener) {
|
||||
mMapView.setOnMapLongClickListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnMapTouchListener(OnMapTouchListener listener) {
|
||||
mMapView.setOnMapTouchListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图单击事件监听接口
|
||||
*/
|
||||
public static interface OnMapClickListener {
|
||||
/**
|
||||
* 地图单击事件回调函数
|
||||
*
|
||||
* @param point
|
||||
*/
|
||||
void onMapClick(GeoPoint point);
|
||||
|
||||
/**
|
||||
* 地图内 Poi 单击事件回调函数
|
||||
*
|
||||
* @param poi
|
||||
*/
|
||||
void onMapPoiClick(GeoPoint poi);
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图双击事件监听接口
|
||||
*/
|
||||
public static interface OnMapDoubleClickListener {
|
||||
|
||||
/**
|
||||
* 地图双击事件监听回调函数
|
||||
*
|
||||
* @param point
|
||||
*/
|
||||
void onMapDoubleClick(GeoPoint point);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图长按事件监听接口
|
||||
*/
|
||||
public static interface OnMapLongClickListener {
|
||||
/**
|
||||
* 地图长按事件监听回调函数
|
||||
*
|
||||
* @param point
|
||||
*/
|
||||
void onMapLongClick(GeoPoint point);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户触摸地图时回调接口
|
||||
*/
|
||||
public static interface OnMapTouchListener {
|
||||
/**
|
||||
* 当用户触摸地图时回调函数
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
void onTouch(MotionEvent event);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.navinfo.collect.library.map
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.handler.*
|
||||
import com.navinfo.collect.library.map.maphandler.MeasureLayerHandler
|
||||
import com.navinfo.collect.library.map.handler.ViewportHandler
|
||||
|
||||
/**
|
||||
* 地图控制器
|
||||
*/
|
||||
|
||||
open class NIMapController(
|
||||
context: Context,
|
||||
options: NIMapOptions? = null,
|
||||
mapView: NIMapView? = null,
|
||||
) {
|
||||
private val mContext = context
|
||||
internal var mMapView: NIMapView =
|
||||
mapView ?: NIMapView(mContext, options)
|
||||
|
||||
val animationHandler: AnimationHandler by lazy { AnimationHandler(mContext, mMapView) }
|
||||
val markerHandle: MarkHandler by lazy { MarkHandler(mContext, mMapView) }
|
||||
val locationLayerHandler: LocationLayerHandler by lazy {
|
||||
LocationLayerHandler(
|
||||
mContext,
|
||||
mMapView
|
||||
)
|
||||
};
|
||||
val lineHandler: LineHandler by lazy { LineHandler(mContext, mMapView) };
|
||||
val polygonHandler: PolygonHandler by lazy { PolygonHandler(mContext, mMapView) };
|
||||
val viewportHandler: ViewportHandler by lazy { ViewportHandler(mContext, mMapView) }
|
||||
val measureLayerHandler: MeasureLayerHandler by lazy { MeasureLayerHandler(mContext, mMapView) };
|
||||
|
||||
|
||||
/**
|
||||
* 刷新地图
|
||||
*/
|
||||
fun upDateMap(redraw: Boolean = true) {
|
||||
if (redraw) {
|
||||
mMapView.vtmMap.events.fire(org.oscim.map.Map.CLEAR_EVENT, mMapView.vtmMap.mapPosition)
|
||||
}
|
||||
mMapView.vtmMap.updateMap(redraw)
|
||||
}
|
||||
|
||||
open fun release() {
|
||||
mMapView.onDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.navinfo.collect.library.map;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.navinfo.collect.library.R;
|
||||
import com.navinfo.collect.library.data.entity.Element;
|
||||
import com.navinfo.collect.library.utils.GeometryTools;
|
||||
import org.oscim.core.GeoPoint;
|
||||
import org.oscim.core.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class NIMapCopyView extends View {
|
||||
|
||||
Paint paint;
|
||||
|
||||
private List<Element> pointList = new ArrayList<>();
|
||||
private Map<String, Bitmap> bitmapMap = new HashMap<>();
|
||||
private Map<String, List<Point>> linesMap = new HashMap<>();
|
||||
private NIMapView mNiMapView;
|
||||
|
||||
public NIMapCopyView(Context context, NIMapView mapView) {
|
||||
this(context, null, 0);
|
||||
this.mNiMapView = mapView;
|
||||
}
|
||||
|
||||
public NIMapCopyView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, -1);
|
||||
}
|
||||
|
||||
public NIMapCopyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, -1);
|
||||
}
|
||||
|
||||
public NIMapCopyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
paint = new Paint();
|
||||
paint.setColor(context.getColor(R.color.default_red));
|
||||
paint.setStrokeWidth(5);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
for (Element element : pointList) {
|
||||
List<Point> lines = linesMap.get(element.getId());
|
||||
if (lines != null && lines.size() > 0) {
|
||||
for (int i = 0; i < lines.size() - 1; i++) {
|
||||
canvas.drawLine((float) lines.get(i).x, (float) lines.get(i).y,
|
||||
(float) lines.get(i + 1).x, (float) lines.get(i + 1).y, paint);
|
||||
|
||||
}
|
||||
Bitmap bitmap = bitmapMap.get(element.getId());
|
||||
if (bitmap != null) {
|
||||
canvas.drawBitmap(bitmap, (float) lines.get(0).x - bitmap.getWidth() / 2, (float) lines.get(0).y - bitmap.getHeight(), paint);
|
||||
}
|
||||
bitmapMap.remove(element.getId());
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPointList(List<Element> pointList) {
|
||||
if (pointList == null || pointList.size() == 0) {
|
||||
this.pointList.clear();
|
||||
this.bitmapMap.clear();
|
||||
this.linesMap.clear();
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
this.pointList = pointList;
|
||||
initData(pointList);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void initData(List<Element> pointList) {
|
||||
for (Element element : pointList) {
|
||||
List<GeoPoint> list = GeometryTools.getGeoPoints(element.getGeometry());
|
||||
List<Point> lines = new ArrayList<>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
GeoPoint geoPoint = list.get(i);
|
||||
Point point1 = new Point();
|
||||
this.mNiMapView.getVtmMap().viewport().toScreenPoint(geoPoint, false, point1);
|
||||
lines.add(point1);
|
||||
}
|
||||
linesMap.put(element.getId(), lines);
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), getBitmapId(element));
|
||||
bitmapMap.put(element.getId(), bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
private int getBitmapId(Element element) {
|
||||
int resId = -1;
|
||||
if (element.getTStatus() == 2) {
|
||||
if (element.getTLifecycle() == 0) {
|
||||
if (resId == -1) {
|
||||
resId = R.mipmap.map_icon_line_pr;
|
||||
}
|
||||
} else {
|
||||
if (resId == -1) {
|
||||
resId = R.mipmap.map_icon_line_add;
|
||||
}
|
||||
}
|
||||
} else if (element.getTStatus() == 3) {
|
||||
if (element.getTLifecycle() == 0) {
|
||||
if (resId == -1) {
|
||||
resId = R.mipmap.map_icon_polygon_pr;
|
||||
}
|
||||
} else {
|
||||
if (resId == -1) {
|
||||
resId = R.mipmap.map_icon_polygon_add;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (element.getTLifecycle() == 0) {
|
||||
if (resId == -1) {
|
||||
resId = R.mipmap.map_icon_point_pr;
|
||||
}
|
||||
} else {
|
||||
if (resId == -1) {
|
||||
resId = R.mipmap.map_icon_point_add;
|
||||
}
|
||||
}
|
||||
}
|
||||
return resId;
|
||||
}
|
||||
|
||||
public Map<String, List<GeoPoint>> getGeoPointsMap() {
|
||||
Map<String, List<GeoPoint>> map = new HashMap<>();
|
||||
|
||||
for (Element element : pointList) {
|
||||
List<GeoPoint> list = new ArrayList<>();
|
||||
List<Point> lines = linesMap.get(element.getId());
|
||||
if (lines.size() > 0) {
|
||||
for (Point point : lines) {
|
||||
GeoPoint geoPoint = this.mNiMapView.getVtmMap().viewport().fromScreenPoint((float) point.x, (float) point.y);
|
||||
list.add(geoPoint);
|
||||
}
|
||||
}
|
||||
map.put(element.getId(), list);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.navinfo.collect.library.map
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
|
||||
data class NIMapOptions(
|
||||
val showCompassControl: Boolean = true,//指南针是否显示
|
||||
val showZoomControl: Boolean = true, //是否显示zoom按钮
|
||||
val zoomLevel: Double = 13.0, /// 地图比例尺初始级别
|
||||
val coordinate: NICoordinate = NICoordinate(39.907375, 116.391349),
|
||||
) {
|
||||
companion object {
|
||||
fun fromJson(json: String): NIMapOptions {
|
||||
var options: NIMapOptions
|
||||
try {
|
||||
val json = JSONObject(json)
|
||||
val showCompassControl = json.optBoolean("showZoomControl", true)
|
||||
val showZoomControl = json.optBoolean("showZoomControl", true)
|
||||
val zoomLevel = json.optDouble("zoomLevel", 13.0)
|
||||
val geometryObject = json.optJSONObject("coordinate")
|
||||
var coor = NICoordinate.fromJson(geometryObject)
|
||||
if (coor == null)
|
||||
coor == NICoordinate(39.907375, 116.391349)
|
||||
options = NIMapOptions(
|
||||
showCompassControl = showCompassControl,
|
||||
showZoomControl = showZoomControl,
|
||||
zoomLevel = zoomLevel,
|
||||
coordinate = coor!!,
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
options = NIMapOptions()
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
data class NICoordinate(val latitude: Double, val longitude: Double) {
|
||||
companion object {
|
||||
fun fromJson(json: JSONObject): NICoordinate? {
|
||||
try {
|
||||
return NICoordinate(
|
||||
json.optDouble("latitude"), json.optDouble("longitude")
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,924 @@
|
||||
package com.navinfo.collect.library.map;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.navinfo.collect.library.R;
|
||||
import com.navinfo.collect.library.map.layers.NaviMapScaleBar;
|
||||
import com.navinfo.collect.library.map.source.MapLifeDBTileSource;
|
||||
import com.navinfo.collect.library.map.source.MapLifeNiLocationTileDataSource;
|
||||
import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource;
|
||||
import com.navinfo.collect.library.system.Constant;
|
||||
|
||||
import org.oscim.android.MapPreferences;
|
||||
import org.oscim.android.MapView;
|
||||
import org.oscim.core.GeoPoint;
|
||||
import org.oscim.android.theme.AssetsRenderTheme;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.event.Event;
|
||||
import org.oscim.event.Gesture;
|
||||
import org.oscim.event.GestureListener;
|
||||
import org.oscim.layers.GroupLayer;
|
||||
import org.oscim.layers.Layer;
|
||||
import org.oscim.layers.TileGridLayer;
|
||||
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||
import org.oscim.layers.tile.vector.OsmTileLayer;
|
||||
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.renderer.GLViewport;
|
||||
import org.oscim.theme.IRenderTheme;
|
||||
import org.oscim.theme.ThemeLoader;
|
||||
import org.oscim.theme.VtmThemes;
|
||||
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
||||
import org.oscim.tiling.source.mapfile.MultiMapFileTileSource;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 一个显示地图的视图(View)。它负责从服务端获取地图数据。它将会捕捉屏幕触控手势事件
|
||||
*/
|
||||
public final class NIMapView extends RelativeLayout {
|
||||
/**
|
||||
* VTM地图
|
||||
*/
|
||||
private MapView mapView;
|
||||
/**
|
||||
* NavinfoMap 地图对象的操作方法与接口
|
||||
*/
|
||||
// private NIMap map;
|
||||
|
||||
/**
|
||||
* 定位图标
|
||||
*/
|
||||
protected ImageView compassImage;
|
||||
|
||||
/**
|
||||
* logo图标
|
||||
*/
|
||||
protected ImageView logoImage;
|
||||
|
||||
/**
|
||||
* 图片旋转
|
||||
*/
|
||||
private NIRotateAnimation mRotateAnimation;
|
||||
|
||||
/**
|
||||
* 之前的旋转角度
|
||||
*/
|
||||
private float mLastRotateZ = 0;
|
||||
|
||||
/**
|
||||
* 缩放按钮
|
||||
*/
|
||||
private ImageView zoomInImage, zoomOutImage;
|
||||
private View zoomLayout;
|
||||
|
||||
/**
|
||||
* 地图状态设置
|
||||
*/
|
||||
private NIMapOptions options;
|
||||
/**
|
||||
* 地图图层管理器
|
||||
*/
|
||||
private NILayerManager mLayerManager;
|
||||
private Layer baseRasterLayer, defaultVectorTileLayer, defaultVectorLabelLayer, gridLayer;
|
||||
protected Context mContext;
|
||||
|
||||
private MapPreferences mPrefs;
|
||||
protected String mapFilePath = Constant.ROOT_PATH+"/map";
|
||||
protected GroupLayer baseGroupLayer; // 用于盛放所有基础底图的图层组,便于统一管理
|
||||
|
||||
public NIMapView(Context context, NIMapOptions options) {
|
||||
this(context, null, 0);
|
||||
this.options = options;
|
||||
initOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图的单击事件监听
|
||||
*/
|
||||
private NIMap.OnMapClickListener mapClickListener;
|
||||
|
||||
/**
|
||||
* 地图的双击事件监听
|
||||
*/
|
||||
private NIMap.OnMapDoubleClickListener mapDoubleClickListener;
|
||||
|
||||
/**
|
||||
* 地图的长按事件监听
|
||||
*/
|
||||
private NIMap.OnMapLongClickListener mapLongClickListener;
|
||||
|
||||
/**
|
||||
* 地图的触摸事件
|
||||
*/
|
||||
private NIMap.OnMapTouchListener touchListener;
|
||||
|
||||
public NIMapView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public NIMapView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public NIMapView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
initView(context);
|
||||
}
|
||||
|
||||
private void initView(Context context) {
|
||||
View rootView = LayoutInflater.from(context).inflate(R.layout.base_map_layout, this, true);
|
||||
this.mContext = context;
|
||||
|
||||
mapView = rootView.findViewById(R.id.base_map_view);
|
||||
// map = new NIMap(this);
|
||||
compassImage = rootView.findViewById(R.id.navinfo_map_compass);
|
||||
initMapGroup(); // 初始化图层组
|
||||
|
||||
mLayerManager = new NILayerManager(context, getVtmMap());
|
||||
|
||||
logoImage = rootView.findViewById(R.id.navinfo_map_logo);
|
||||
mRotateAnimation = new NIRotateAnimation(compassImage);
|
||||
mPrefs = new MapPreferences(NIMapView.class.getName(), mContext);
|
||||
getVtmMap().events.bind(new Map.UpdateListener() {
|
||||
@Override
|
||||
public void onMapEvent(Event e, MapPosition mapPosition) {
|
||||
//旋转
|
||||
if (mLastRotateZ != mapPosition.bearing) {
|
||||
mRotateAnimation.startRotationZ(mLastRotateZ, mapPosition.bearing);
|
||||
mLastRotateZ = mapPosition.bearing;
|
||||
}
|
||||
|
||||
//增加控制联动效果
|
||||
// if (map != null && map.isEnableCompassImage()) {
|
||||
//2D,正北隐藏
|
||||
if (compassImage.getVisibility() != View.VISIBLE && (mapPosition.tilt != 0 || mapPosition.bearing != 0)) {
|
||||
compassImage.setVisibility(View.VISIBLE);
|
||||
} else if (compassImage.getVisibility() == View.VISIBLE && mapPosition.tilt == 0 && mapPosition.bearing == 0) {
|
||||
compassImage.clearAnimation();
|
||||
compassImage.setVisibility(View.GONE);
|
||||
}
|
||||
// } else {
|
||||
// compassImage.clearAnimation();
|
||||
// compassImage.setVisibility(View.GONE);
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
// 增加比例尺图层
|
||||
NaviMapScaleBar naviMapScaleBar = new NaviMapScaleBar(getVtmMap());
|
||||
naviMapScaleBar.initScaleBarLayer(GLViewport.Position.BOTTOM_LEFT, 25, 60);
|
||||
|
||||
if (gridLayer == null) {
|
||||
gridLayer = new TileGridLayer(getVtmMap());
|
||||
getVtmMap().layers().add(gridLayer, LAYER_GROUPS.ALLWAYS_SHOW_GROUP.groupIndex);
|
||||
gridLayer.setEnabled(false);
|
||||
}
|
||||
|
||||
compassImage.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MapPosition mapPosition = getVtmMap().getMapPosition();
|
||||
mapPosition.setBearing(0);
|
||||
mapPosition.setTilt(0);
|
||||
getVtmMap().animator().animateTo(300, mapPosition);
|
||||
}
|
||||
});
|
||||
|
||||
zoomInImage = rootView.findViewById(R.id.navinfo_map_zoom_in);
|
||||
zoomInImage.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
zoomIn(arg0);
|
||||
}
|
||||
});
|
||||
|
||||
zoomOutImage = rootView.findViewById(R.id.navinfo_map_zoom_out);
|
||||
zoomOutImage.setImageResource(R.drawable.icon_map_zoom_out);
|
||||
zoomOutImage.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
zoomOut(arg0);
|
||||
}
|
||||
});
|
||||
|
||||
mapView.setOnTouchListener(new OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (touchListener != null) {
|
||||
touchListener.onTouch(event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
zoomLayout = rootView.findViewById(R.id.navinfo_map_zoom_layer);
|
||||
initMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图初始化参数
|
||||
*/
|
||||
private void initOptions() {
|
||||
if (options != null) {
|
||||
if (options.getShowZoomControl()) {
|
||||
zoomLayout.setVisibility(VISIBLE);
|
||||
} else {
|
||||
zoomLayout.setVisibility(GONE);
|
||||
}
|
||||
MapPosition mapPosition = getVtmMap().getMapPosition();
|
||||
mapPosition.setZoom(options.getZoomLevel());
|
||||
mapPosition.setPosition(options.getCoordinate().getLatitude(), options.getCoordinate().getLongitude());
|
||||
getVtmMap().animator().animateTo(100, mapPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
*/
|
||||
private void initMap() {
|
||||
switchBaseMapType(BASE_MAP_TYPE.CYCLE_MAP);
|
||||
switchTileVectorLayerTheme(MAP_THEME.DEFAULT);
|
||||
initVectorTileLayer();
|
||||
initMapLifeSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加作业渲染
|
||||
*/
|
||||
LabelLayer labelLayer;
|
||||
/**
|
||||
* 作业数据图层
|
||||
*/
|
||||
VectorTileLayer vectorTileLayer;
|
||||
/**
|
||||
* 作业数据渲染图层
|
||||
*/
|
||||
MapLifeDBTileSource mapLifeDBTileSource;
|
||||
/**
|
||||
* 轨迹渲染图层
|
||||
*/
|
||||
MapLifeNiLocationTileSource mapLifeNiLocationTileSource;
|
||||
/**
|
||||
* 轨迹数据图层
|
||||
*/
|
||||
VectorTileLayer vectorNiLocationTileLayer;
|
||||
/**
|
||||
* 增加作业渲染
|
||||
*/
|
||||
LabelLayer labelNiLocationLayer;
|
||||
|
||||
public void initMapLifeSource() {
|
||||
mapLifeDBTileSource = new MapLifeDBTileSource(this.mContext, Constant.ROOT_PATH + "/coremap.db");
|
||||
mapLifeNiLocationTileSource = new MapLifeNiLocationTileSource(this.mContext,Constant.ROOT_PATH + "/coremap.db");
|
||||
vectorTileLayer = new VectorTileLayer(mapView.map(), mapLifeDBTileSource);
|
||||
vectorNiLocationTileLayer = new VectorTileLayer(mapView.map(),mapLifeNiLocationTileSource);
|
||||
mapView.map().layers().add(vectorNiLocationTileLayer,LAYER_GROUPS.VECTOR_TILE.groupIndex);
|
||||
mapView.map().layers().add(vectorTileLayer,LAYER_GROUPS.VECTOR_TILE.groupIndex);
|
||||
labelLayer = new LabelLayer(mapView.map(), vectorTileLayer, new LabelTileLoaderHook(), 15);
|
||||
mapView.map().layers().add(labelLayer,LAYER_GROUPS.VECTOR_TILE.groupIndex);
|
||||
labelNiLocationLayer = new LabelLayer(mapView.map(), vectorNiLocationTileLayer, new LabelTileLoaderHook(), 15);
|
||||
mapView.map().layers().add(labelNiLocationLayer,LAYER_GROUPS.VECTOR_TILE.groupIndex);
|
||||
|
||||
switchTileVectorLayerTheme(null);
|
||||
mapView.map().updateMap(true);
|
||||
MapPosition mapPosition = new MapPosition();
|
||||
mapPosition.setZoomLevel(18);
|
||||
mapPosition.setPosition(40.091692296269144, 116.26712172082546);
|
||||
//116.26712172082546 40.091692296269144
|
||||
mapView.map().animator().animateTo(mapPosition);
|
||||
}
|
||||
|
||||
public void dataLayerUpdate() {
|
||||
switchTileVectorLayerTheme(null);
|
||||
}
|
||||
|
||||
private void initMapGroup() {
|
||||
for (LAYER_GROUPS groups : LAYER_GROUPS.values()) {
|
||||
getVtmMap().layers().addGroup(groups.groupIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换基础底图样式
|
||||
*/
|
||||
public void switchBaseMapType(BASE_MAP_TYPE type) {
|
||||
if (baseRasterLayer != null) {
|
||||
getVtmMap().layers().remove(baseRasterLayer);
|
||||
baseRasterLayer = null;
|
||||
getVtmMap().updateMap();
|
||||
}
|
||||
baseRasterLayer = mLayerManager.getRasterTileLayer(mContext, type.url, type.tilePath, true);
|
||||
getVtmMap().layers().add(baseRasterLayer, LAYER_GROUPS.BASE_RASTER.groupIndex);
|
||||
getVtmMap().updateMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除基础底图样式
|
||||
*/
|
||||
public void removeBaseMap() {
|
||||
if (baseRasterLayer != null) {
|
||||
getVtmMap().layers().remove(baseRasterLayer);
|
||||
baseRasterLayer = null;
|
||||
getVtmMap().updateMap();
|
||||
}
|
||||
}
|
||||
|
||||
public void initVectorTileLayer(){
|
||||
if (baseGroupLayer == null) {
|
||||
baseGroupLayer = new GroupLayer(getVtmMap());
|
||||
}
|
||||
for (Layer layer : baseGroupLayer.layers) {
|
||||
getVtmMap().layers().remove(layer);
|
||||
}
|
||||
baseGroupLayer.layers.clear();
|
||||
|
||||
File baseMapFolder = new File(mapFilePath);
|
||||
if (!baseMapFolder.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
File[] mapFileList = baseMapFolder.listFiles();
|
||||
|
||||
if (mapFileList != null && mapFileList.length > 0) {
|
||||
|
||||
MultiMapFileTileSource multiMapFileTileSource = new MultiMapFileTileSource();
|
||||
|
||||
for (File mapFile : mapFileList) {
|
||||
|
||||
if (!mapFile.exists() || !mapFile.getName().endsWith(".map")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MapFileTileSource mTileSource = new MapFileTileSource();
|
||||
|
||||
mTileSource.setPreferredLanguage("zh");
|
||||
|
||||
if (mTileSource.setMapFile(mapFile.getAbsolutePath())) {
|
||||
multiMapFileTileSource.add(mTileSource);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VectorTileLayer baseMapLayer = new OsmTileLayer(getVtmMap());
|
||||
baseMapLayer.setTileSource(multiMapFileTileSource);
|
||||
|
||||
baseGroupLayer.layers.add(baseMapLayer);
|
||||
|
||||
if (getTheme(null) != null)
|
||||
baseMapLayer.setTheme(getTheme(null));
|
||||
|
||||
baseGroupLayer.layers.add(new BuildingLayer(getVtmMap(), baseMapLayer));
|
||||
baseGroupLayer.layers.add(new LabelLayer(getVtmMap(), baseMapLayer));
|
||||
|
||||
for (Layer layer : baseGroupLayer.layers) {
|
||||
if (layer instanceof LabelLayer) {
|
||||
getVtmMap().layers().add(layer, LAYER_GROUPS.VECTOR.groupIndex);
|
||||
} else {
|
||||
getVtmMap().layers().add(layer, LAYER_GROUPS.BASE_VECTOR.groupIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取渲染资源
|
||||
public IRenderTheme getTheme(final String styleId) {
|
||||
AssetsRenderTheme theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
|
||||
if (styleId == null || "".equals(styleId.trim())) {
|
||||
switch (2) {
|
||||
case 0:
|
||||
theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
|
||||
break;
|
||||
case 1:
|
||||
theme = new AssetsRenderTheme(mContext.getAssets(), null, "osmarender.xml");
|
||||
break;
|
||||
case 2:
|
||||
theme = new AssetsRenderTheme(mContext.getAssets(), null, "tronrender.xml");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ThemeLoader.load(theme);
|
||||
}
|
||||
|
||||
public void addDefaultVectorTileLayer(MAP_THEME theme) {
|
||||
if (defaultVectorTileLayer != null) {
|
||||
getVtmMap().layers().remove(defaultVectorTileLayer);
|
||||
defaultVectorTileLayer = null;
|
||||
getVtmMap().updateMap();
|
||||
}
|
||||
defaultVectorTileLayer = mLayerManager.getDefaultVectorLayer(true);
|
||||
getVtmMap().layers().add(defaultVectorTileLayer, LAYER_GROUPS.VECTOR_TILE.groupIndex);
|
||||
defaultVectorLabelLayer = new LabelLayer(getVtmMap(), (VectorTileLayer) defaultVectorTileLayer);
|
||||
getVtmMap().layers().add(defaultVectorLabelLayer, LAYER_GROUPS.VECTOR_TILE.groupIndex);
|
||||
if (theme != null) {
|
||||
switchTileVectorLayerTheme(theme);
|
||||
}
|
||||
getVtmMap().updateMap();
|
||||
}
|
||||
|
||||
public void setBaseRasterVisiable(boolean visiable) {
|
||||
if (baseRasterLayer != null) {
|
||||
baseRasterLayer.setEnabled(visiable);
|
||||
getVtmMap().updateMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础
|
||||
*/
|
||||
public enum BASE_MAP_TYPE {
|
||||
OPEN_STREET_MAP("Open Street Map", "http://a.tile.openstreetmap.org", "/{Z}}/{X}/{Y}.png"), // openStreetMap底图
|
||||
CYCLE_MAP("Cycle Map", "http://c.tile.opencyclemap.org/cycle", "/{Z}}/{X}/{Y}.png"), // cyclemap底图
|
||||
S_MAP("SMap", "http://smap.navinfo.com/gateway/smap-raster-map/raster/basemap/tile", "z={Z}&x={X}&y={Y}"), // cyclemap底图
|
||||
TRANSPORT_MAP("Transport Map", "http://b.tile2.opencyclemap.org/transport", "/{Z}}/{X}/{Y}.png"); // TransportMap底图
|
||||
String title;
|
||||
String url;
|
||||
String tilePath;
|
||||
|
||||
BASE_MAP_TYPE(String title, String url, String tilePath) {
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.tilePath = tilePath;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getTilePath() {
|
||||
return tilePath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 网格图层是否显示
|
||||
*/
|
||||
public void setGridLayerVisiable(boolean visiable) {
|
||||
if (gridLayer != null) {
|
||||
gridLayer.setEnabled(visiable);
|
||||
getVtmMap().updateMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 图层组定义
|
||||
*/
|
||||
public enum LAYER_GROUPS {
|
||||
BASE_RASTER(0)/*栅格底图*/, BASE_VECTOR(1)/*矢量底图*/,
|
||||
RASTER_TILE(2)/*栅格网格*/, VECTOR_TILE(3)/*矢量网格*/,
|
||||
VECTOR(4)/*矢量图层组*/, OTHER(5)/*其他图层*/,
|
||||
ALLWAYS_SHOW_GROUP(6), OPERATE(7)/*操作图层组*/;
|
||||
int groupIndex;
|
||||
|
||||
LAYER_GROUPS(int groupIndex) {
|
||||
this.groupIndex = groupIndex;
|
||||
}
|
||||
|
||||
public int getGroupIndex() {
|
||||
return groupIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
}
|
||||
|
||||
public enum GRAVITY {
|
||||
LEFT_TOP,
|
||||
RIGHT_TOP,
|
||||
LEFT_BOTTOM,
|
||||
RIGHT_BOTTOM
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户重载这个方法时必须调用父类的这个方法 用于NIMapView保存地图状态
|
||||
*
|
||||
* @param context
|
||||
* @param bundle
|
||||
*/
|
||||
public void onCreate(Context context, Bundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 当Activity暂停的时候调用地图暂停
|
||||
*/
|
||||
public void onPause() {
|
||||
if (mapView != null) {
|
||||
if (mPrefs != null)
|
||||
mPrefs.save(getVtmMap());
|
||||
mapView.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当Activity唤醒时调用地图唤醒
|
||||
*/
|
||||
public void onResume() {
|
||||
if (mapView != null) {
|
||||
if (mPrefs != null)
|
||||
mPrefs.load(getVtmMap());
|
||||
mapView.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户重载这个方法时必须调用父类的这个方法 用于NIMapView保存地图状态
|
||||
*
|
||||
* @param bundle
|
||||
*/
|
||||
public void onSaveInstanceState(Bundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 当Activity销毁时调用地图的销毁
|
||||
*/
|
||||
public void onDestroy() {
|
||||
try{
|
||||
if (mapView != null) {
|
||||
mapView.onDestroy();
|
||||
}
|
||||
}catch (Exception e){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param child
|
||||
* @param params
|
||||
*/
|
||||
public void addView(View child, ViewGroup.LayoutParams params) {
|
||||
super.addView(child, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从NIMapView中移除一个子View
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
public void removeView(View view) {
|
||||
super.removeView(view);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取地图控制器
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
// public NIMap getMap() {
|
||||
// return map;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取VTM-Map
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map getVtmMap() {
|
||||
if (mapView != null)
|
||||
return mapView.map();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前地图级别对应比例尺大小
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getMapLevel() {
|
||||
|
||||
if (mapView != null && mapView.map() != null)
|
||||
return mapView.map().getMapPosition().getZoomLevel();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param view
|
||||
*/
|
||||
public void zoomIn(View view) {
|
||||
if (view != null) {
|
||||
if (view.isEnabled()) {
|
||||
MapPosition mapPosition = mapView.map().getMapPosition();
|
||||
mapPosition.setZoom(mapPosition.getZoom() + 1);
|
||||
mapView.map().animator().animateTo(mapPosition);
|
||||
// map.zoomIn(true);
|
||||
}
|
||||
view.setEnabled(false);
|
||||
view.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
view.setEnabled(true);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param view
|
||||
*/
|
||||
public void zoomOut(View view) {
|
||||
if (view != null) {
|
||||
if (view.isEnabled()) {
|
||||
MapPosition mapPosition = mapView.map().getMapPosition();
|
||||
mapPosition.setZoom(mapPosition.getZoom() - 1);
|
||||
mapView.map().animator().animateTo(mapPosition);
|
||||
|
||||
// map.zoomOut(true);
|
||||
}
|
||||
view.setEnabled(false);
|
||||
view.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
view.setEnabled(true);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置MotionEvent
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void setUpViewEventToNIMapView(MotionEvent event) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缩放按钮位置
|
||||
*
|
||||
* @param position 按钮位置
|
||||
*/
|
||||
public void setZoomControlPosition(GRAVITY position) {
|
||||
if (zoomLayout != null) {
|
||||
setLayoutParams(position, zoomLayout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缩放按钮位置
|
||||
*
|
||||
* @param position 按钮位置
|
||||
*/
|
||||
public void setLogoPosition(GRAVITY position) {
|
||||
if (logoImage != null) {
|
||||
setLayoutParams(position, logoImage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缩放按钮位置
|
||||
*
|
||||
* @param position 按钮位置
|
||||
*/
|
||||
public void setCompassPosition(GRAVITY position) {
|
||||
if (compassImage != null) {
|
||||
setLayoutParams(position, compassImage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据GRAVITY生成对应的layoutParams
|
||||
*
|
||||
* @param position 按钮相对于父布局的位置
|
||||
* @param view 被设置显示位置的view
|
||||
*/
|
||||
private void setLayoutParams(GRAVITY position, View view) {
|
||||
LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
|
||||
if (layoutParams.getRules() != null) {
|
||||
for (int i = 0; i < layoutParams.getRules().length; i++) {
|
||||
layoutParams.removeRule(i);
|
||||
}
|
||||
}
|
||||
switch (position) {
|
||||
case LEFT_TOP:
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
|
||||
break;
|
||||
case RIGHT_TOP:
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
|
||||
break;
|
||||
case LEFT_BOTTOM:
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
|
||||
break;
|
||||
case RIGHT_BOTTOM:
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
|
||||
break;
|
||||
}
|
||||
view.setLayoutParams(layoutParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否显示缩放控件
|
||||
*
|
||||
* @param show
|
||||
*/
|
||||
public void showZoomControls(boolean show) {
|
||||
if (zoomLayout != null) {
|
||||
if (show) {
|
||||
zoomLayout.setVisibility(VISIBLE);
|
||||
} else {
|
||||
zoomLayout.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否显示缩放控件
|
||||
*
|
||||
* @param show
|
||||
*/
|
||||
public void showCompass(boolean show) {
|
||||
// if (map != null) {
|
||||
// map.setCompassEnable(show);
|
||||
// }
|
||||
if (compassImage != null) {
|
||||
compassImage.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
compassImage.setEnabled(show);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指北针
|
||||
*/
|
||||
protected ImageView getCompassImage() {
|
||||
return compassImage;
|
||||
}
|
||||
|
||||
|
||||
public enum MAP_THEME {
|
||||
DEFAULT(0), NEWTRON(1), OSMAGRAY(2),
|
||||
OSMARENDER(3), TRONRENDER(4);
|
||||
int themeId;
|
||||
|
||||
MAP_THEME(int themeId) {
|
||||
this.themeId = themeId;
|
||||
}
|
||||
|
||||
public MAP_THEME getMapTheme(int themeId) {
|
||||
MAP_THEME theme = DEFAULT;
|
||||
switch (themeId) {
|
||||
case 1:
|
||||
theme = NEWTRON;
|
||||
break;
|
||||
case 2:
|
||||
theme = OSMAGRAY;
|
||||
break;
|
||||
case 3:
|
||||
theme = OSMARENDER;
|
||||
break;
|
||||
case 4:
|
||||
theme = TRONRENDER;
|
||||
break;
|
||||
}
|
||||
return theme;
|
||||
}
|
||||
}
|
||||
|
||||
public void switchTileVectorLayerTheme(MAP_THEME styleId) {
|
||||
// 如果不包含vectorlayer,则设置theme无效
|
||||
boolean bHis = false;
|
||||
for (Layer layer : getVtmMap().layers()) {
|
||||
if (layer instanceof VectorTileLayer) {
|
||||
bHis = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bHis) {
|
||||
getVtmMap().updateMap(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (styleId == null) {
|
||||
getVtmMap().setTheme(new AssetsRenderTheme(mContext.getAssets(), "", "navdefault.xml"), true);
|
||||
} else {
|
||||
switch (styleId) {
|
||||
case NEWTRON:
|
||||
getVtmMap().setTheme(VtmThemes.NEWTRON, true);
|
||||
break;
|
||||
case OSMAGRAY:
|
||||
getVtmMap().setTheme(VtmThemes.OSMAGRAY, true);
|
||||
break;
|
||||
case OSMARENDER:
|
||||
getVtmMap().setTheme(VtmThemes.OSMARENDER, true);
|
||||
break;
|
||||
case TRONRENDER:
|
||||
getVtmMap().setTheme(VtmThemes.TRONRENDER, true);
|
||||
break;
|
||||
default:
|
||||
getVtmMap().setTheme(new AssetsRenderTheme(mContext.getAssets(), "", "editormarker.xml"), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
getVtmMap().updateMap();
|
||||
}
|
||||
|
||||
public NILayerManager getLayerManager() {
|
||||
return mLayerManager;
|
||||
}
|
||||
|
||||
// 地图点击事件对应的图层
|
||||
private class MapEventsReceiver extends Layer implements GestureListener {
|
||||
|
||||
public MapEventsReceiver(Map map) {
|
||||
super(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onGesture(Gesture g, org.oscim.event.MotionEvent e) {
|
||||
GeoPoint geoPoint = mMap.viewport().fromScreenPoint(e.getX(), e.getY());
|
||||
if (g instanceof Gesture.Tap) { // 单击事件
|
||||
if (mapClickListener != null) {
|
||||
mapClickListener.onMapClick(geoPoint);
|
||||
}
|
||||
} else if (g instanceof Gesture.DoubleTap) { // 双击
|
||||
if (mapDoubleClickListener != null) {
|
||||
mapDoubleClickListener.onMapDoubleClick(geoPoint);
|
||||
}
|
||||
} else if (g instanceof Gesture.LongPress) { // 长按
|
||||
if (mapLongClickListener != null) {
|
||||
mapLongClickListener.onMapLongClick(geoPoint);
|
||||
}
|
||||
}
|
||||
setOnMapClickListener(new NIMap.OnMapClickListener() {
|
||||
@Override
|
||||
public void onMapClick(GeoPoint point) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapPoiClick(GeoPoint poi) {
|
||||
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图的点击事件
|
||||
*/
|
||||
public void setOnMapClickListener(@Nullable NIMap.OnMapClickListener listener) {
|
||||
this.mapClickListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图的双击事件
|
||||
* 注:默认情况下,双击会自动放大地图
|
||||
*/
|
||||
public void setOnMapDoubleClickListener(@Nullable NIMap.OnMapDoubleClickListener listener) {
|
||||
this.mapDoubleClickListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图长按事件
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnMapLongClickListener(@Nullable NIMap.OnMapLongClickListener listener) {
|
||||
this.mapLongClickListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图的触摸事件
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnMapTouchListener(@Nullable NIMap.OnMapTouchListener listener) {
|
||||
this.touchListener = listener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.navinfo.collect.library.map;
|
||||
|
||||
import android.graphics.Camera;
|
||||
import android.graphics.Matrix;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.view.animation.Transformation;
|
||||
import android.widget.ImageView;
|
||||
|
||||
/*
|
||||
*com.nmp.widget
|
||||
*zhjch
|
||||
*2021/6/24
|
||||
*22:29
|
||||
*说明(图片旋转)
|
||||
*/
|
||||
public class NIRotateAnimation extends Animation {
|
||||
private float mFromX;
|
||||
private float mToX;
|
||||
private float mFromZ;
|
||||
private float mToZ;
|
||||
private float mCenterX;
|
||||
private float mCenterY;
|
||||
private final float mDepthZ = 0;
|
||||
private final boolean mReverse = true;
|
||||
private Camera mCamera;
|
||||
private ImageView mImageView;
|
||||
|
||||
private float mPivotX;
|
||||
private float mPivotY;
|
||||
|
||||
public NIRotateAnimation(ImageView imageView) {
|
||||
mImageView = imageView;
|
||||
// 计算中心点
|
||||
mCenterX = imageView.getWidth() / 2.0f;
|
||||
mCenterY = imageView.getHeight() / 2.0f;
|
||||
setDuration(10);
|
||||
setFillAfter(true);
|
||||
|
||||
//匀速旋转
|
||||
setInterpolator(new LinearInterpolator());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(int width, int height, int parentWidth, int parentHeight) {
|
||||
super.initialize(width, height, parentWidth, parentHeight);
|
||||
mCamera = new Camera();
|
||||
mPivotX = resolveSize(Animation.RELATIVE_TO_SELF, 0.5f, width, parentWidth);
|
||||
mPivotY = resolveSize(Animation.RELATIVE_TO_SELF, 0.5f, height, parentHeight);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
||||
float degrees = mFromZ + ((mToZ - mFromZ) * interpolatedTime);
|
||||
float scale = getScaleFactor();
|
||||
final Matrix matrix = t.getMatrix();
|
||||
|
||||
final float centerX = mCenterX;
|
||||
final float centerY = mCenterY;
|
||||
final Camera camera = mCamera;
|
||||
|
||||
//保存一次camera初始状态,用于restore()
|
||||
camera.save();
|
||||
if (mReverse) {
|
||||
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
|
||||
} else {
|
||||
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
|
||||
}
|
||||
|
||||
final float fromX = mFromX;
|
||||
float degreesX = fromX + ((mToX - fromX) * interpolatedTime);
|
||||
//围绕Y轴旋转degrees度
|
||||
camera.rotateX(degreesX);
|
||||
// //行camera中取出矩阵,赋值给matrix
|
||||
camera.getMatrix(matrix);
|
||||
camera.restore();
|
||||
//camera恢复到初始状态,继续用于下次的计算
|
||||
if (mPivotX == 0.0f && mPivotY == 0.0f) {
|
||||
matrix.preRotate(degrees);//它也是用matrix来实现旋转的,不是matrix的按z轴旋转和它一样, 是它就是这样实现的.
|
||||
} else {
|
||||
matrix.preRotate(degrees, mPivotX * scale, mPivotY * scale);
|
||||
}
|
||||
matrix.preTranslate(-centerX, -centerY);
|
||||
matrix.postTranslate(centerX, centerY);
|
||||
}
|
||||
|
||||
public void startRotationX(float start, float end) {
|
||||
|
||||
// Create a new 3D rotation with the supplied parameter
|
||||
// The animation listener is used to trigger the next animation
|
||||
//final Rotate3dAnimation rotation =new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
|
||||
mFromX = start;
|
||||
mToX = end;
|
||||
mImageView.startAnimation(this);
|
||||
}
|
||||
|
||||
public void startRotationZ(float start, float end) {
|
||||
|
||||
// Create a new 3D rotation with the supplied parameter
|
||||
// The animation listener is used to trigger the next animation
|
||||
//final Rotate3dAnimation rotation =new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
|
||||
mFromZ = start;
|
||||
mToZ = end;
|
||||
mImageView.startAnimation(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
package com.navinfo.collect.library.map.flutter
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.FlutterBaseActivity
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.map.NIMapOptions
|
||||
import com.navinfo.collect.library.map.flutter.flutterhandler.*
|
||||
import com.navinfo.collect.library.map.flutter.maphandler.FlutterMeasureLayerHandler
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
class FlutterMapController(
|
||||
id: Int,
|
||||
context: Context,
|
||||
binaryMessenger: BinaryMessenger,
|
||||
options: NIMapOptions,
|
||||
) : NIMapController(context, options), MethodChannel.MethodCallHandler {
|
||||
private val mMethodChannel: MethodChannel = MethodChannel(
|
||||
binaryMessenger,
|
||||
"com.navinfo.collect/mapView_$id"
|
||||
)
|
||||
|
||||
private val flutterMapBaseControlHandler: FlutterMapBaseControlHandler =
|
||||
FlutterMapBaseControlHandler(context, mMethodChannel, mMapView)
|
||||
|
||||
private val flutterAnimationHandler: FlutterAnimationHandler by lazy {
|
||||
FlutterAnimationHandler(context, mMapView)
|
||||
}
|
||||
private val flutterMarkerHandler: FlutterMarkerHandler by lazy {
|
||||
FlutterMarkerHandler(context, mMapView)
|
||||
}
|
||||
|
||||
private val flutterLocationHandler: FlutterLocationLayerHandler by lazy {
|
||||
FlutterLocationLayerHandler(context, mMapView)
|
||||
}
|
||||
|
||||
private val flutterLineHandler: FlutterLineHandler by lazy {
|
||||
FlutterLineHandler(context, mMapView)
|
||||
}
|
||||
|
||||
private val flutterPolygonHandler: FlutterPolygonHandler by lazy {
|
||||
FlutterPolygonHandler(context, mMapView)
|
||||
}
|
||||
|
||||
private val flutterViewportHandler: FlutterViewportHandler by lazy {
|
||||
FlutterViewportHandler(context, mMapView)
|
||||
}
|
||||
|
||||
private val flutterLayerManagerHandler: FlutterLayerManagerHandler =
|
||||
FlutterLayerManagerHandler(context, mMapView)
|
||||
|
||||
init {
|
||||
mMethodChannel.setMethodCallHandler(this)
|
||||
}
|
||||
|
||||
private val flutterMeasureLayerHandler: FlutterMeasureLayerHandler by lazy {
|
||||
FlutterMeasureLayerHandler(context, mMapView)
|
||||
}
|
||||
|
||||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||
when (call.method) {
|
||||
/**
|
||||
* 地图基础操作部分
|
||||
*/
|
||||
//刷新地图
|
||||
FlutterMapProtocolKeys.kMapUpdateMap -> {
|
||||
flutterMapBaseControlHandler.updateMap(call, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图动画效果控制协议
|
||||
*/
|
||||
//根据屏幕像素移动地图
|
||||
FlutterMapProtocolKeys.AnimationProtocol.kMapAnimationByPixel -> {
|
||||
flutterAnimationHandler.animation(call, result)
|
||||
}
|
||||
//地图缩小
|
||||
FlutterMapProtocolKeys.AnimationProtocol.kMapAnimationZoomOut -> {
|
||||
flutterAnimationHandler.zoomOut(call, result)
|
||||
}
|
||||
//地图放大
|
||||
FlutterMapProtocolKeys.AnimationProtocol.kMapAnimationZoomIn -> {
|
||||
flutterAnimationHandler.zoomIn(call, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图Marker控制协议
|
||||
*/
|
||||
//增加或更新marker
|
||||
FlutterMapProtocolKeys.MarkerProtocol.kMapAddMarkerMethod -> {
|
||||
flutterMarkerHandler.addMarker(call, result)
|
||||
}
|
||||
//删除marker
|
||||
FlutterMapProtocolKeys.MarkerProtocol.kMapRemoveMarkerMethod -> {
|
||||
flutterMarkerHandler.removeMarker(call, result)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 地图定位信息控制协议
|
||||
*/
|
||||
//更新定位信息
|
||||
FlutterMapProtocolKeys.LocationProtocol.kMapUpdateLocationDataMethod -> {
|
||||
flutterLocationHandler.updateCurrentLocation(call, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 线数据协议
|
||||
*/
|
||||
//绘制线时的打点
|
||||
FlutterMapProtocolKeys.LineProtocol.kMapAddDrawLinePointMethod -> {
|
||||
flutterLineHandler.addDrawLinePoint(call, result)
|
||||
}
|
||||
//清除正在绘制的线
|
||||
FlutterMapProtocolKeys.LineProtocol.kMapCleanDrawLineMethod -> {
|
||||
flutterLineHandler.clean(call, result)
|
||||
}
|
||||
//添加线数据
|
||||
FlutterMapProtocolKeys.LineProtocol.kMapAddDrawLineMethod -> {
|
||||
flutterLineHandler.addDrawLine(call, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 面数据协议
|
||||
*/
|
||||
//绘制面时的打点
|
||||
FlutterMapProtocolKeys.PolygonProtocol.kMapAddDrawPolygonPointMethod -> {
|
||||
flutterPolygonHandler.addDrawPolygonPoint(call, result)
|
||||
}
|
||||
/**
|
||||
* 面数据协议
|
||||
*/
|
||||
//绘制面时的打点
|
||||
FlutterMapProtocolKeys.PolygonProtocol.kMapAddDrawPolygonNiPointMethod -> {
|
||||
flutterPolygonHandler.addDrawPolygonNiPoint(call, result)
|
||||
}
|
||||
|
||||
//绘制面
|
||||
FlutterMapProtocolKeys.PolygonProtocol.kMapAddDrawPolygonMethod -> {
|
||||
flutterPolygonHandler.addDrawPolygon(call, result)
|
||||
}
|
||||
|
||||
//清除正在绘制的面
|
||||
FlutterMapProtocolKeys.PolygonProtocol.kMapCleanDrawPolygonMethod -> {
|
||||
flutterPolygonHandler.clean(call, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 视窗操作
|
||||
*/
|
||||
//设置地图中心点的偏移量
|
||||
FlutterMapProtocolKeys.ViewportProtocol.kMapViewportSetViewCenterMethod -> {
|
||||
flutterViewportHandler.setMapViewCenter(call, result)
|
||||
}
|
||||
//获取几何扩展后的外接矩形
|
||||
FlutterMapProtocolKeys.ViewportProtocol.kMapViewportGetBoundingBoxMethod -> {
|
||||
flutterViewportHandler.getBoundingBoxWkt(call, result)
|
||||
}
|
||||
|
||||
//坐标转屏幕点
|
||||
FlutterMapProtocolKeys.ViewportProtocol.kMapViewportToScreenPointMethod -> {
|
||||
flutterViewportHandler.toScreenPoint(call, result)
|
||||
}
|
||||
|
||||
//屏幕点转坐标
|
||||
FlutterMapProtocolKeys.ViewportProtocol.kMapViewportFromScreenPointMethod -> {
|
||||
flutterViewportHandler.fromScreenPoint(call, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 底图切换控制协议
|
||||
*/
|
||||
//切换底图
|
||||
FlutterMapProtocolKeys.LayerManagerProtocol.kMapSwitchRasterTileLayerMethod -> {
|
||||
flutterLayerManagerHandler.switchRasterTileLayer(call, result)
|
||||
}
|
||||
|
||||
//获取支持的底图
|
||||
FlutterMapProtocolKeys.LayerManagerProtocol.kMapGetRasterTileLayerListMethod -> {
|
||||
flutterLayerManagerHandler.getBaseRasterTileLayerList(call, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 底图切换控制协议
|
||||
*/
|
||||
//切换底图
|
||||
FlutterMapProtocolKeys.LayerManagerProtocol.kMapSwitchRasterTileLayerMethod -> {
|
||||
flutterLayerManagerHandler.switchRasterTileLayer(call, result)
|
||||
}
|
||||
|
||||
//获取支持的底图
|
||||
FlutterMapProtocolKeys.LayerManagerProtocol.kMapGetRasterTileLayerListMethod -> {
|
||||
flutterLayerManagerHandler.getBaseRasterTileLayerList(call, result)
|
||||
}
|
||||
|
||||
//绘制线或者面
|
||||
FlutterMapProtocolKeys.LayerManagerProtocol.kMapDrawLineOrPolygonMethod -> {
|
||||
flutterMeasureLayerHandler.drawLineOrPolygon(call, result);
|
||||
}
|
||||
|
||||
//清理绘制线或者面
|
||||
FlutterMapProtocolKeys.LayerManagerProtocol.kMapCleanDrawLineOrPolygonMethod -> {
|
||||
flutterMeasureLayerHandler.clean();
|
||||
}
|
||||
|
||||
//绘制线或者面
|
||||
FlutterMapProtocolKeys.LayerManagerProtocol.kMapEditLineOrPolygonMethod -> {
|
||||
flutterLayerManagerHandler.editLineOrPolygon(call, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
super.release()
|
||||
|
||||
mMethodChannel.setMethodCallHandler(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.navinfo.collect.library.map.flutter
|
||||
|
||||
import com.navinfo.collect.library.map.NIMapOptions
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
|
||||
/**
|
||||
* 和flutter层进行数据传递时的数据格式转换
|
||||
*/
|
||||
class FlutterMapConversion {
|
||||
companion object {
|
||||
// flutter json 转成原生对象
|
||||
/**
|
||||
* 地图初始配置信息转换
|
||||
*/
|
||||
fun flutterToNIMapOptions(args: String): NIMapOptions {
|
||||
|
||||
return NIMapOptions.fromJson(args)
|
||||
// return MoshiUtil.fromJson<NIMapOptions>(args)!!;
|
||||
// val moshi = Moshi.Builder().build()
|
||||
// val jsonAdapter: JsonAdapter<NIMapOptions> = moshi.adapter(NIMapOptions::class.java)
|
||||
// return jsonAdapter.fromJson(args)!!
|
||||
}
|
||||
|
||||
|
||||
//原生转给flutter
|
||||
/**
|
||||
* marker 转json
|
||||
*/
|
||||
fun markerToJson(marker: MarkerItem): String {
|
||||
return "{\"id\":\"${marker.title}\",\"description\":\"${marker.description}\",\"geoPoint\":{\"longitude\":${marker.geoPoint.longitude},\"latitude\":${marker.geoPoint.latitude}}}"
|
||||
}
|
||||
|
||||
/**
|
||||
* line转json
|
||||
*/
|
||||
fun lineToJson(list: List<GeoPoint>): String {
|
||||
var jsonArray = JSONArray();
|
||||
for (point in list) {
|
||||
val jsonObject = JSONObject();
|
||||
jsonObject.put("latitude", point.latitude)
|
||||
jsonObject.put("longitude", point.longitude)
|
||||
jsonObject.put("latitudeE6", point.latitudeE6)
|
||||
jsonObject.put("longitudeE6", point.longitudeE6)
|
||||
jsonArray.put(jsonObject)
|
||||
}
|
||||
|
||||
return jsonArray.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图转json
|
||||
*/
|
||||
fun baseMapTypeToJson(list: Array<NIMapView.BASE_MAP_TYPE>): String {
|
||||
var jsonArray = JSONArray();
|
||||
//循环输出 值
|
||||
for (baseMapType in list) {
|
||||
val jsonObject = JSONObject();
|
||||
jsonObject.put("title", baseMapType.title)
|
||||
jsonObject.put("url", baseMapType.url)
|
||||
jsonObject.put("tilePath", baseMapType.tilePath)
|
||||
jsonArray.put(jsonObject)
|
||||
}
|
||||
return jsonArray.toString()
|
||||
}
|
||||
|
||||
fun toGeoPointMapList(list: List<GeoPoint>): List<*> {
|
||||
val newList = mutableListOf<Map<*, *>>()
|
||||
for (item in list) {
|
||||
newList.add(
|
||||
mapOf(
|
||||
"latitude" to item.latitude,
|
||||
"longitude" to item.longitude,
|
||||
"latitudeE6" to item.latitudeE6,
|
||||
"longitudeE6" to item.longitudeE6,
|
||||
),
|
||||
)
|
||||
}
|
||||
return newList
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.navinfo.collect.library.map.flutter
|
||||
|
||||
object FlutterMapProtocolKeys {
|
||||
|
||||
///刷新地图
|
||||
const val kMapUpdateMap = "flutter_nimap/base/UpdateMap";
|
||||
|
||||
/**
|
||||
* 地图动画控制协议
|
||||
*/
|
||||
object AnimationProtocol {
|
||||
// 按像素移动地图中心点
|
||||
const val kMapAnimationByPixel = "flutter_nimap/animation/AnimationByPixel"
|
||||
|
||||
///地图缩小
|
||||
const val kMapAnimationZoomOut = "flutter_nimap/animation/AnimationZoomOut";
|
||||
|
||||
///地图放大
|
||||
const val kMapAnimationZoomIn = "flutter_nimap/animation/AnimationZoomIn";
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* marker控制协议
|
||||
*/
|
||||
object MarkerProtocol {
|
||||
// 添加marker
|
||||
const val kMapAddMarkerMethod = "flutter_nimap/marker/addMarker"
|
||||
|
||||
// 删除marker
|
||||
const val kMapRemoveMarkerMethod = "flutter_nimap/marker/removeMarker";
|
||||
}
|
||||
|
||||
/**
|
||||
* 定位信息控制协议
|
||||
*/
|
||||
object LocationProtocol {
|
||||
// 动态更新我的位置数据
|
||||
const val kMapUpdateLocationDataMethod = "flutter_nimap/location/updateLocationData"
|
||||
}
|
||||
|
||||
/**
|
||||
* 线数据控制协议
|
||||
*/
|
||||
object LineProtocol {
|
||||
// 线数据打点
|
||||
const val kMapAddDrawLinePointMethod = "flutter_nimap/line/addDrawLinePoint";
|
||||
|
||||
// 清除画线功能
|
||||
const val kMapCleanDrawLineMethod = "flutter_nimap/line/cleanDrawLine"
|
||||
|
||||
// 添加线数据
|
||||
const val kMapAddDrawLineMethod = "flutter_nimap/line/addDrawLine"
|
||||
}
|
||||
|
||||
/**
|
||||
* 线数据控制协议
|
||||
*/
|
||||
object PolygonProtocol {
|
||||
// 线数据打点
|
||||
const val kMapAddDrawPolygonPointMethod = "flutter_nimap/Polygon/addDrawPolygonPoint";
|
||||
// 线数据打点
|
||||
const val kMapAddDrawPolygonNiPointMethod = "flutter_nimap/Polygon/addDrawPolygonNiPoint";
|
||||
// 添加面数据
|
||||
const val kMapAddDrawPolygonMethod = "flutter_nimap/Polygon/addDrawPolygon"
|
||||
// 清除画线功能
|
||||
const val kMapCleanDrawPolygonMethod = "flutter_nimap/Polygon/cleanDrawPolygon"
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图view操作
|
||||
*/
|
||||
object ViewportProtocol {
|
||||
// 设置地图中心点
|
||||
const val kMapViewportSetViewCenterMethod = "flutter_nimap/Viewport/SetViewCenter";
|
||||
//获取几何扩展后的外接矩形
|
||||
const val kMapViewportGetBoundingBoxMethod = "flutter_nimap/Viewport/GetBoundingBox";
|
||||
//坐标转屏幕点
|
||||
const val kMapViewportToScreenPointMethod = "flutter_nimap/Viewport/ToScreenPoint";
|
||||
//屏幕点转坐标
|
||||
const val kMapViewportFromScreenPointMethod = "flutter_nimap/Viewport/FromScreenPoint";
|
||||
}
|
||||
|
||||
/**
|
||||
* 原生地图通知flutter命令
|
||||
*/
|
||||
object MapCallBackProtocol {
|
||||
// 用户操作地图,状态回调
|
||||
const val kMapEventCallback = "flutter_nimap/mapCallBack/kMapEventCallback";
|
||||
|
||||
// 用户单击地图,回调点击坐标
|
||||
const val kMapOnClickCallback = "flutter_nimap/mapCallBack/kMapOnClickCallback";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* LayerManager控制协议
|
||||
*/
|
||||
object LayerManagerProtocol {
|
||||
// 切换RasterTileLayer
|
||||
const val kMapSwitchRasterTileLayerMethod = "flutter_nimap/LayerManager/switchRasterTileLayer";
|
||||
|
||||
// 移除RasterTileLayer
|
||||
const val kMapRemoveRasterTileLayerMethod = "flutter_nimap/LayerManager/removeRasterTileLayer"
|
||||
|
||||
// 获取RasterTileLayer
|
||||
const val kMapGetRasterTileLayerListMethod = "flutter_nimap/LayerManager/getRasterTileLayerList"
|
||||
|
||||
// 绘制线或者面
|
||||
const val kMapDrawLineOrPolygonMethod = "flutter_nimap/LayerManager/drawLineOrPolygon"
|
||||
|
||||
// 清理绘制线或者面
|
||||
const val kMapCleanDrawLineOrPolygonMethod = "flutter_nimap/LayerManager/cleanDrawLineOrPolygon"
|
||||
|
||||
// 编辑线或者面
|
||||
const val kMapEditLineOrPolygonMethod = "flutter_nimap/LayerManager/editLineOrPolygon"
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.navinfo.collect.library.map.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.handler.AnimationHandler
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
class FlutterAnimationHandler(
|
||||
context: Context,
|
||||
mapView: NIMapView
|
||||
) :
|
||||
AnimationHandler(context, mapView) {
|
||||
|
||||
|
||||
/**
|
||||
* 使用像素移动地图
|
||||
*/
|
||||
fun animation(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.hasArgument("xPixel") && call.hasArgument("yPixel")) {
|
||||
val x = call.argument<Double>("xPixel")
|
||||
val y = call.argument<Double>("yPixel")
|
||||
var time = 200;
|
||||
if (call.hasArgument("animateDurationMs")) {
|
||||
time = call.argument<Int>("animateDurationMs")!!;
|
||||
}
|
||||
super.animationByPixel(x!!.toInt(), y!!.toInt(), time.toLong())
|
||||
result.success(true)
|
||||
} else if (call.hasArgument("latitude") && call.hasArgument("longitude")) {
|
||||
var time = 200;
|
||||
if (call.hasArgument("animateDurationMs")) {
|
||||
time = call.argument<Int>("animateDurationMs")!!;
|
||||
}
|
||||
animationByLonLat(
|
||||
call.argument<Double>("latitude") as Double,
|
||||
call.argument<Double>("longitude") as Double,
|
||||
time.toLong()
|
||||
)
|
||||
result.success(true)
|
||||
} else {
|
||||
result.error("-1", "像素坐标错误", "")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图缩小
|
||||
*/
|
||||
fun zoomOut(call: MethodCall, result: MethodChannel.Result) {
|
||||
super.zoomOut()
|
||||
result.success(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图放大
|
||||
*/
|
||||
fun zoomIn(call: MethodCall, result: MethodChannel.Result) {
|
||||
super.zoomIn()
|
||||
result.success(true)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.navinfo.collect.library.map.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.handler.LayerManagerHandler
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
/**
|
||||
* 图层操作控制
|
||||
*/
|
||||
class FlutterLayerManagerHandler(context: Context, mapView: NIMapView) :
|
||||
LayerManagerHandler(context, mapView) {
|
||||
|
||||
//切换底图
|
||||
fun switchRasterTileLayer(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.hasArgument("url") && call.hasArgument("tilePath")) {
|
||||
|
||||
}
|
||||
val url = call.argument<String>("url")
|
||||
val tilePath = call.argument<String>("tilePath")
|
||||
val cache = call.argument<Boolean>("cache")
|
||||
switchRasterTileLayer(url, tilePath, cache)
|
||||
}
|
||||
|
||||
fun removeRasterTileLayer(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.hasArgument("url")) {
|
||||
val url = call.argument<String>("url")
|
||||
removeRasterTileLayer(url!!);
|
||||
result.success(true)
|
||||
}
|
||||
}
|
||||
|
||||
//获取支持底图内容
|
||||
fun getBaseRasterTileLayerList(call: MethodCall, result: MethodChannel.Result) {
|
||||
getBaseRasterTileLayerList { baseMapJson ->
|
||||
result.success(baseMapJson)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//编辑线或者面
|
||||
fun editLineOrPolygon(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.hasArgument("type")&&call.hasArgument("geometry")) {
|
||||
val type = call.argument<Int>("type")
|
||||
val geometry = call.argument<String>("geometry")
|
||||
if (type != null) {
|
||||
editLineOrPolygon(geometry!!,type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.navinfo.collect.library.map.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapConversion
|
||||
import com.navinfo.collect.library.map.handler.LineHandler
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import org.oscim.core.GeoPoint
|
||||
|
||||
/**
|
||||
* 线数据操作控制
|
||||
*/
|
||||
class FlutterLineHandler(context: Context, mapView: NIMapView) :
|
||||
LineHandler(context, mapView) {
|
||||
|
||||
/**
|
||||
* 给线数据增加一个点,如果是经纬度就用经纬度,如果是屏幕坐标就转换成经纬度
|
||||
*/
|
||||
fun addDrawLinePoint(call: MethodCall, result: MethodChannel.Result) {
|
||||
val list = addDrawLinePoint(
|
||||
GeoPoint(
|
||||
mMapView.vtmMap.mapPosition.latitude,
|
||||
mMapView.vtmMap.mapPosition.longitude
|
||||
)
|
||||
)
|
||||
result.success(FlutterMapConversion.lineToJson(list))
|
||||
}
|
||||
|
||||
fun clean(call: MethodCall, result: MethodChannel.Result) {
|
||||
clean()
|
||||
result.success(true)
|
||||
}
|
||||
|
||||
fun addDrawLine(call: MethodCall, result: MethodChannel.Result) {
|
||||
clean()
|
||||
val pointList = mutableListOf<GeoPoint>();
|
||||
if (call.arguments is List<*>) {
|
||||
for (item in call.arguments as List<*>) {
|
||||
if (item is Map<*, *>) {
|
||||
pointList.add(GeoPoint(item["latitude"] as Double, item["longitude"] as Double))
|
||||
}
|
||||
}
|
||||
}
|
||||
addDrawLine(pointList);
|
||||
result.success(true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.navinfo.collect.library.map.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NILocation
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.handler.LocationLayerHandler
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import org.oscim.core.GeoPoint
|
||||
|
||||
class FlutterLocationLayerHandler(context: Context, mapView: NIMapView) :
|
||||
LocationLayerHandler(context, mapView) {
|
||||
|
||||
var bFirst = true;
|
||||
|
||||
/**
|
||||
* 设置当前定位信息
|
||||
*/
|
||||
fun updateCurrentLocation(call: MethodCall, result: MethodChannel.Result) {
|
||||
var bTracking = true;
|
||||
if (call.hasArgument("tracking")) {
|
||||
bTracking = call.argument<Boolean>("tracking") == true
|
||||
}
|
||||
var locationMap = call.argument<Map<*, *>>("location");
|
||||
if (locationMap != null) {
|
||||
if (locationMap.containsKey("latitude") && locationMap.containsKey("longitude")) {
|
||||
val longitude = locationMap["longitude"]
|
||||
val latitude = locationMap["latitude"]
|
||||
val location = NILocation("GPS");
|
||||
if (latitude is Double && longitude is Double) {
|
||||
location.latitude = latitude
|
||||
location.longitude = longitude
|
||||
} else {
|
||||
return result.success(false)
|
||||
}
|
||||
if (locationMap.containsKey("direction")) {
|
||||
val direction = locationMap["direction"]
|
||||
if (direction is Float)
|
||||
location.bearing = direction
|
||||
}
|
||||
if (locationMap.containsKey("altitude")) {
|
||||
val altitude = locationMap["altitude"]
|
||||
if (altitude is Double)
|
||||
location.altitude = altitude
|
||||
}
|
||||
if (locationMap.containsKey("radius")) {
|
||||
val radius = locationMap["radius"]
|
||||
if (radius is Float)
|
||||
location.radius = radius
|
||||
}
|
||||
setCurrentLocation(location)
|
||||
if (bFirst || bTracking) {
|
||||
mMapView.vtmMap.animator().animateTo(GeoPoint(latitude, longitude))
|
||||
bFirst = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return result.success(true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.navinfo.collect.library.map.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapProtocolKeys
|
||||
import com.navinfo.collect.library.map.handler.MapBaseControlHandler
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import org.oscim.event.Gesture
|
||||
import org.oscim.event.GestureListener
|
||||
import org.oscim.event.MotionEvent
|
||||
import org.oscim.layers.Layer
|
||||
import org.oscim.map.Map
|
||||
|
||||
class FlutterMapBaseControlHandler(
|
||||
context: Context,
|
||||
methodChannel: MethodChannel,
|
||||
mapView: NIMapView
|
||||
) :
|
||||
MapBaseControlHandler(context, mapView) {
|
||||
init {
|
||||
mMapView.vtmMap.events.bind(Map.UpdateListener { e, _ ->
|
||||
when (e) {
|
||||
Map.MOVE_EVENT -> methodChannel.invokeMethod(
|
||||
FlutterMapProtocolKeys.MapCallBackProtocol.kMapEventCallback,
|
||||
mapOf("MapEvent" to 0)
|
||||
);
|
||||
Map.SCALE_EVENT -> methodChannel.invokeMethod(
|
||||
FlutterMapProtocolKeys.MapCallBackProtocol.kMapEventCallback,
|
||||
mapOf("MapEvent" to 1)
|
||||
);
|
||||
Map.ROTATE_EVENT -> methodChannel.invokeMethod(
|
||||
FlutterMapProtocolKeys.MapCallBackProtocol.kMapEventCallback,
|
||||
mapOf("MapEvent" to 2)
|
||||
);
|
||||
Map.TILT_EVENT -> methodChannel.invokeMethod(
|
||||
FlutterMapProtocolKeys.MapCallBackProtocol.kMapEventCallback,
|
||||
mapOf("MapEvent" to 3)
|
||||
);
|
||||
}
|
||||
})
|
||||
mMapView.layerManager.addLayer(
|
||||
"pointSnapLayer",
|
||||
MapEventsReceiver(methodChannel, mMapView.vtmMap)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class MapEventsReceiver(methodChannel: MethodChannel, map: Map?) : Layer(map),
|
||||
GestureListener {
|
||||
private val _methodChannel = methodChannel;
|
||||
override fun onGesture(g: Gesture, e: MotionEvent): Boolean {
|
||||
if (g is Gesture.Tap) {
|
||||
val p = mMap.viewport().fromScreenPoint(e.x, e.y)
|
||||
_methodChannel.invokeMethod(
|
||||
FlutterMapProtocolKeys.MapCallBackProtocol.kMapOnClickCallback,
|
||||
mapOf(
|
||||
"latitude" to p.latitude,
|
||||
"longitude" to p.longitude,
|
||||
"longitudeE6" to p.longitudeE6,
|
||||
"latitudeE6" to p.latitudeE6,
|
||||
)
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新地图
|
||||
*/
|
||||
fun updateMap(call: MethodCall, result: MethodChannel.Result) {
|
||||
var redraw = call.argument<Boolean>("redraw") ?: true
|
||||
upDateMap(redraw);
|
||||
result.success(true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.navinfo.collect.library.map.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapConversion
|
||||
import com.navinfo.collect.library.map.handler.MarkHandler
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
|
||||
class FlutterMarkerHandler(context: Context, mapView: NIMapView) :
|
||||
MarkHandler(context, mapView) {
|
||||
|
||||
fun addMarker(call: MethodCall, result: MethodChannel.Result) {
|
||||
val marker: MarkerItem;
|
||||
val description = call.argument<String>("description")
|
||||
val title = call.argument<String>("title")
|
||||
if (call.hasArgument("xPixel") && call.hasArgument("yPixel")) {
|
||||
val x = call.argument<Double>("xPixel")
|
||||
val y = call.argument<Double>("yPixel")
|
||||
val description = call.argument<String>("description")
|
||||
val geoPoint =
|
||||
mMapView.vtmMap.viewport().fromScreenPoint(x!!.toFloat(), y!!.toFloat())
|
||||
marker = addMarker(geoPoint, title, description)
|
||||
} else if (call.hasArgument("longitude") && call.hasArgument("latitude")) {
|
||||
val lon = call.argument<Double>("longitude")
|
||||
val lat = call.argument<Double>("latitude")
|
||||
|
||||
marker = addMarker(GeoPoint(lat!!, lon!!), title, description)
|
||||
} else {
|
||||
marker = addMarker(
|
||||
GeoPoint(
|
||||
mMapView.vtmMap.mapPosition.latitude,
|
||||
mMapView.vtmMap.mapPosition.longitude
|
||||
), title, description
|
||||
)
|
||||
}
|
||||
result.success(FlutterMapConversion.markerToJson(marker));
|
||||
}
|
||||
|
||||
fun removeMarker(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.hasArgument("title")) {
|
||||
val title = call.argument<String>("title")
|
||||
removeMarker(title!!);
|
||||
result.success(true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.navinfo.collect.library.map.flutter.maphandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.maphandler.MeasureLayerHandler
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
/**
|
||||
* 测距操作控制
|
||||
*/
|
||||
class FlutterMeasureLayerHandler(context: Context, mapView: NIMapView) :
|
||||
MeasureLayerHandler(context, mapView) {
|
||||
|
||||
/**
|
||||
* 给面数据增加一个点,如果是经纬度就用经纬度,如果是屏幕坐标就转换成经纬度
|
||||
*/
|
||||
fun drawLineOrPolygon(call: MethodCall, result: MethodChannel.Result) {
|
||||
|
||||
if (call.hasArgument("type")) {
|
||||
val type = call.argument<Int>("type")
|
||||
if (type != null) {
|
||||
drawLineOrPolygon(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun clean(call: MethodCall, result: MethodChannel.Result) {
|
||||
clean()
|
||||
result.success(true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.navinfo.collect.library.map.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapConversion
|
||||
import com.navinfo.collect.library.map.handler.PolygonHandler
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import org.oscim.core.GeoPoint
|
||||
|
||||
/**
|
||||
* 面据操作控制
|
||||
*/
|
||||
class FlutterPolygonHandler(context: Context, mapView: NIMapView) :
|
||||
PolygonHandler(context, mapView) {
|
||||
|
||||
/**
|
||||
* 给面数据增加一个点,如果是经纬度就用经纬度,如果是屏幕坐标就转换成经纬度
|
||||
*/
|
||||
fun addDrawPolygonPoint(call: MethodCall, result: MethodChannel.Result) {
|
||||
val list = addDrawPolygonPoint(
|
||||
GeoPoint(
|
||||
mMapView.vtmMap.mapPosition.latitude,
|
||||
mMapView.vtmMap.mapPosition.longitude
|
||||
)
|
||||
)
|
||||
result.success(FlutterMapConversion.lineToJson(list));
|
||||
}
|
||||
/**
|
||||
* 给面数据增加一个点,如果是经纬度就用经纬度,如果是屏幕坐标就转换成经纬度
|
||||
*/
|
||||
fun addDrawPolygonNiPoint(call: MethodCall, result: MethodChannel.Result) {
|
||||
|
||||
if (call.hasArgument("longitude")&&call.hasArgument("latitude")) {
|
||||
|
||||
val x = call.argument<Double>("longitude")
|
||||
val y = call.argument<Double>("latitude")
|
||||
|
||||
val list = addDrawPolygonPoint(GeoPoint(y!!, x!!))
|
||||
|
||||
result.success(FlutterMapConversion.lineToJson(list))
|
||||
}
|
||||
}
|
||||
|
||||
fun addDrawPolygon(call: MethodCall, result: MethodChannel.Result) {
|
||||
clean()
|
||||
val pointList = mutableListOf<GeoPoint>();
|
||||
if (call.arguments is List<*>) {
|
||||
for (item in call.arguments as List<*>) {
|
||||
if (item is Map<*, *>) {
|
||||
pointList.add(GeoPoint(item["latitude"] as Double, item["longitude"] as Double))
|
||||
}
|
||||
}
|
||||
}
|
||||
addDrawPolygon(pointList);
|
||||
result.success(true)
|
||||
}
|
||||
|
||||
fun clean(call: MethodCall, result: MethodChannel.Result) {
|
||||
clean()
|
||||
result.success(true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.navinfo.collect.library.map.flutter.flutterhandler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.handler.ViewportHandler
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import org.oscim.core.GeoPoint
|
||||
|
||||
class FlutterViewportHandler(context: Context, mapView: NIMapView) :
|
||||
ViewportHandler(context, mapView) {
|
||||
/**
|
||||
* 设置地图中心偏移量 [-1,1]之间
|
||||
*/
|
||||
fun setMapViewCenter(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
val x = call.argument<Double>("xPivot")
|
||||
val y = call.argument<Double>("yPivot")
|
||||
val mapPosition = mMapView.vtmMap.mapPosition;
|
||||
setMapViewCenter(x!!.toFloat(), y!!.toFloat())
|
||||
mMapView.vtmMap.animator().animateTo(mapPosition)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取几何的外接矩形,返回矩形的左上,右下两个坐标
|
||||
*/
|
||||
fun getBoundingBoxWkt(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
val lat = call.argument<Double>("latitude")
|
||||
val lon = call.argument<Double>("longitude")
|
||||
val snapType = call.argument<Int>("snapType")
|
||||
val distance = call.argument<Int>("distance")
|
||||
val geoPoint = GeoPoint(lat!!, lon!!);
|
||||
|
||||
val map = getBoundingBoxWkt(geoPoint, GeometryTools.SNAP_TYPE.values()[snapType!!], distance!!)
|
||||
|
||||
result.success(map)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 坐标转屏幕点
|
||||
*/
|
||||
fun toScreenPoint(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.arguments is Map<*, *>) {
|
||||
val lat = call.argument<Double>("latitude")
|
||||
val lon = call.argument<Double>("longitude")
|
||||
val geoPoint = GeoPoint(lat!!, lon!!);
|
||||
|
||||
val map = toScreenPoint(geoPoint)
|
||||
|
||||
result.success(map)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 屏幕点转坐标
|
||||
*/
|
||||
fun fromScreenPoint(call: MethodCall, result: MethodChannel.Result) {
|
||||
|
||||
print("qj===fromScreenPoint")
|
||||
|
||||
if (call.arguments is Map<*, *>) {
|
||||
val px = call.argument<Double>("px")
|
||||
val py = call.argument<Double>("py")
|
||||
|
||||
print("qj===px:$px==py:$py")
|
||||
|
||||
if(px!=null&&py!=null){
|
||||
val map = fromScreenPoint(px.toFloat(),py.toFloat())
|
||||
|
||||
result.success(map)
|
||||
}else{
|
||||
result.success("")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.navinfo.collect.library.map.flutter.plugin
|
||||
|
||||
import androidx.annotation.NonNull
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||
import io.flutter.embedding.engine.plugins.lifecycle.HiddenLifecycleReference
|
||||
|
||||
|
||||
class FlutterLifecycleAdapter {
|
||||
private val TAG = "FlutterLifecycleAdapter"
|
||||
|
||||
/**
|
||||
* Returns the lifecycle object for the activity a plugin is bound to.
|
||||
*
|
||||
*
|
||||
* Returns null if the Flutter engine version does not include the lifecycle extraction code.
|
||||
* (this probably means the Flutter engine version is too old).
|
||||
*/
|
||||
companion object {
|
||||
@NonNull
|
||||
fun getActivityLifecycle(
|
||||
@NonNull activityPluginBinding: ActivityPluginBinding
|
||||
): Lifecycle {
|
||||
val reference = activityPluginBinding.lifecycle as HiddenLifecycleReference
|
||||
return reference.lifecycle
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.navinfo.collect.library.map.flutter.plugin
|
||||
|
||||
import android.view.View
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.navinfo.collect.library.data.flutter.FlutterDataController
|
||||
import com.navinfo.collect.library.importExport.flutter.FlutterImportExportController
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapController
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import io.flutter.plugin.platform.PlatformView
|
||||
|
||||
|
||||
class FlutterMapView(
|
||||
mapController: FlutterMapController,
|
||||
dataController: FlutterDataController,
|
||||
importExportController: FlutterImportExportController,
|
||||
lifecycleProxy: LifecycleProxy
|
||||
) :
|
||||
PlatformView, DefaultLifecycleObserver {
|
||||
private val mMapController: FlutterMapController = mapController
|
||||
private val mDataController: FlutterDataController = dataController
|
||||
private val mImportExportController: FlutterImportExportController = importExportController
|
||||
private val mapView: NIMapView = mMapController.mMapView
|
||||
private var mIsDisposed = false
|
||||
private val mLifecycleProxy: LifecycleProxy = lifecycleProxy;
|
||||
|
||||
init {
|
||||
var lifecycle: Lifecycle? = mLifecycleProxy.getLifecycle()
|
||||
lifecycle?.addObserver(this)
|
||||
}
|
||||
|
||||
override fun getView(): View {
|
||||
return mapView
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
|
||||
if (mIsDisposed) {
|
||||
return
|
||||
}
|
||||
|
||||
mIsDisposed = true
|
||||
|
||||
mMapController.release()
|
||||
mDataController.release()
|
||||
|
||||
val lifecycle: Lifecycle? = mLifecycleProxy.getLifecycle()
|
||||
lifecycle?.removeObserver(this)
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
if (!mIsDisposed) {
|
||||
mapView.onPause()
|
||||
}
|
||||
super.onPause(owner)
|
||||
}
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
if (!mIsDisposed) {
|
||||
mapView.onResume()
|
||||
}
|
||||
super.onResume(owner)
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
if (!mIsDisposed) {
|
||||
mMapController.release()
|
||||
mDataController.release()
|
||||
// mapView = null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.navinfo.collect.library.map.flutter.plugin
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.FlutterBaseActivity
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
|
||||
import com.navinfo.collect.library.data.flutter.FlutterDataController
|
||||
import com.navinfo.collect.library.importExport.flutter.FlutterImportExportController
|
||||
import com.navinfo.collect.library.map.NIMapOptions
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapConversion
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapController
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.StandardMessageCodec
|
||||
import io.flutter.plugin.platform.PlatformView
|
||||
import io.flutter.plugin.platform.PlatformViewFactory
|
||||
|
||||
class FlutterMapViewFactory(
|
||||
messenger: BinaryMessenger,
|
||||
lifecycleProxy: LifecycleProxy,
|
||||
activity: FlutterBaseActivity,
|
||||
) :
|
||||
PlatformViewFactory(StandardMessageCodec.INSTANCE) {
|
||||
private val binaryMessenger: BinaryMessenger = messenger
|
||||
|
||||
private var mLifecycleProxy: LifecycleProxy = lifecycleProxy
|
||||
|
||||
lateinit var mapController: FlutterMapController
|
||||
lateinit var dataController: FlutterDataController
|
||||
private val activity: FlutterBaseActivity = activity
|
||||
|
||||
override fun create(context: Context?, id: Int, args: Any?): PlatformView {
|
||||
mapController = buildMapController(context!!, id, args!!)
|
||||
dataController = buildDataController(context, id, activity)
|
||||
val importExportController =
|
||||
buildImportExportController(context, id, dataController.mDateBase)
|
||||
return FlutterMapView(
|
||||
mapController,
|
||||
dataController,
|
||||
importExportController,
|
||||
mLifecycleProxy
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建地图控制器
|
||||
*/
|
||||
private fun buildMapController(
|
||||
context: Context,
|
||||
viewId: Int,
|
||||
args: Any,
|
||||
): FlutterMapController {
|
||||
|
||||
val options: NIMapOptions = FlutterMapConversion.flutterToNIMapOptions(args.toString())
|
||||
return FlutterMapController(viewId, context, binaryMessenger, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据控制器
|
||||
*/
|
||||
private fun buildDataController(
|
||||
context: Context,
|
||||
viewId: Int,
|
||||
activity: FlutterBaseActivity
|
||||
): FlutterDataController {
|
||||
return FlutterDataController(viewId, context, binaryMessenger, activity)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件导入导出
|
||||
*/
|
||||
private fun buildImportExportController(
|
||||
context: Context,
|
||||
viewId: Int,
|
||||
dataBase: MapLifeDataBase
|
||||
): FlutterImportExportController {
|
||||
return FlutterImportExportController(viewId, context, binaryMessenger, dataBase)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.navinfo.collect.library.map.flutter.plugin
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LifecycleRegistry
|
||||
import com.navinfo.collect.FlutterBaseActivity
|
||||
import com.navinfo.collect.library.system.Constant
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
|
||||
object FlutterMapViewFlutterPlugin : ActivityAware, FlutterPlugin {
|
||||
private const val NATIVE_VIEW_TYPE_ID = "com.navinfo.collect/mapView"
|
||||
private var mLifecycle: Lifecycle? = null
|
||||
private lateinit var mActivity:FlutterBaseActivity
|
||||
// //旧方法
|
||||
// fun registerWith(registry: PluginRegistry) {
|
||||
// val key = FlutterMapViewFlutterPlugin::class.java.canonicalName
|
||||
// if (registry.hasPlugin(key)) {
|
||||
// return
|
||||
// }
|
||||
// val registrar = registry.registrarFor(key)
|
||||
// registrar.platformViewRegistry()
|
||||
// .registerViewFactory(NATIVE_VIEW_TYPE_ID, FlutterMapViewFactory(registrar.messenger()))
|
||||
// }
|
||||
|
||||
//新方法
|
||||
fun registerWith(
|
||||
flutterEngine: FlutterEngine,
|
||||
activity: FlutterBaseActivity,
|
||||
rootPath: String = ""
|
||||
): FlutterMapViewFactory {
|
||||
mActivity = activity
|
||||
var lifecycleProxy: LifecycleProxy = if (activity is LifecycleOwner) {
|
||||
object : LifecycleProxy {
|
||||
override fun getLifecycle(): Lifecycle {
|
||||
return (activity as LifecycleOwner).lifecycle
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ActivityLifecycleProxy(activity)
|
||||
}
|
||||
if (rootPath != "") {
|
||||
Constant.ROOT_PATH = rootPath;
|
||||
}
|
||||
|
||||
val factory =
|
||||
FlutterMapViewFactory(flutterEngine.dartExecutor.binaryMessenger, lifecycleProxy,activity)
|
||||
flutterEngine.platformViewsController.registry.registerViewFactory(
|
||||
NATIVE_VIEW_TYPE_ID,
|
||||
factory
|
||||
)
|
||||
return factory
|
||||
}
|
||||
|
||||
private class ActivityLifecycleProxy(activity: Activity) :
|
||||
LifecycleProxy, Application.ActivityLifecycleCallbacks, LifecycleOwner {
|
||||
private val mLifecycle = LifecycleRegistry(this)
|
||||
private var mRegistrarActivityHashCode: Int = activity.hashCode()
|
||||
override fun getLifecycle(): Lifecycle {
|
||||
return mLifecycle
|
||||
}
|
||||
|
||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||
if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
return
|
||||
}
|
||||
mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityStarted(activity: Activity) {
|
||||
if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
return
|
||||
}
|
||||
mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
|
||||
}
|
||||
|
||||
override fun onActivityResumed(activity: Activity) {
|
||||
if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
return
|
||||
}
|
||||
mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
}
|
||||
|
||||
override fun onActivityPaused(activity: Activity) {
|
||||
if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
return
|
||||
}
|
||||
mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
||||
}
|
||||
|
||||
override fun onActivityStopped(activity: Activity) {
|
||||
if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
return
|
||||
}
|
||||
mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
|
||||
}
|
||||
|
||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
|
||||
override fun onActivityDestroyed(activity: Activity) {
|
||||
if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
return
|
||||
}
|
||||
mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
|
||||
}
|
||||
|
||||
init {
|
||||
activity.application.registerActivityLifecycleCallbacks(this)
|
||||
}
|
||||
}
|
||||
|
||||
//首次绑定到Activity
|
||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||
mLifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding)
|
||||
}
|
||||
|
||||
//由于某些原因导致暂时解绑
|
||||
override fun onDetachedFromActivityForConfigChanges() {
|
||||
onDetachedFromActivity()
|
||||
}
|
||||
|
||||
//恢复绑定
|
||||
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
|
||||
onAttachedToActivity(binding)
|
||||
}
|
||||
|
||||
//解绑
|
||||
override fun onDetachedFromActivity() {
|
||||
mLifecycle = null
|
||||
}
|
||||
|
||||
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// val mMessenger: BinaryMessenger = binding.binaryMessenger
|
||||
|
||||
binding.platformViewRegistry.registerViewFactory(
|
||||
NATIVE_VIEW_TYPE_ID,
|
||||
FlutterMapViewFactory(binding.binaryMessenger, object : LifecycleProxy {
|
||||
override fun getLifecycle(): Lifecycle? {
|
||||
return mLifecycle
|
||||
}
|
||||
}, mActivity)
|
||||
)
|
||||
|
||||
|
||||
// // 单独配置获取版本的消息通道,和地图实例的消息通道无关
|
||||
// val methodChannel = MethodChannel(
|
||||
// mMessenger,
|
||||
// Constants.NATIVE_SDK_VERSION_CHANNEL
|
||||
// )
|
||||
// methodChannel.setMethodCallHandler(this)
|
||||
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// val binaryMessenger = binding.binaryMessenger
|
||||
|
||||
// mOfflineHandler.unInit(binaryMessenger)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.navinfo.collect.library.map.flutter.plugin
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import com.navinfo.collect.library.map.NIMapCopyView
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import io.flutter.plugin.platform.PlatformView
|
||||
|
||||
|
||||
class FlutterNiMapCopyView(context:Context,niMapView: NIMapView,
|
||||
lifecycleProxy: LifecycleProxy
|
||||
) :
|
||||
PlatformView, DefaultLifecycleObserver {
|
||||
private val copyView: NIMapCopyView = NIMapCopyView(context,niMapView);
|
||||
private var mIsDisposed = false
|
||||
private val mLifecycleProxy: LifecycleProxy = lifecycleProxy;
|
||||
|
||||
init {
|
||||
var lifecycle: Lifecycle? = mLifecycleProxy.getLifecycle()
|
||||
lifecycle?.addObserver(this)
|
||||
}
|
||||
|
||||
override fun getView(): View {
|
||||
return copyView
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
|
||||
if (mIsDisposed) {
|
||||
return
|
||||
}
|
||||
|
||||
mIsDisposed = true
|
||||
val lifecycle: Lifecycle? = mLifecycleProxy.getLifecycle()
|
||||
lifecycle?.removeObserver(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.navinfo.collect.library.map.flutter.plugin
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.data.flutter.FlutterDataController
|
||||
import com.navinfo.collect.library.map.NIMapOptions
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapConversion
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapController
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.StandardMessageCodec
|
||||
import io.flutter.plugin.platform.PlatformView
|
||||
import io.flutter.plugin.platform.PlatformViewFactory
|
||||
|
||||
class FlutterNiMapCopyViewFactory(
|
||||
private val messenger: BinaryMessenger,
|
||||
lifecycleProxy: LifecycleProxy
|
||||
) :
|
||||
PlatformViewFactory(StandardMessageCodec.INSTANCE) {
|
||||
private val binaryMessenger: BinaryMessenger = messenger
|
||||
|
||||
private var mLifecycleProxy: LifecycleProxy = lifecycleProxy
|
||||
|
||||
override fun create(context: Context, id: Int, args: Any?): PlatformView {
|
||||
return FlutterNiMapCopyView(context,args as NIMapView, mLifecycleProxy)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
//package com.navinfo.collect.library.map.flutter.plugin
|
||||
//
|
||||
//import android.app.Activity
|
||||
//import android.app.Application
|
||||
//import android.os.Bundle
|
||||
//import androidx.lifecycle.Lifecycle
|
||||
//import androidx.lifecycle.LifecycleOwner
|
||||
//import androidx.lifecycle.LifecycleRegistry
|
||||
//import com.navinfo.collect.library.system.Constant
|
||||
//import io.flutter.embedding.engine.FlutterEngine
|
||||
//import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
//import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||
//import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||
//import io.flutter.plugin.common.BinaryMessenger
|
||||
//
|
||||
//object FlutterNiMapCopyViewFlutterPlugin : ActivityAware, FlutterPlugin {
|
||||
// private const val NATIVE_VIEW_TYPE_ID = "com.navinfo.collect/copyView"
|
||||
// private var mLifecycle: Lifecycle? = null
|
||||
//
|
||||
// //新方法
|
||||
// fun registerWith(flutterEngine: FlutterEngine, activity: Activity, rootPath: String = "") {
|
||||
// var lifecycleProxy: LifecycleProxy = if (activity is LifecycleOwner) {
|
||||
// object : LifecycleProxy {
|
||||
// override fun getLifecycle(): Lifecycle {
|
||||
// return (activity as LifecycleOwner).lifecycle
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// ActivityLifecycleProxy(activity)
|
||||
// }
|
||||
// if (rootPath != "") {
|
||||
// Constant.ROOT_PATH = rootPath;
|
||||
// }
|
||||
// flutterEngine.platformViewsController.registry.registerViewFactory(
|
||||
// NATIVE_VIEW_TYPE_ID,
|
||||
// FlutterMapViewFactory(flutterEngine.dartExecutor.binaryMessenger, lifecycleProxy)
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// private class ActivityLifecycleProxy(activity: Activity) :
|
||||
// LifecycleProxy, Application.ActivityLifecycleCallbacks, LifecycleOwner {
|
||||
// private val mLifecycle = LifecycleRegistry(this)
|
||||
// private var mRegistrarActivityHashCode: Int = activity.hashCode()
|
||||
// override fun getLifecycle(): Lifecycle {
|
||||
// return mLifecycle
|
||||
// }
|
||||
//
|
||||
// override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||
// if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
// return
|
||||
// }
|
||||
// mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
|
||||
// }
|
||||
//
|
||||
//
|
||||
// override fun onActivityStarted(activity: Activity) {
|
||||
// if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
// return
|
||||
// }
|
||||
// mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
|
||||
// }
|
||||
//
|
||||
// override fun onActivityResumed(activity: Activity) {
|
||||
// if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
// return
|
||||
// }
|
||||
// mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
// }
|
||||
//
|
||||
// override fun onActivityPaused(activity: Activity) {
|
||||
// if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
// return
|
||||
// }
|
||||
// mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
||||
// }
|
||||
//
|
||||
// override fun onActivityStopped(activity: Activity) {
|
||||
// if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
// return
|
||||
// }
|
||||
// mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
|
||||
// }
|
||||
//
|
||||
// override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
|
||||
// override fun onActivityDestroyed(activity: Activity) {
|
||||
// if (activity.hashCode() != mRegistrarActivityHashCode) {
|
||||
// return
|
||||
// }
|
||||
// mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
|
||||
// }
|
||||
//
|
||||
// init {
|
||||
// activity.application.registerActivityLifecycleCallbacks(this)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||
// mLifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding)
|
||||
// }
|
||||
//
|
||||
// override fun onDetachedFromActivityForConfigChanges() {
|
||||
// onDetachedFromActivity()
|
||||
// }
|
||||
//
|
||||
// override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
|
||||
// onAttachedToActivity(binding)
|
||||
// }
|
||||
//
|
||||
// override fun onDetachedFromActivity() {
|
||||
// mLifecycle = null
|
||||
// }
|
||||
//
|
||||
// override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// binding.platformViewRegistry.registerViewFactory(
|
||||
// NATIVE_VIEW_TYPE_ID,
|
||||
// FlutterMapViewFactory(binding.binaryMessenger, object : LifecycleProxy {
|
||||
// override fun getLifecycle(): Lifecycle? {
|
||||
// return mLifecycle
|
||||
// }
|
||||
// })
|
||||
// )
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.navinfo.collect.library.map.flutter.plugin
|
||||
|
||||
import androidx.lifecycle.Lifecycle
|
||||
|
||||
interface LifecycleProxy {
|
||||
fun getLifecycle(): Lifecycle?
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.MapPosition
|
||||
|
||||
/**
|
||||
* 控制地图状态相关操作
|
||||
*/
|
||||
open class AnimationHandler(context: Context, mapView: NIMapView) :
|
||||
BaseHandler(context, mapView) {
|
||||
|
||||
|
||||
/**
|
||||
* 根据屏幕像素移动
|
||||
*
|
||||
* xPixel: 屏幕横坐标,xPixel:屏幕纵坐标
|
||||
*/
|
||||
fun animationByPixel(xPixel: Int, yPixel: Int, time: Long = 200) {
|
||||
val geoPoint =
|
||||
mMapView.vtmMap.viewport().fromScreenPoint(xPixel.toFloat(), yPixel.toFloat())
|
||||
mMapView.vtmMap.animator().animateTo(time, geoPoint)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据经纬度移动
|
||||
*
|
||||
* latitude: ,longitude:经纬度
|
||||
**
|
||||
*/
|
||||
fun animationByLonLat(latitude: Double, longitude: Double, time: Long = 200) {
|
||||
mMapView.vtmMap.animator().animateTo(time, GeoPoint(latitude, longitude))
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据经纬度,zoom值 移动
|
||||
*
|
||||
* latitude: ,longitude:经纬度
|
||||
**
|
||||
*/
|
||||
fun animationByZoom(latitude: Double, longitude: Double, zoomLevel: Int) {
|
||||
val mapPosition: MapPosition = mMapView.vtmMap.mapPosition
|
||||
if (mapPosition.getZoomLevel() < zoomLevel) {
|
||||
mapPosition.setZoomLevel(zoomLevel)
|
||||
}
|
||||
mapPosition.setPosition(latitude, longitude)
|
||||
mMapView.vtmMap.animator().animateTo(300, mapPosition)
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩小地图
|
||||
*/
|
||||
fun zoomOut() {
|
||||
val mapPosition: MapPosition = mMapView.vtmMap.mapPosition
|
||||
mapPosition.zoom = mapPosition.zoom - 1
|
||||
mMapView.vtmMap.animator().animateTo(mapPosition)
|
||||
}
|
||||
|
||||
/**
|
||||
* 放大地图
|
||||
*/
|
||||
fun zoomIn() {
|
||||
val mapPosition: MapPosition = mMapView.vtmMap.mapPosition
|
||||
mapPosition.zoom = mapPosition.zoom + 1
|
||||
mMapView.vtmMap.animator().animateTo(mapPosition)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
|
||||
open class BaseHandler(context:Context, mapView: NIMapView) {
|
||||
protected val mContext:Context = context
|
||||
protected val mMapView: NIMapView = mapView
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.NIMapView.LAYER_GROUPS
|
||||
import com.navinfo.collect.library.map.flutter.FlutterMapConversion
|
||||
import org.oscim.layers.Layer
|
||||
|
||||
/**
|
||||
* Layer 操作
|
||||
*/
|
||||
open class LayerManagerHandler(context: Context, mapView: NIMapView) :
|
||||
BaseHandler(context, mapView) {
|
||||
|
||||
//增加RasterTileLayer
|
||||
fun switchRasterTileLayer(
|
||||
url: String?,
|
||||
filePath: String? = "",
|
||||
cache: Boolean? = false,
|
||||
): Boolean {
|
||||
mMapView.removeBaseMap()
|
||||
val layer: Layer =
|
||||
mMapView.layerManager.getRasterTileLayer(mContext, url, filePath, cache!!)
|
||||
if (layer != null) {
|
||||
mMapView.vtmMap.layers().add(layer, LAYER_GROUPS.BASE_RASTER.groupIndex)
|
||||
mMapView.vtmMap.clearMap()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//删除RasterTileLayer
|
||||
fun removeRasterTileLayer(url: String) {
|
||||
|
||||
}
|
||||
|
||||
fun getBaseRasterTileLayerList(callback: (baseMapJson: String) -> Unit) {
|
||||
val strJson = FlutterMapConversion.baseMapTypeToJson(NIMapView.BASE_MAP_TYPE.values())
|
||||
callback.invoke(strJson)
|
||||
}
|
||||
|
||||
fun editLineOrPolygon(geometry: String,type: Int){
|
||||
mMapView.layerManager.showEditMapGraphical(geometry,type)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import android.widget.Toast
|
||||
import com.navinfo.collect.library.R
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.collect.library.utils.StringUtil
|
||||
import org.oscim.android.canvas.AndroidBitmap
|
||||
import org.oscim.backend.canvas.Bitmap
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.MapPosition
|
||||
import org.oscim.event.Event
|
||||
import org.oscim.layers.marker.ItemizedLayer
|
||||
import org.oscim.layers.marker.ItemizedLayer.OnItemGestureListener
|
||||
import org.oscim.layers.marker.MarkerInterface
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
import org.oscim.layers.marker.MarkerSymbol
|
||||
import org.oscim.layers.vector.PathLayer
|
||||
import org.oscim.layers.vector.geometries.Style
|
||||
import org.oscim.map.Map
|
||||
|
||||
open class LineHandler(context: Context, mapView: NIMapView) :
|
||||
BaseHandler(context, mapView), Map.UpdateListener {
|
||||
|
||||
private var editIndex: Int = -1;
|
||||
private val mPathMakers: MutableList<MarkerItem> = mutableListOf()
|
||||
|
||||
//绘制线 引导线样式
|
||||
private val newTempStyle: Style
|
||||
|
||||
//绘制线 样式
|
||||
private val lineStyle: Style
|
||||
|
||||
//线型编辑时的样式
|
||||
private val editTempStyle: Style
|
||||
|
||||
//新增线数据
|
||||
private val mPathLayer: PathLayer
|
||||
|
||||
//新增线数据引线
|
||||
private val mPathLayerTemp: PathLayer
|
||||
|
||||
//线路端点图标
|
||||
private val mPathMarkerBitmap: Bitmap
|
||||
|
||||
//线路端点marker
|
||||
private val mEndpointLayer: ItemizedLayer
|
||||
|
||||
private var bDrawLine = false
|
||||
|
||||
init {
|
||||
mMapView.vtmMap.events.bind(this)
|
||||
|
||||
//新增线数据图层和线样式
|
||||
lineStyle = Style.builder()
|
||||
.stippleColor(context.resources.getColor(R.color.draw_line_blue1_color, null))
|
||||
.strokeWidth(4f)
|
||||
.fillColor(context.resources.getColor(R.color.draw_line_blue2_color, null))
|
||||
.fillAlpha(0.5f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color, null))
|
||||
.fixed(true)
|
||||
.build()
|
||||
|
||||
newTempStyle = Style.builder()
|
||||
.stippleColor(context.resources.getColor(R.color.transparent, null))
|
||||
.stipple(30)
|
||||
.stippleWidth(30f)
|
||||
.strokeWidth(4f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color, null))
|
||||
.fixed(true)
|
||||
.randomOffset(false)
|
||||
.build()
|
||||
|
||||
editTempStyle = Style.builder()
|
||||
.stippleColor(context.resources.getColor(R.color.transparent, null))
|
||||
.stipple(30)
|
||||
.stippleWidth(30f)
|
||||
.strokeWidth(8f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_red_color, null))
|
||||
.fixed(true)
|
||||
.randomOffset(false)
|
||||
.build()
|
||||
|
||||
mPathLayer = PathLayer(mMapView.vtmMap, lineStyle)
|
||||
mMapView.layerManager.addLayer(
|
||||
"defaultLineLayer",
|
||||
mPathLayer,
|
||||
NIMapView.LAYER_GROUPS.VECTOR.ordinal
|
||||
)
|
||||
|
||||
mPathLayerTemp = if (mMapView.layerManager.containsLayer("guideLineLayer")) {
|
||||
mMapView.layerManager.getLayer("guideLineLayer") as PathLayer
|
||||
} else {
|
||||
PathLayer(mMapView.vtmMap, newTempStyle)
|
||||
}
|
||||
mMapView.layerManager.addLayer(
|
||||
"guideLineLayer",
|
||||
mPathLayerTemp,
|
||||
NIMapView.LAYER_GROUPS.VECTOR.ordinal
|
||||
)
|
||||
|
||||
mPathMarkerBitmap = AndroidBitmap(
|
||||
BitmapFactory.decodeResource(
|
||||
mContext.resources,
|
||||
R.mipmap.icon_path_maker
|
||||
)
|
||||
)
|
||||
val markerSymbol = MarkerSymbol(mPathMarkerBitmap, MarkerSymbol.HotspotPlace.CENTER)
|
||||
//新增marker图层
|
||||
mEndpointLayer = if (mMapView.layerManager.containsLayer("endpointLayer")) {
|
||||
mMapView.layerManager.getLayer("endpointLayer") as ItemizedLayer
|
||||
} else
|
||||
//新增marker图层
|
||||
ItemizedLayer(
|
||||
mMapView.vtmMap,
|
||||
java.util.ArrayList<MarkerInterface>(),
|
||||
markerSymbol,
|
||||
null
|
||||
)
|
||||
mMapView.layerManager.addLayer(
|
||||
"endpointLayer",
|
||||
mEndpointLayer,
|
||||
NIMapView.LAYER_GROUPS.VECTOR.ordinal
|
||||
)
|
||||
mEndpointLayer.setOnItemGestureListener(object : OnItemGestureListener<MarkerInterface> {
|
||||
override fun onItemSingleTapUp(index: Int, item: MarkerInterface): Boolean {
|
||||
if (bDrawLine) {
|
||||
for (i in mPathMakers.indices) {
|
||||
val item1 = mPathMakers[i]
|
||||
if (item === item1) {
|
||||
mMapView.vtmMap.animator().animateTo(
|
||||
GeoPoint(
|
||||
item.getPoint().latitude,
|
||||
item.getPoint().longitude
|
||||
)
|
||||
)
|
||||
editIndex = i
|
||||
mPathLayerTemp.setStyle(editTempStyle)
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
if (editIndex == 0 || editIndex == mPathMakers.size - 1) {
|
||||
list.add(item.getPoint())
|
||||
list.add(item.getPoint())
|
||||
} else {
|
||||
list.add(mPathMakers[editIndex - 1].geoPoint)
|
||||
list.add(item.getPoint())
|
||||
list.add(mPathMakers[editIndex + 1].geoPoint)
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onItemLongPress(index: Int, item: MarkerInterface): Boolean {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun addDrawLinePoint(geoPoint: GeoPoint): List<GeoPoint> {
|
||||
|
||||
if (!bDrawLine) {
|
||||
mPathLayer.isEnabled = true
|
||||
mPathLayerTemp.isEnabled = true
|
||||
mEndpointLayer.isEnabled = true
|
||||
bDrawLine = true
|
||||
}
|
||||
//编辑点
|
||||
if (editIndex > -1) {
|
||||
if (mPathLayer.points.size > 0) {
|
||||
var list: MutableList<GeoPoint> = mutableListOf<GeoPoint>()
|
||||
list.addAll(mPathLayer.points)
|
||||
if (list.size > 3) {
|
||||
if (editIndex == 0) {
|
||||
val listNew = mutableListOf<GeoPoint>()
|
||||
listNew.add(geoPoint)
|
||||
listNew.add(list[1])
|
||||
list.removeAt(0)
|
||||
if (GeometryTools.isLineStringCrosses(list, listNew)) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return mPathLayer.points
|
||||
}
|
||||
} else if (editIndex == list.size - 1) {
|
||||
val listNew = mutableListOf<GeoPoint>()
|
||||
listNew.add(geoPoint)
|
||||
listNew.add(list[editIndex - 1])
|
||||
list.removeAt(editIndex)
|
||||
if (GeometryTools.isLineStringCrosses(list, listNew)) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return mPathLayer.points
|
||||
}
|
||||
} else if (editIndex == 1) {
|
||||
val listNew = mutableListOf<GeoPoint>()
|
||||
listNew.add(list[0])
|
||||
listNew.add(geoPoint)
|
||||
listNew.add(list[2])
|
||||
list = list.subList(2, list.size)
|
||||
if (GeometryTools.isLineStringCrosses(list, listNew)) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return mPathLayer.points
|
||||
}
|
||||
} else if (editIndex == list.size - 2) {
|
||||
val listNew = mutableListOf<GeoPoint>()
|
||||
listNew.add(list[list.size - 1])
|
||||
listNew.add(geoPoint)
|
||||
listNew.add(list[editIndex - 1])
|
||||
list = list.subList(0, list.size - 2)
|
||||
if (GeometryTools.isLineStringCrosses(list, listNew)) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return mPathLayer.points
|
||||
}
|
||||
} else {
|
||||
val listNew = mutableListOf<GeoPoint>()
|
||||
listNew.add(list[editIndex - 1])
|
||||
listNew.add(geoPoint)
|
||||
listNew.add(list[editIndex + 1])
|
||||
val list1: MutableList<GeoPoint> = mutableListOf();
|
||||
list1.addAll(list.subList(0, editIndex))
|
||||
val list2: MutableList<GeoPoint> = mutableListOf()
|
||||
list2.addAll(list.subList(editIndex + 1, list.size))
|
||||
if (GeometryTools.isLineStringCrosses(list1, listNew)) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return mPathLayer.points
|
||||
}
|
||||
if (GeometryTools.isLineStringCrosses(list2, listNew)) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return mPathLayer.points
|
||||
}
|
||||
}
|
||||
}
|
||||
if (editIndex < mPathLayer.getPoints().size) {
|
||||
mPathLayer.points.removeAt(editIndex)
|
||||
val list2: MutableList<GeoPoint> = mutableListOf<GeoPoint>()
|
||||
list2.addAll(mPathLayer.points)
|
||||
list2.add(editIndex, geoPoint)
|
||||
mPathLayer.setPoints(list2)
|
||||
}
|
||||
}
|
||||
if (mPathMakers.size > editIndex) {
|
||||
mEndpointLayer.removeItem(mPathMakers[editIndex])
|
||||
mPathMakers.removeAt(editIndex)
|
||||
val markerItem = MarkerItem(StringUtil.createUUID(), "", "", geoPoint)
|
||||
mEndpointLayer.addItem(markerItem)
|
||||
mPathMakers.add(editIndex, markerItem)
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
// if (NMPFragmentManager.getInstance()
|
||||
// .getNewDataBottomType() === 3 && mPathMakers.size > 1
|
||||
// ) {
|
||||
// list.add(mPathMakers[0].geoPoint)
|
||||
// list.add(geoPoint)
|
||||
// list.add(mPathMakers[mPathMakers.size - 1].geoPoint)
|
||||
// } else {
|
||||
list.add(mPathMakers[mPathMakers.size - 1].geoPoint)
|
||||
list.add(geoPoint)
|
||||
// }
|
||||
mPathLayerTemp.setPoints(list)
|
||||
}
|
||||
editIndex = -1
|
||||
} else { //新增点
|
||||
val points: List<GeoPoint> = mPathLayer.points
|
||||
if (points.size > 2) {
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
list.add(geoPoint)
|
||||
list.add(points[points.size - 1])
|
||||
val bCross = GeometryTools.isLineStringCrosses(points, list)
|
||||
if (bCross) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return mPathLayer.points
|
||||
}
|
||||
}
|
||||
mPathLayer.addPoint(geoPoint)
|
||||
val markerItem = MarkerItem(StringUtil.createUUID(), "", "", geoPoint)
|
||||
mEndpointLayer.addItem(markerItem)
|
||||
mPathMakers.add(markerItem)
|
||||
}
|
||||
|
||||
return mPathLayer.points
|
||||
}
|
||||
|
||||
fun addDrawLine(list: List<GeoPoint>) {
|
||||
for(item in list){
|
||||
addDrawLinePoint(item)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onMapEvent(e: Event, mapPosition: MapPosition) {
|
||||
if (!bDrawLine)
|
||||
return
|
||||
// if (mMapView.centerPixel[1] > mMapView.vtmMap.height / 2) {
|
||||
// val geoPoint =
|
||||
// mMapView.vtmMap.viewport()
|
||||
// .fromScreenPoint(
|
||||
// mMapView.centerPixel[0],
|
||||
// mMapView.vtmMap.height - mMapView.centerPixel[1]
|
||||
// )
|
||||
// mapPosition.setPosition(geoPoint)
|
||||
// }
|
||||
if (e === Map.POSITION_EVENT) {
|
||||
if (mPathLayer.points.size > 0) {
|
||||
if (editIndex > -1) {
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
if (editIndex == 0 || editIndex == mPathMakers.size - 1) {
|
||||
list.add(mPathMakers[editIndex].geoPoint)
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude,
|
||||
mapPosition.longitude
|
||||
)
|
||||
)
|
||||
} else {
|
||||
list.add(mPathMakers[editIndex - 1].geoPoint)
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude,
|
||||
mapPosition.longitude
|
||||
)
|
||||
)
|
||||
list.add(mPathMakers[editIndex + 1].geoPoint)
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
// crossText.setText("")
|
||||
} else {
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
list.add(mPathLayer.points[mPathLayer.points.size - 1])
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude,
|
||||
mapPosition.longitude
|
||||
)
|
||||
)
|
||||
mPathLayerTemp.setPoints(list)
|
||||
if (mPathLayer.points.size > 0) {
|
||||
val listDis: MutableList<GeoPoint> = mutableListOf()
|
||||
listDis.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude,
|
||||
mapPosition.longitude
|
||||
)
|
||||
)
|
||||
// val distance: Double =
|
||||
// GeometryTools.getDistance(listDis)
|
||||
// if (distance < 1000) crossText.setText(
|
||||
// distance as Int.toString() + "米"
|
||||
// ) else {
|
||||
// val d = distance / 1000.0
|
||||
// val bg = BigDecimal(d)
|
||||
// val f1 =
|
||||
// bg.setScale(1, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
//// crossText.setText(f1.toString() + "公里")
|
||||
// }
|
||||
} else {
|
||||
// crossText.setText("")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun clean() {
|
||||
mPathLayer.clearPath()
|
||||
mPathLayer.isEnabled = false
|
||||
mPathLayerTemp.clearPath()
|
||||
mPathLayerTemp.isEnabled = false
|
||||
mEndpointLayer.removeAllItems()
|
||||
mEndpointLayer.isEnabled = false
|
||||
mPathMakers.clear()
|
||||
editIndex = -1
|
||||
bDrawLine = false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NILocation
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
|
||||
open class LocationLayerHandler(context: Context, mapView:NIMapView) :
|
||||
BaseHandler(context, mapView) {
|
||||
|
||||
private var mCurrentLocation: NILocation? = null
|
||||
|
||||
/**
|
||||
* 设置当前位置信息
|
||||
*/
|
||||
fun setCurrentLocation(location: NILocation) {
|
||||
this.mCurrentLocation = location
|
||||
mMapView.layerManager.locationLayer.setPosition(
|
||||
location.latitude,
|
||||
location.longitude,
|
||||
location.radius
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
|
||||
open class MapBaseControlHandler(context: Context, mapView: NIMapView) :
|
||||
BaseHandler(context, mapView) {
|
||||
|
||||
/**
|
||||
* 刷新地图
|
||||
*/
|
||||
fun upDateMap(redraw: Boolean = true) {
|
||||
if (redraw) {
|
||||
mMapView.vtmMap.events.fire(org.oscim.map.Map.CLEAR_EVENT, mMapView.vtmMap.mapPosition)
|
||||
}
|
||||
mMapView.vtmMap.updateMap(redraw)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.utils.StringUtil
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.layers.marker.ItemizedLayer.OnItemGestureListener
|
||||
import org.oscim.layers.marker.MarkerInterface
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
|
||||
/**
|
||||
* marker 操作
|
||||
*/
|
||||
open class MarkHandler(context: Context, mapView:NIMapView) :
|
||||
BaseHandler(context, mapView), OnItemGestureListener<MarkerInterface> {
|
||||
|
||||
//增加marker
|
||||
fun addMarker(
|
||||
geoPoint: GeoPoint,
|
||||
title: String?,
|
||||
description: String? = ""
|
||||
): MarkerItem {
|
||||
var marker: MarkerItem? = null
|
||||
for (e in mMapView.layerManager.defaultMarkerLayer.itemList) {
|
||||
if (e is MarkerItem && e.title == title) {
|
||||
marker = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (marker == null) {
|
||||
var tempTitle = title;
|
||||
if (tempTitle.isNullOrBlank()) {
|
||||
tempTitle = StringUtil.createUUID();
|
||||
}
|
||||
val marker = MarkerItem(
|
||||
tempTitle,
|
||||
description,
|
||||
geoPoint
|
||||
)
|
||||
mMapView.layerManager.defaultMarkerLayer.addItem(marker);
|
||||
mMapView.vtmMap.updateMap(true)
|
||||
return marker
|
||||
} else {
|
||||
marker.description = description
|
||||
marker.geoPoint = geoPoint
|
||||
mMapView.layerManager.defaultMarkerLayer.removeItem(marker)
|
||||
mMapView.layerManager.defaultMarkerLayer.addItem(marker)
|
||||
mMapView.vtmMap.updateMap(true)
|
||||
return marker
|
||||
}
|
||||
}
|
||||
|
||||
fun removeMarker(title: String) {
|
||||
var marker: MarkerItem? = null
|
||||
for (e in mMapView.layerManager.defaultMarkerLayer.itemList) {
|
||||
if (e is MarkerItem && e.title == title) {
|
||||
marker = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (marker != null) {
|
||||
mMapView.layerManager.defaultMarkerLayer.removeItem(marker)
|
||||
mMapView.vtmMap.updateMap(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemSingleTapUp(index: Int, item: MarkerInterface): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onItemLongPress(index: Int, item: MarkerInterface): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
package com.navinfo.collect.library.map.maphandler
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.text.TextPaint
|
||||
import android.widget.Toast
|
||||
import com.navinfo.collect.library.R
|
||||
import com.navinfo.collect.library.map.NILayerManager
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.handler.BaseHandler
|
||||
import com.navinfo.collect.library.map.layers.NIPolygonLayer
|
||||
import com.navinfo.collect.library.utils.DistanceUtil
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.collect.library.utils.StringUtil.Companion.createUUID
|
||||
import org.oscim.android.canvas.AndroidBitmap
|
||||
import org.oscim.backend.CanvasAdapter
|
||||
import org.oscim.backend.canvas.Bitmap
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.MapPosition
|
||||
import org.oscim.event.Event
|
||||
import org.oscim.layers.marker.ItemizedLayer
|
||||
import org.oscim.layers.marker.ItemizedLayer.OnItemGestureListener
|
||||
import org.oscim.layers.marker.MarkerInterface
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
import org.oscim.layers.marker.MarkerSymbol
|
||||
import org.oscim.layers.vector.PathLayer
|
||||
import org.oscim.layers.vector.geometries.Style
|
||||
import org.oscim.map.Map
|
||||
import java.math.BigDecimal
|
||||
|
||||
open class MeasureLayerHandler(context: Context, mapView: NIMapView) :
|
||||
BaseHandler(context, mapView), Map.UpdateListener {
|
||||
|
||||
private var editIndex: Int = -1;//线修型的时候,用来表示是不是正在修型,修的第几个点
|
||||
private val mPathMakers: MutableList<MarkerItem> = mutableListOf()
|
||||
private var bDrawLine = false
|
||||
private val bDrawPoint = false
|
||||
|
||||
private var mAreaLayer: ItemizedLayer
|
||||
//绘制线 样式
|
||||
private val lineStyle: Style
|
||||
|
||||
private val newTempStyle: Style
|
||||
|
||||
//线型编辑时的样式
|
||||
private val editTempStyle: Style
|
||||
|
||||
//新增线数据引线
|
||||
private var mPathLayerTemp: PathLayer
|
||||
//新增线数据
|
||||
private var mPathLayer: PathLayer
|
||||
//线路端点图标
|
||||
private var mPathMarkerBitmap: Bitmap
|
||||
|
||||
private var bDrawPolygon = false
|
||||
|
||||
private var mPolygonLayer: NIPolygonLayer
|
||||
|
||||
init {
|
||||
|
||||
//新增线数据图层和线样式
|
||||
lineStyle = Style.builder().scaleZoomLevel(20).buffer(1.0)
|
||||
.stippleColor(context.resources.getColor(R.color.draw_line_blue1_color, null))
|
||||
.strokeWidth(4f)
|
||||
.fillColor(context.resources.getColor(R.color.draw_line_blue2_color, null))
|
||||
.fillAlpha(0.5f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color, null))
|
||||
.fillColor(context.resources.getColor(R.color.draw_line_red_color,null))
|
||||
.stippleWidth(4f)
|
||||
.fixed(true)
|
||||
.build()
|
||||
|
||||
newTempStyle = Style.builder()
|
||||
.stippleColor(context.resources.getColor(R.color.transparent, null))
|
||||
.stipple(30)
|
||||
.stippleWidth(30f)
|
||||
.strokeWidth(4f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color, null))
|
||||
.fixed(true)
|
||||
.randomOffset(false)
|
||||
.build()
|
||||
|
||||
editTempStyle = Style.builder()
|
||||
.stippleColor(context.resources.getColor(R.color.transparent, null))
|
||||
.stipple(30)
|
||||
.stippleWidth(30f)
|
||||
.strokeWidth(8f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_red_color, null))
|
||||
.fixed(true)
|
||||
.randomOffset(false)
|
||||
.build()
|
||||
|
||||
mPolygonLayer = NIPolygonLayer(
|
||||
mMapView.vtmMap,
|
||||
lineStyle
|
||||
)
|
||||
mMapView.layerManager.addLayer(
|
||||
"meatureLayer",
|
||||
mPolygonLayer,
|
||||
NIMapView.LAYER_GROUPS.VECTOR.ordinal
|
||||
)
|
||||
|
||||
mPathLayerTemp = if (mMapView.layerManager.containsLayer("meatureLineLayer")) {
|
||||
mMapView.layerManager.getLayer("meatureLineLayer") as PathLayer
|
||||
} else {
|
||||
PathLayer(mMapView.vtmMap, newTempStyle)
|
||||
}
|
||||
mMapView.layerManager.addLayer(
|
||||
"meatureLineLayer",
|
||||
mPathLayerTemp,
|
||||
NIMapView.LAYER_GROUPS.VECTOR.ordinal
|
||||
)
|
||||
|
||||
mPathMarkerBitmap = AndroidBitmap(
|
||||
BitmapFactory.decodeResource(
|
||||
context.resources,
|
||||
R.mipmap.icon_path_maker
|
||||
)
|
||||
)
|
||||
|
||||
val markerSymbol = MarkerSymbol(mPathMarkerBitmap, MarkerSymbol.HotspotPlace.CENTER)
|
||||
|
||||
mAreaLayer = ItemizedLayer(mMapView.vtmMap, ArrayList(), markerSymbol, null)
|
||||
|
||||
mPathLayer = PathLayer(mMapView.vtmMap, lineStyle)
|
||||
|
||||
mMapView.vtmMap.layers().add(mPathLayer, NIMapView.LAYER_GROUPS.OTHER.ordinal)
|
||||
|
||||
}
|
||||
|
||||
open fun drawLineOrPolygon(type: Int) {
|
||||
bDrawLine = true
|
||||
|
||||
//画面
|
||||
if (type == 3) {
|
||||
if (mPolygonLayer == null) {
|
||||
mPolygonLayer = NIPolygonLayer(mMapView.vtmMap, lineStyle)
|
||||
mMapView.vtmMap.layers().add(mPolygonLayer, NIMapView.LAYER_GROUPS.OTHER.ordinal)
|
||||
} else if (!mPolygonLayer.isEnabled) {
|
||||
mPolygonLayer.isEnabled = true
|
||||
}
|
||||
} else {
|
||||
if (mPathLayer == null) {
|
||||
mPathLayer = PathLayer(mMapView.vtmMap, lineStyle)
|
||||
mMapView.vtmMap.layers().add(mPathLayer, NIMapView.LAYER_GROUPS.OTHER.ordinal)
|
||||
} else if (!mPathLayer.isEnabled()) {
|
||||
mPathLayer.setEnabled(true)
|
||||
}
|
||||
}
|
||||
//上一个点的引线
|
||||
if (mPathLayerTemp == null) {
|
||||
mPathLayerTemp = PathLayer(mMapView.vtmMap, newTempStyle)
|
||||
mMapView.vtmMap.layers().add(mPathLayerTemp, NIMapView.LAYER_GROUPS.OTHER.ordinal)
|
||||
} else if (!mPathLayerTemp.isEnabled) {
|
||||
mPathLayerTemp.isEnabled = true
|
||||
}
|
||||
val geoPoint: GeoPoint =
|
||||
GeoPoint(mMapView.vtmMap.getMapPosition().getLatitude(), mMapView.vtmMap.getMapPosition().getLongitude())
|
||||
|
||||
//编辑点
|
||||
if (editIndex > -1) {
|
||||
if (mPathMakers.size > editIndex) {
|
||||
mMapView.layerManager.removeMarker(mPathMakers[editIndex], NILayerManager.MARQUEE_MARKER_LAYER)
|
||||
mPathMakers.removeAt(editIndex)
|
||||
if (mPathMarkerBitmap == null) {
|
||||
mPathMarkerBitmap = AndroidBitmap(
|
||||
BitmapFactory.decodeResource(
|
||||
mContext.getResources(),
|
||||
R.mipmap.icon_path_maker
|
||||
)
|
||||
)
|
||||
}
|
||||
val markerItem = MarkerItem(createUUID(), "", "", geoPoint)
|
||||
val markerSymbol = MarkerSymbol(mPathMarkerBitmap, MarkerSymbol.HotspotPlace.CENTER)
|
||||
markerItem.marker = markerSymbol
|
||||
mMapView.layerManager.addMarker2MarkerLayer(
|
||||
markerItem,
|
||||
mPathMarkerBitmap,
|
||||
NILayerManager.MARQUEE_MARKER_LAYER,
|
||||
NIMapView.LAYER_GROUPS.OTHER.ordinal,
|
||||
itemGestureListener
|
||||
)
|
||||
mPathMakers.add(editIndex, markerItem)
|
||||
if (mPathLayer != null && mPathLayer.getPoints().size > 0) {
|
||||
val list: MutableList<GeoPoint> = mPathLayer.getPoints()
|
||||
if (editIndex < list.size) {
|
||||
list.removeAt(editIndex)
|
||||
val list2: MutableList<GeoPoint> = java.util.ArrayList(list)
|
||||
list2.add(editIndex, geoPoint)
|
||||
mPathLayer.setPoints(list2)
|
||||
}
|
||||
} else if (mPolygonLayer != null && mPolygonLayer.points.size > 0) {
|
||||
val list = mPolygonLayer.points
|
||||
if (editIndex < list.size) {
|
||||
list.removeAt(editIndex)
|
||||
val list2: MutableList<GeoPoint> = java.util.ArrayList(list)
|
||||
list2.add(editIndex, geoPoint)
|
||||
mPolygonLayer.setPoints(list2)
|
||||
}
|
||||
}
|
||||
if (mPathLayerTemp != null) {
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList<GeoPoint>()
|
||||
if (type == 3 && mPathMakers.size > 1) {
|
||||
list.add(mPathMakers[0].geoPoint)
|
||||
list.add(geoPoint)
|
||||
list.add(mPathMakers[mPathMakers.size - 1].geoPoint)
|
||||
} else {
|
||||
list.add(mPathMakers[mPathMakers.size - 1].geoPoint)
|
||||
list.add(geoPoint)
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
}
|
||||
}
|
||||
editIndex = -1
|
||||
} else { //新增点
|
||||
if (type == 3) {
|
||||
val points: MutableList<GeoPoint> = java.util.ArrayList(mPolygonLayer.points)
|
||||
if (points.size > 2) {
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList()
|
||||
points.add(points[0])
|
||||
list.add(points[0])
|
||||
list.add(geoPoint)
|
||||
list.add(mPolygonLayer.points[mPolygonLayer.points.size - 1])
|
||||
val bCross = GeometryTools.isPolygonCrosses(points, list)
|
||||
if (bCross == true) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
}
|
||||
mPolygonLayer.addPoint(geoPoint)
|
||||
} else {
|
||||
val points: List<GeoPoint> = mPathLayer.getPoints()
|
||||
if (points.size > 2) {
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList()
|
||||
list.add(geoPoint)
|
||||
list.add(points[points.size - 1])
|
||||
val bCross = GeometryTools.isLineStringCrosses(points, list)
|
||||
if (bCross == true) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
}
|
||||
mPathLayer.addPoint(geoPoint)
|
||||
}
|
||||
if (mPathMarkerBitmap == null) {
|
||||
mPathMarkerBitmap = AndroidBitmap(
|
||||
BitmapFactory.decodeResource(
|
||||
mContext.getResources(),
|
||||
R.mipmap.icon_path_maker
|
||||
)
|
||||
)
|
||||
}
|
||||
val markerItem = MarkerItem(createUUID(), "", "", geoPoint)
|
||||
val markerSymbol = MarkerSymbol(mPathMarkerBitmap, MarkerSymbol.HotspotPlace.CENTER)
|
||||
markerItem.marker = markerSymbol
|
||||
mMapView.layerManager.addMarker2MarkerLayer(
|
||||
markerItem,
|
||||
mPathMarkerBitmap,
|
||||
NILayerManager.MARQUEE_MARKER_LAYER,
|
||||
NIMapView.LAYER_GROUPS.OTHER.ordinal,
|
||||
itemGestureListener
|
||||
)
|
||||
mPathMakers.add(markerItem)
|
||||
}
|
||||
showAreaLayer()
|
||||
}
|
||||
|
||||
open fun drawLineBackspace() {
|
||||
if (mPathLayer != null && mPathLayer.getPoints().size > 0) {
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList<GeoPoint>(mPathLayer.getPoints())
|
||||
val point = list[mPathLayer.getPoints().size - 1]
|
||||
list.remove(point)
|
||||
mPathLayer.setPoints(list)
|
||||
mMapView.layerManager.jumpToPosition(point.longitude, point.latitude, 0)
|
||||
} else if (mPolygonLayer != null && mPolygonLayer.points.size > 0) {
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList<GeoPoint>(mPolygonLayer.points)
|
||||
val point = list[mPolygonLayer.points.size - 1]
|
||||
list.remove(point)
|
||||
mPolygonLayer.setPoints(list)
|
||||
mMapView.layerManager.jumpToPosition(point!!.longitude, point.latitude, 0)
|
||||
}
|
||||
if (mPathMakers.size > 0) {
|
||||
var item: MarkerItem? = mPathMakers[mPathMakers.size - 1]
|
||||
mMapView.layerManager.removeMarker(item, NILayerManager.MARQUEE_MARKER_LAYER)
|
||||
mPathMakers.remove(item)
|
||||
item = null
|
||||
}
|
||||
if (mPathMakers.size == 0 && mPathLayerTemp != null) {
|
||||
mPathLayerTemp.clearPath()
|
||||
}
|
||||
editIndex = -1
|
||||
if (mPathLayerTemp != null) {
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 隐藏面积计算
|
||||
*/
|
||||
open fun hideAreaLayer() {
|
||||
if (mAreaLayer != null) {
|
||||
mAreaLayer.removeAllItems()
|
||||
mMapView.vtmMap.layers().remove(mAreaLayer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 显示面积计算
|
||||
*/
|
||||
open fun showAreaLayer() {
|
||||
if (mAreaLayer != null) {
|
||||
mAreaLayer.removeAllItems()
|
||||
mMapView.vtmMap.layers().remove(mAreaLayer)
|
||||
}
|
||||
if (mPolygonLayer != null && mPolygonLayer.points.size > 2) {
|
||||
val list: MutableList<GeoPoint> = ArrayList(mPolygonLayer.points)
|
||||
val area = DistanceUtil.planarPolygonAreaMeters2(list)
|
||||
var areaString: String
|
||||
if (area < 1000000) {
|
||||
areaString = area.toString()+"平方米"
|
||||
} else if (area < 10000000000.0){
|
||||
val d = area / 1000000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 = bg.setScale(1, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
areaString = f1.toString() + "平方公里"
|
||||
} else {
|
||||
val d = area / 10000000000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 = bg.setScale(1, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
areaString = f1.toString() + "万平方公里"
|
||||
}
|
||||
val textPaint = TextPaint()
|
||||
textPaint.textSize = 13 * CanvasAdapter.getScale()
|
||||
textPaint.color = Color.BLUE
|
||||
val width = Math.ceil(textPaint.measureText(areaString).toDouble()).toInt()
|
||||
val fontMetrics = textPaint.fontMetrics
|
||||
val height =
|
||||
Math.ceil((Math.abs(fontMetrics.bottom) + Math.abs(fontMetrics.top)).toDouble())
|
||||
.toInt()
|
||||
val bitmap = android.graphics.Bitmap.createBitmap(
|
||||
width,
|
||||
height,
|
||||
android.graphics.Bitmap.Config.ARGB_8888
|
||||
)
|
||||
val canvas = Canvas(bitmap)
|
||||
canvas.drawText(areaString, 0f, Math.abs(fontMetrics.ascent), textPaint)
|
||||
val bitmap2: Bitmap = AndroidBitmap(bitmap)
|
||||
val markerSymbol = MarkerSymbol(bitmap2, MarkerSymbol.HotspotPlace.CENTER)
|
||||
mAreaLayer = ItemizedLayer(mMapView.vtmMap, ArrayList(), markerSymbol, null)
|
||||
mMapView.vtmMap.layers().add(mAreaLayer)
|
||||
list.add(list[0])
|
||||
val polygon = GeometryTools.createPolygon(list)
|
||||
val point = polygon.centroid
|
||||
val item = MarkerItem(areaString, "", GeoPoint(point.coordinate.y, point.coordinate.x))
|
||||
mAreaLayer.removeAllItems()
|
||||
mAreaLayer.addItem(item)
|
||||
mAreaLayer.update()
|
||||
}
|
||||
}
|
||||
|
||||
open fun removeLine() {
|
||||
bDrawLine = false
|
||||
editIndex = -1
|
||||
for (item in mPathMakers) {
|
||||
mMapView.layerManager.removeMarker(item, NILayerManager.MARQUEE_MARKER_LAYER)
|
||||
}
|
||||
mPathMakers.clear()
|
||||
if (mPathLayer != null) {
|
||||
mPathLayer.clearPath()
|
||||
mPathLayer.isEnabled = false
|
||||
}
|
||||
if (mPolygonLayer != null) {
|
||||
mPolygonLayer.clearPath()
|
||||
mPolygonLayer.isEnabled = false
|
||||
}
|
||||
if (mPathLayerTemp != null) {
|
||||
mPathLayerTemp.clearPath()
|
||||
mPathLayerTemp.isEnabled = false
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
}
|
||||
hideAreaLayer()
|
||||
}
|
||||
|
||||
fun clean() {
|
||||
removeLine()
|
||||
mMapView.vtmMap.updateMap(true)
|
||||
}
|
||||
|
||||
override fun onMapEvent(e: Event?, mapPosition: MapPosition?) {
|
||||
|
||||
}
|
||||
|
||||
private val itemGestureListener: OnItemGestureListener<*> =
|
||||
object : OnItemGestureListener<MarkerInterface> {
|
||||
override fun onItemSingleTapUp(index: Int, item: MarkerInterface): Boolean {
|
||||
if (bDrawLine) {
|
||||
for (i in mPathMakers.indices) {
|
||||
val item1 = mPathMakers[i]
|
||||
if (item === item1) {
|
||||
mMapView.layerManager.jumpToPosition(item.getPoint().longitude, item.getPoint().latitude, 0)
|
||||
editIndex = i
|
||||
if (mPathLayerTemp != null) {
|
||||
mPathLayerTemp.setStyle(editTempStyle)
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList<GeoPoint>()
|
||||
if (editIndex == 0 || editIndex == mPathMakers.size - 1) {
|
||||
list.add(item.geoPoint as Nothing)
|
||||
list.add(item.geoPoint as Nothing)
|
||||
} else {
|
||||
list.add(mPathMakers[editIndex - 1].geoPoint as Nothing)
|
||||
list.add(item.geoPoint as Nothing)
|
||||
list.add(mPathMakers[editIndex + 1].geoPoint as Nothing)
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onItemLongPress(index: Int, item: MarkerInterface): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import com.navinfo.collect.library.R
|
||||
import com.navinfo.collect.library.map.NILayerManager
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.layers.NIPolygonLayer
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.collect.library.utils.StringUtil
|
||||
import com.navinfo.collect.library.utils.StringUtil.Companion.createUUID
|
||||
import org.oscim.android.canvas.AndroidBitmap
|
||||
import org.oscim.backend.canvas.Bitmap
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.MapPosition
|
||||
import org.oscim.event.Event
|
||||
import org.oscim.layers.marker.ItemizedLayer
|
||||
import org.oscim.layers.marker.ItemizedLayer.OnItemGestureListener
|
||||
import org.oscim.layers.marker.MarkerInterface
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
import org.oscim.layers.marker.MarkerSymbol
|
||||
import org.oscim.layers.vector.PathLayer
|
||||
import org.oscim.layers.vector.geometries.Style
|
||||
import org.oscim.map.Map
|
||||
|
||||
open class PolygonHandler(context: Context, mapView: NIMapView) :
|
||||
BaseHandler(context, mapView), Map.UpdateListener {
|
||||
|
||||
private var editIndex: Int = -1;
|
||||
private val mPathMakers: MutableList<MarkerItem> = mutableListOf()
|
||||
|
||||
//绘制线 引导线样式
|
||||
private val newTempStyle: Style
|
||||
|
||||
//绘制线 样式
|
||||
private val lineStyle: Style
|
||||
|
||||
//线型编辑时的样式
|
||||
private val editTempStyle: Style
|
||||
|
||||
//新增线数据引线
|
||||
private var mPathLayerTemp: PathLayer
|
||||
|
||||
//线路端点图标
|
||||
private var mPathMarkerBitmap: Bitmap
|
||||
|
||||
//线路端点marker
|
||||
private val mEndpointLayer: ItemizedLayer
|
||||
|
||||
private var bDrawPolygon = false
|
||||
|
||||
private var mPolygonLayer: NIPolygonLayer
|
||||
|
||||
init {
|
||||
mMapView.vtmMap.events.bind(this)
|
||||
|
||||
//新增线数据图层和线样式
|
||||
lineStyle = Style.builder().scaleZoomLevel(20).buffer(1.0)
|
||||
.stippleColor(context.resources.getColor(R.color.draw_line_blue1_color, null))
|
||||
.strokeWidth(4f)
|
||||
.fillColor(context.resources.getColor(R.color.draw_line_blue2_color, null))
|
||||
.fillAlpha(0.5f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color, null))
|
||||
.fillColor(context.resources.getColor(R.color.draw_line_red_color, null))
|
||||
.stippleWidth(4f)
|
||||
.fixed(true)
|
||||
.build()
|
||||
|
||||
newTempStyle = Style.builder()
|
||||
.stippleColor(context.resources.getColor(R.color.transparent, null))
|
||||
.stipple(30)
|
||||
.stippleWidth(30f)
|
||||
.strokeWidth(4f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color, null))
|
||||
.fixed(true)
|
||||
.randomOffset(false)
|
||||
.build()
|
||||
|
||||
editTempStyle = Style.builder()
|
||||
.stippleColor(context.resources.getColor(R.color.transparent, null))
|
||||
.stipple(30)
|
||||
.stippleWidth(30f)
|
||||
.strokeWidth(8f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_red_color, null))
|
||||
.fixed(true)
|
||||
.randomOffset(false)
|
||||
.build()
|
||||
|
||||
mPolygonLayer = NIPolygonLayer(
|
||||
mMapView.vtmMap,
|
||||
lineStyle
|
||||
)
|
||||
mMapView.layerManager.addLayer(
|
||||
"defaultPolygonLayer",
|
||||
mPolygonLayer,
|
||||
NIMapView.LAYER_GROUPS.VECTOR.ordinal
|
||||
)
|
||||
|
||||
mPathLayerTemp = if (mMapView.layerManager.containsLayer("guideLineLayer")) {
|
||||
mMapView.layerManager.getLayer("guideLineLayer") as PathLayer
|
||||
} else {
|
||||
PathLayer(mMapView.vtmMap, newTempStyle)
|
||||
}
|
||||
mMapView.layerManager.addLayer(
|
||||
"guideLineLayer",
|
||||
mPathLayerTemp,
|
||||
NIMapView.LAYER_GROUPS.VECTOR.ordinal
|
||||
)
|
||||
|
||||
mPathMarkerBitmap = AndroidBitmap(
|
||||
BitmapFactory.decodeResource(
|
||||
mContext.resources,
|
||||
R.mipmap.icon_path_maker
|
||||
)
|
||||
)
|
||||
|
||||
val markerSymbol = MarkerSymbol(mPathMarkerBitmap, MarkerSymbol.HotspotPlace.CENTER)
|
||||
|
||||
mEndpointLayer = if (mMapView.layerManager.containsLayer("endpointLayer")) {
|
||||
mMapView.layerManager.getLayer("endpointLayer") as ItemizedLayer
|
||||
} else
|
||||
//新增marker图层
|
||||
ItemizedLayer(
|
||||
mMapView.vtmMap,
|
||||
java.util.ArrayList<MarkerInterface>(),
|
||||
markerSymbol,
|
||||
null
|
||||
)
|
||||
mMapView.layerManager.addLayer(
|
||||
"endpointLayer",
|
||||
mEndpointLayer,
|
||||
NIMapView.LAYER_GROUPS.VECTOR.ordinal
|
||||
)
|
||||
|
||||
mEndpointLayer.setOnItemGestureListener(object : OnItemGestureListener<MarkerInterface> {
|
||||
override fun onItemSingleTapUp(index: Int, item: MarkerInterface): Boolean {
|
||||
if (bDrawPolygon) {
|
||||
for (i in mPathMakers.indices) {
|
||||
val item1 = mPathMakers[i]
|
||||
if (item === item1) {
|
||||
mMapView.vtmMap.animator().animateTo(
|
||||
GeoPoint(
|
||||
item.getPoint().latitude,
|
||||
item.getPoint().longitude
|
||||
)
|
||||
)
|
||||
editIndex = i
|
||||
mPathLayerTemp.setStyle(editTempStyle)
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
if (editIndex == 0 || editIndex == mPathMakers.size - 1) {
|
||||
list.add(item.getPoint())
|
||||
list.add(item.getPoint())
|
||||
} else {
|
||||
list.add(mPathMakers[editIndex - 1].geoPoint)
|
||||
list.add(item.getPoint())
|
||||
list.add(mPathMakers[editIndex + 1].geoPoint)
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onItemLongPress(index: Int, item: MarkerInterface): Boolean {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun addDrawPolygonPoint(geoPoint: GeoPoint): List<GeoPoint> {
|
||||
if (!bDrawPolygon) {
|
||||
mPolygonLayer.isEnabled = true
|
||||
mPathLayerTemp.isEnabled = true
|
||||
mEndpointLayer.isEnabled = true
|
||||
bDrawPolygon = true
|
||||
}
|
||||
//编辑点
|
||||
if (editIndex > -1) {
|
||||
if (mPolygonLayer.points.size > 0) {
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
list.addAll(mPolygonLayer.points)
|
||||
if (list.size > 3) {
|
||||
val newList: MutableList<GeoPoint> = mutableListOf()
|
||||
if (editIndex == 0) {
|
||||
newList.add(list[list.size - 1])
|
||||
newList.add(geoPoint)
|
||||
newList.add(list[editIndex + 1])
|
||||
} else if (editIndex == list.size - 1) {
|
||||
newList.add(list[0])
|
||||
newList.add(geoPoint)
|
||||
newList.add(list[editIndex - 1])
|
||||
} else {
|
||||
newList.add(list[editIndex - 1])
|
||||
newList.add(geoPoint)
|
||||
newList.add(list[editIndex + 1])
|
||||
}
|
||||
val newList2: MutableList<GeoPoint> = mutableListOf()
|
||||
for (i in editIndex + 1 until list.size) {
|
||||
newList2.add(list[i])
|
||||
}
|
||||
for (i in 0 until editIndex) {
|
||||
newList2.add(list[i])
|
||||
}
|
||||
if (GeometryTools.isLineStringCrosses(newList, newList2)) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return mPolygonLayer.points
|
||||
}
|
||||
}
|
||||
if (editIndex < list.size) {
|
||||
list.removeAt(editIndex)
|
||||
val list2: MutableList<GeoPoint> = mutableListOf()
|
||||
list2.addAll(list)
|
||||
list2.add(editIndex, geoPoint)
|
||||
mPolygonLayer.setPoints(list2)
|
||||
}
|
||||
}
|
||||
if (mPathMakers.size > editIndex) {
|
||||
mEndpointLayer.removeItem(mPathMakers[editIndex])
|
||||
mPathMakers.removeAt(editIndex)
|
||||
val markerItem = MarkerItem(StringUtil.createUUID(), "", "", geoPoint)
|
||||
mEndpointLayer.addItem(markerItem)
|
||||
mPathMakers.add(editIndex, markerItem)
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
if (mPathMakers.size > 1) {
|
||||
list.add(mPathMakers[0].geoPoint)
|
||||
list.add(geoPoint)
|
||||
list.add(mPathMakers[mPathMakers.size - 1].geoPoint)
|
||||
} else {
|
||||
list.add(mPathMakers[mPathMakers.size - 1].geoPoint)
|
||||
list.add(geoPoint)
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
}
|
||||
editIndex = -1
|
||||
} else { //新增点
|
||||
val points: MutableList<GeoPoint> = mutableListOf()
|
||||
points.addAll(mPolygonLayer.points)
|
||||
if (points.size > 2) {
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
points.add(points[0])
|
||||
list.add(points[0])
|
||||
list.add(geoPoint)
|
||||
list.add(mPolygonLayer.points[mPolygonLayer.points.size - 1])
|
||||
if (GeometryTools.isPolygonCrosses(points, list)) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return mPolygonLayer.points
|
||||
}
|
||||
}
|
||||
mPolygonLayer.addPoint(geoPoint)
|
||||
val markerItem = MarkerItem(StringUtil.createUUID(), "", "", geoPoint)
|
||||
mEndpointLayer.addItem(markerItem)
|
||||
mPathMakers.add(markerItem)
|
||||
}
|
||||
return mPolygonLayer.points
|
||||
}
|
||||
|
||||
fun addDrawPolygon(list: List<GeoPoint>) {
|
||||
for (item in list) {
|
||||
addDrawPolygonPoint(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMapEvent(e: Event, mapPosition: MapPosition) {
|
||||
if (!bDrawPolygon)
|
||||
return
|
||||
// if (mMapView.centerPixel[1] > mMapView.vtmMap.height / 2) {
|
||||
// val geoPoint =
|
||||
// mMapView.vtmMap.viewport()
|
||||
// .fromScreenPoint(
|
||||
// mMapView.centerPixel[0],
|
||||
// mMapView.vtmMap.height - mMapView.centerPixel[1]
|
||||
// )
|
||||
// mapPosition.setPosition(geoPoint)
|
||||
// }
|
||||
if (e === Map.POSITION_EVENT) {
|
||||
if (mPolygonLayer.points.size > 0) {
|
||||
if (editIndex > -1) {
|
||||
val list: MutableList<GeoPoint> =
|
||||
mutableListOf()
|
||||
if (editIndex == 0 || editIndex == mPathMakers.size - 1) {
|
||||
list.add(mPathMakers[editIndex].geoPoint)
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude,
|
||||
mapPosition.longitude
|
||||
)
|
||||
)
|
||||
} else {
|
||||
list.add(mPathMakers[editIndex - 1].geoPoint)
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude,
|
||||
mapPosition.longitude
|
||||
)
|
||||
)
|
||||
list.add(mPathMakers[editIndex + 1].geoPoint)
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
// crossText.setText("")
|
||||
} else {
|
||||
val list: MutableList<GeoPoint> =
|
||||
mutableListOf()
|
||||
if (mPolygonLayer.points.size > 1) {
|
||||
list.add(mPolygonLayer.points[0])
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude,
|
||||
mapPosition.longitude
|
||||
)
|
||||
)
|
||||
list.add(
|
||||
mPolygonLayer.points[mPolygonLayer.points.size - 1]
|
||||
)
|
||||
} else {
|
||||
list.add(
|
||||
mPolygonLayer.points[mPolygonLayer.points.size - 1]
|
||||
)
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude,
|
||||
mapPosition.longitude
|
||||
)
|
||||
)
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
if (mPolygonLayer.points.size > 1) {
|
||||
val list1: MutableList<GeoPoint> =
|
||||
mutableListOf()
|
||||
list1.addAll(mPolygonLayer.points)
|
||||
list1.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude,
|
||||
mapPosition.longitude
|
||||
)
|
||||
)
|
||||
list1.add(mPolygonLayer.points[0])
|
||||
//// val area: Double =
|
||||
//// GeometryTools.PlanarPolygonAreaMeters2(list1)
|
||||
//// if (area < 1000000) crossText.setText(
|
||||
//// area as Int.toString
|
||||
//// () + "平方米"
|
||||
//// ) else if (area < 10000000000.0) {
|
||||
//// val d = area / 1000000.0
|
||||
//// val bg = BigDecimal(d)
|
||||
//// val f1 =
|
||||
//// bg.setScale(1, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
//// crossText.setText(f1.toString() + "平方公里")
|
||||
//// } else {
|
||||
//// val d = area / 10000000000.0
|
||||
//// val bg = BigDecimal(d)
|
||||
//// val f1 =
|
||||
//// bg.setScale(1, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
//// crossText.setText(f1.toString() + "万平方公里")
|
||||
//// }
|
||||
// } else {
|
||||
//// crossText.setText("")
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun clean() {
|
||||
mPolygonLayer.clearPath()
|
||||
mPolygonLayer.isEnabled = false
|
||||
mPathLayerTemp.clearPath()
|
||||
mPathLayerTemp.isEnabled = false
|
||||
mEndpointLayer.removeAllItems()
|
||||
mEndpointLayer.isEnabled = false
|
||||
mPathMakers.clear()
|
||||
editIndex = -1
|
||||
bDrawPolygon = false
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user