diff --git a/app/build.gradle b/app/build.gradle index 77c2faa..50be1b0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,7 +7,7 @@ android { defaultConfig { applicationId "com.navinfo.outdoor" - minSdkVersion 22 + minSdkVersion 24 targetSdkVersion 30 versionCode 23 versionName "8.220617" @@ -62,7 +62,6 @@ dependencies { implementation 'androidx.navigation:navigation-fragment:2.1.0' implementation 'androidx.navigation:navigation-ui:2.1.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation files('libs\\jts-1.13.jar') testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' @@ -82,6 +81,7 @@ dependencies { //网络框架 implementation 'com.lzy.net:okgo:3.0.4' + implementation 'com.lzy.net:okrx2:2.0.2' implementation 'com.google.code.gson:gson:2.8.5' //retrofit+rxJava diff --git a/app/libs/gt-epsg-hsql-25.0.jar b/app/libs/gt-epsg-hsql-25.0.jar new file mode 100644 index 0000000..f56fecc Binary files /dev/null and b/app/libs/gt-epsg-hsql-25.0.jar differ diff --git a/app/libs/gt-main-25.0.jar b/app/libs/gt-main-25.0.jar new file mode 100644 index 0000000..4e34260 Binary files /dev/null and b/app/libs/gt-main-25.0.jar differ diff --git a/app/libs/jts-1.13.jar b/app/libs/jts-1.13.jar deleted file mode 100644 index bbaa20b..0000000 Binary files a/app/libs/jts-1.13.jar and /dev/null differ diff --git a/app/libs/jts-core-1.18.2.jar b/app/libs/jts-core-1.18.2.jar new file mode 100644 index 0000000..8da196f Binary files /dev/null and b/app/libs/jts-core-1.18.2.jar differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 684f37b..8ea8267 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -113,6 +113,10 @@ <activity android:name=".activity.VideoActivity" android:screenOrientation="portrait" /> + <!--自动拍照界面--> + <activity + android:name=".activity.AutoTakePictureActivity" + android:screenOrientation="portrait" /> <activity android:name=".activity.UserActivity" android:configChanges="keyboardHidden|orientation" diff --git a/app/src/main/java/com/navinfo/outdoor/activity/AutoTakePictureActivity.java b/app/src/main/java/com/navinfo/outdoor/activity/AutoTakePictureActivity.java new file mode 100644 index 0000000..c3c7150 --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/activity/AutoTakePictureActivity.java @@ -0,0 +1,1492 @@ +package com.navinfo.outdoor.activity; + +import static com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE; +import static com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +import android.location.Location; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.DisplayMetrics; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.Switch; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.AppCompatActivity; + +import com.github.lazylibrary.util.FileUtils; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.kongzue.dialog.interfaces.OnDialogButtonClickListener; +import com.kongzue.dialog.util.BaseDialog; +import com.kongzue.dialog.util.DialogSettings; +import com.kongzue.dialog.v3.CustomDialog; +import com.kongzue.dialog.v3.MessageDialog; +import com.kongzue.dialog.v3.WaitDialog; +import com.lzy.okgo.OkGo; +import com.lzy.okgo.model.HttpParams; +import com.navinfo.outdoor.R; +import com.navinfo.outdoor.api.Constant; +import com.navinfo.outdoor.api.UserApplication; +import com.navinfo.outdoor.base.BaseActivity; +import com.navinfo.outdoor.bean.JobSearchBean; +import com.navinfo.outdoor.bean.LocationRecorder; +import com.navinfo.outdoor.bean.RoadMatchEntity; +import com.navinfo.outdoor.bean.RoadSaveBean; +import com.navinfo.outdoor.bean.TaskByNetBean; +import com.navinfo.outdoor.bean.UnPolygonTaskBean; +import com.navinfo.outdoor.http.Callback; +import com.navinfo.outdoor.http.HttpInterface; +import com.navinfo.outdoor.http.OkGoBuilder; +import com.navinfo.outdoor.room.InsertAndUpdateUtils; +import com.navinfo.outdoor.room.LocationRecorderDao; +import com.navinfo.outdoor.room.PoiDao; +import com.navinfo.outdoor.room.PoiDatabase; +import com.navinfo.outdoor.room.PoiEntity; +import com.navinfo.outdoor.util.AWMp4ParserHelper; +import com.navinfo.outdoor.util.FlushTokenUtil; +import com.navinfo.outdoor.util.GPSUtils; +import com.navinfo.outdoor.util.Geohash; +import com.navinfo.outdoor.util.GeometryTools; +import com.navinfo.outdoor.util.Gps; +import com.navinfo.outdoor.util.MyTecentLocationSource; +import com.navinfo.outdoor.util.PreserveUtils; +import com.navinfo.outdoor.util.SystemTTS; +import com.navinfo.outdoor.util.TencentMarkerUtils; +import com.navinfo.outdoor.util.TimestampUtil; +import com.navinfo.outdoor.util.ToastUtils; +import com.otaliastudios.cameraview.CameraListener; +import com.otaliastudios.cameraview.CameraLogger; +import com.otaliastudios.cameraview.CameraOptions; +import com.otaliastudios.cameraview.CameraView; +import com.otaliastudios.cameraview.FileCallback; +import com.otaliastudios.cameraview.PictureResult; +import com.otaliastudios.cameraview.controls.Mode; +import com.otaliastudios.cameraview.size.AspectRatio; +import com.otaliastudios.cameraview.size.SizeSelector; +import com.otaliastudios.cameraview.size.SizeSelectors; +import com.tencent.map.geolocation.TencentLocation; +import com.tencent.map.geolocation.TencentPoi; +import com.tencent.tencentmap.mapsdk.maps.CameraUpdate; +import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory; +import com.tencent.tencentmap.mapsdk.maps.TencentMap; +import com.tencent.tencentmap.mapsdk.maps.TextureMapView; +import com.tencent.tencentmap.mapsdk.maps.UiSettings; +import com.tencent.tencentmap.mapsdk.maps.interfaces.Removable; +import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor; +import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory; +import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition; +import com.tencent.tencentmap.mapsdk.maps.model.LatLng; +import com.tencent.tencentmap.mapsdk.maps.model.Marker; +import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions; +import com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle; +import com.tencent.tencentmap.mapsdk.maps.model.Polyline; +import com.tencent.tencentmap.mapsdk.maps.model.PolylineOptions; +import com.umeng.commonsdk.internal.crash.UMCrashManager; +import com.umeng.umcrash.UMCrash; +import org.locationtech.jts.algorithm.Angle; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.CoordinateSequence; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.MultiLineString; +import org.locationtech.jts.geom.Point; +import com.wanghong.webpnative.WebPNative; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.geom.PrecisionModel; +import org.locationtech.jts.geom.impl.CoordinateArraySequence; +import org.locationtech.jts.geom.impl.PackedCoordinateSequence; + +import java.io.File; +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Timer; +import java.util.TimerTask; +import java.util.stream.Collectors; + +import io.reactivex.BackpressureStrategy; +import io.reactivex.Flowable; +import io.reactivex.FlowableEmitter; +import io.reactivex.FlowableOnSubscribe; +import io.reactivex.Observable; +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; +import io.reactivex.ObservableSource; +import io.reactivex.Observer; +import io.reactivex.Scheduler; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Action; +import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import io.reactivex.schedulers.Schedulers; +import okhttp3.Response; + +/** + * 拍照 + * (poi录像 和 道路) + */ +@RequiresApi(api = Build.VERSION_CODES.N) +public class AutoTakePictureActivity extends BaseActivity implements View.OnClickListener { + private static final CameraLogger LOG = CameraLogger.create("AutoTakePictureActivity"); + private CameraView camera; + private TencentMap tencentMap; + private TextureMapView tvMapView; + private SystemTTS systemTTS; + private List<Removable> trackLocRemovables/*用户轨迹图标marker*/; + private GPSUtils gpsUtils; + private Location gpsLocation; + private boolean isMapSlide = false; // 地图是否为靠在侧边的小图模式 + private ImageView ivZoomAdd/*zoom放大*/, ivZoomDel/*zoom缩小*/, ivLocation/*定位按钮*/, + ivPicRoadImage/*道路拍摄水平线*/, ivPicVideoImage/*视频拍摄水平线*/; + private ImageView btnSwitch; // 切换地图大小的按钮 + private ViewGroup layerChange; // 切换地图和相机的父控件 + private BitmapDescriptor pileDescriptor = BitmapDescriptorFactory + .fromResource(R.drawable.circle); + private TencentMarkerUtils tencentMarkerUtils; + private List<Removable> removables; // 地图上渲染的网络获取的道路任务 + private List<Removable> removablesLocality; // 地图上渲染的本地道路任务 + private HashMap<String, List<Marker>> removableHashMap; + private List<RoadMatchEntity> roadLinkEntityList, roadMatchEntityList; + private int satelliteCount; // 卫星颗数 + private final long UN_MATCH_TIME_MAX=30*1000; // 未匹配到的时间阈值,最长为30秒 + private static double MATCH_BUFFER_DISTANCE=5e-5; // 匹配途经点用到的buffer距离,此处5米使用简易判断 + private static double MATCH_START_BUFFER_DISTANCE=50e-5; // 匹配起点用到的buffer距离,此处5米使用简易判断 + private final String tmpPicFoldPath = Constant.PICTURE_FOLDER+"/tmp"; + private LocationRecorderDao recorderDao; + private PoiDao poiDao; + private SimpleDateFormat picFormatter = new SimpleDateFormat("yyyyMMdd HHmmss"); + private Button btnClearMatch, btnStopPicture; + private Point lastPositionPoint; // 最近一次的定位,用来过滤距离较近的点位 + private static int UNMATCH_BUFFER_START_BUFFER = 5/*匹配开始后连续未匹配的个数*/, UNMATCH_BUFFER_MIDDLE_BUFFER = 10/*匹配过程中连续未匹配的个数*/; + private static float UNMATCH_GIVE_UP_DISTANCE_BUFFER = 0.2f/*放弃的距离匹配阈值*/, MATCH_CONFIRM_FINISH_BUFFER=0.9f/*完全匹配的距离阈值*/; + private static float UNMATCH_COUNT_BUFFER = UNMATCH_GIVE_UP_DISTANCE_BUFFER/(1-UNMATCH_GIVE_UP_DISTANCE_BUFFER); + private static int BRIGHTNESS=40, FRAMENESS=30; + private Button btnSetting; + private Switch locationSwitch; + private boolean locationEnable; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + SharedPreferences sharedPreferences = getSharedPreferences("pic", Context.MODE_PRIVATE); + BRIGHTNESS = sharedPreferences.getInt("brightness", 40); + FRAMENESS = sharedPreferences.getInt("framness", 30); + + // 设置当前界面亮度为40% + setWindowBrightness(BRIGHTNESS); + super.onCreate(savedInstanceState); + } + + @Override + protected int getLayout() { + EventBus.getDefault().register(this); + return R.layout.activity_auto_take_pictures; + } + + @SuppressLint("SimpleDateFormat") + @Override + protected void initView() { + super.initView(); + if (!EventBus.getDefault().isRegistered(this)) { + EventBus.getDefault().register(this); + } + + this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + layerChange = findViewById(R.id.layer_change); + systemTTS = SystemTTS.getInstance(AutoTakePictureActivity.this); + tvMapView = findViewById(R.id.text_map_view); + tvMapView.setOnClickListener(this); + ivZoomAdd = findViewById(R.id.iv_zoom_add); + ivZoomAdd.setOnClickListener(this); + ivZoomDel = findViewById(R.id.iv_zoom_del); + ivZoomDel.setOnClickListener(this); + ivLocation = findViewById(R.id.iv_location); + ivLocation.setOnClickListener(this); + camera = findViewById(R.id.camera); + CameraOptions cameraOptions = camera.getCameraOptions(); + camera.setPreviewFrameRate(FRAMENESS); + camera.setSnapshotMaxWidth(1920); + camera.setSnapshotMaxHeight(1440); + camera.setOnClickListener(this); + btnSwitch = findViewById(R.id.btn_switch); + btnSwitch.setOnClickListener(this); + ivPicRoadImage = findViewById(R.id.iv_pic_road); + ivPicVideoImage = findViewById(R.id.iv_pic_video); + btnClearMatch = findViewById(R.id.clear_all_match_data); + btnStopPicture = findViewById(R.id.btn_stop_picture); + + //获取地图 + tencentMap = tvMapView.getMap(); + //获取地图UI 设置对象 + UiSettings uiSettings = tencentMap.getUiSettings(); + //设置logo的大小 + uiSettings.setLogoScale(0.7f); + uiSettings.setRotateGesturesEnabled(false);//禁止地图旋转手势. + uiSettings.setTiltGesturesEnabled(false);//禁止倾斜手势. + setLocMarkerStyle(LOCATION_TYPE_LOCATION_ROTATE); + DisplayMetrics dm = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(dm); + FrameLayout.LayoutParams layoutParamsMap = (FrameLayout.LayoutParams) tvMapView.getLayoutParams();//相机的宽高 + layoutParamsMap.width = dm.widthPixels / 3; + layoutParamsMap.height = dm.heightPixels / 3; + tvMapView.setLayoutParams(layoutParamsMap); + + ivPicRoadImage.setVisibility(View.VISIBLE); + ivPicVideoImage.setVisibility(View.GONE); + + trackLocRemovables = new ArrayList<>(); + gpsUtils = new GPSUtils(AutoTakePictureActivity.this); + gpsUtils.setOnClickGPSStatus(new GPSUtils.OnClickGPSStatus() { + @Override + public void onGpsCount(int count) { + satelliteCount = count; + } + }); + + // 清空所有匹配的数据 + btnClearMatch.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (roadMatchEntityList!=null&&!roadMatchEntityList.isEmpty()) { + cancelReciverTask(roadMatchEntityList) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer<PoiEntity>() { + @Override + public void accept(PoiEntity poiEntity) throws Exception { + + } + }, new Consumer<Throwable>() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(AutoTakePictureActivity.this, throwable.getMessage(), Toast.LENGTH_SHORT).show(); + } + }, new Action() { + @Override + public void run() throws Exception { + // 重新刷新地图 + initRoadLine2Map(); + // 执行结束后清空已匹配列表 + roadMatchEntityList.clear(); + } + }); + } + } + }); + + btnStopPicture.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onBackPressed(); + } + }); + + btnSetting = findViewById(R.id.btn_setting); + btnSetting.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CustomDialog.show(AutoTakePictureActivity.this, R.layout.camera_setting, new CustomDialog.OnBindView() { + @Override + public void onBind(CustomDialog dialog, View v) { + EditText startDistance = v.findViewById(R.id.edt_camera_setting_start_distance); + startDistance.setText(MATCH_START_BUFFER_DISTANCE*100000+""); + + EditText midDistance = v.findViewById(R.id.edt_camera_setting_mid_distance); + midDistance.setText(MATCH_BUFFER_DISTANCE*100000+""); + + EditText startCount = v.findViewById(R.id.edt_camera_setting_start_count); + startCount.setText(UNMATCH_BUFFER_START_BUFFER+""); + + EditText midCount = v.findViewById(R.id.edt_camera_setting_mid_count); + midCount.setText(UNMATCH_BUFFER_MIDDLE_BUFFER+""); + + EditText unmatchPecent = v.findViewById(R.id.edt_camera_setting_unmatch_pecent); + unmatchPecent.setText(UNMATCH_GIVE_UP_DISTANCE_BUFFER+""); + + EditText matchPecent = v.findViewById(R.id.edt_camera_setting_match_pecent); + matchPecent.setText(MATCH_CONFIRM_FINISH_BUFFER+""); + + Button btnConfirm = v.findViewById(R.id.btn_camera_setting_confirm); + btnConfirm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!startDistance.getText().toString().isEmpty()) { + MATCH_START_BUFFER_DISTANCE = Double.parseDouble(startDistance.getText().toString())/100000; + } + if (!midDistance.getText().toString().isEmpty()) { + MATCH_BUFFER_DISTANCE = Double.parseDouble(midDistance.getText().toString())/100000; + } + if (!startCount.getText().toString().isEmpty()) { + UNMATCH_BUFFER_START_BUFFER = Integer.parseInt(startCount.getText().toString()); + } + if (!midCount.getText().toString().isEmpty()) { + UNMATCH_BUFFER_MIDDLE_BUFFER = Integer.parseInt(midCount.getText().toString()); + } + if (!unmatchPecent.getText().toString().isEmpty()) { + UNMATCH_GIVE_UP_DISTANCE_BUFFER = Float.parseFloat(unmatchPecent.getText().toString()); + } + if (!matchPecent.getText().toString().isEmpty()) { + MATCH_CONFIRM_FINISH_BUFFER = Float.parseFloat(matchPecent.getText().toString()); + } + Toast.makeText(AutoTakePictureActivity.this, "设置完成", Toast.LENGTH_SHORT).show(); + dialog.doDismiss(); + } + }); + } + }).setFullScreen(true); + } + }); + locationSwitch = findViewById(R.id.location_switch); + locationSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + locationEnable = isChecked; + } + }); + } + + + + @Override + protected void initData() { + super.initData(); + tencentMarkerUtils = new TencentMarkerUtils(); + removables = new ArrayList<>();//存储网络数据的marker数据(线,面,点) + removablesLocality = new ArrayList<>();//存储本地的marker数据(线,面,点) + removableHashMap = new HashMap<>();//key wkt value :存储的数据类型 + roadLinkEntityList = new ArrayList<>(); + roadMatchEntityList = new ArrayList<>(); + recorderDao = PoiDatabase.getInstance(AutoTakePictureActivity.this).getRecorderDao(); + poiDao = PoiDatabase.getInstance(AutoTakePictureActivity.this).getPoiDao(); + + camera.setMode(Mode.PICTURE); + initCameraSize(); + tencentMap.addOnMapLoadedCallback(new TencentMap.OnMapLoadedCallback() { + @Override + public void onMapLoaded() { + initRoadLine2Map(); // 获取道路任务,渲染在地图上 + } + }); + + tencentMap.setOnMapClickListener(new TencentMap.OnMapClickListener() { + @Override + public void onMapClick(LatLng latLng) { + Message msg = handler.obtainMessage(0x105); + msg.obj = obtainTecentLocation(latLng); + handler.sendMessage(msg); + } + }); + camera.addCameraListener(new CameraListener() { + @Override + public void onPictureTaken(@NonNull PictureResult result) { + super.onPictureTaken(result); + // 获取照片数据 + if (result != null && result.getData() != null && result.getData().length > 0) { + super.onPictureTaken(result); + System.out.println("收到拍照按钮jieguo:"+result.getSize().toString()); + // 道路拍照必须为横向拍照 + // TODO 测试时先解除竖向拍摄检查 +// if (Objects.requireNonNull(camera.getPictureSize()).getWidth() < camera.getPictureSize().getHeight()) { +// ToastUtils.Message(AutoTakePictureActivity.this, "不允许竖向拍摄..."); +// systemTTS.playText("不允许竖向拍摄"); +// return; +// } + + File tmpPicFolder = new File(tmpPicFoldPath); + if (!tmpPicFolder.exists()) { + tmpPicFolder.mkdirs(); + } + String currentName = System.currentTimeMillis()+""; + File picFile = new File(tmpPicFolder.getAbsolutePath(), currentName); + synchronized (picFile) { + // 生成点位marker + addTrackMarker(); + result.toFile(picFile, new FileCallback() { + @Override + public void onFileReady(@Nullable File file) { + // 在数据库中记录照片、轨迹位置以及卫星颗数 + LocationRecorder recorder = new LocationRecorder(); + recorder.setTime(Long.parseLong(file.getName())); + recorder.setTencentLocationX(Constant.currentLocation.getLongitude()); + recorder.setTencentLocationY(Constant.currentLocation.getLatitude()); + gpsLocation = gpsUtils.getLocation(); + if (gpsLocation!=null) { + recorder.setGpsLocationX(gpsLocation.getLongitude()); + recorder.setGpsLocationY(gpsLocation.getLatitude()); + } + if (Constant.currentLocation.getBearing() != 0) { + recorder.setBearing(Constant.currentLocation.getBearing()); + } else { + recorder.setBearing(Constant.currentLocation.getDirection()); + } + recorder.setImgFileName(file.getAbsolutePath()); + recorder.setRssi(Constant.currentLocation.getGPSRssi()); + recorder.setSatelliteCount(satelliteCount); + Observable.just(recorder).observeOn(Schedulers.io()) + .filter(roadMatchEntity -> roadMatchEntity!=null) + .subscribe(new Consumer<LocationRecorder>() { + @Override + public void accept(LocationRecorder locationRecorder) throws Exception { + recorderDao.insertLocationRecorder(recorder); + } + }); + } + }); + } + } + } + }); + + SharedPreferences spf = getSharedPreferences("MatchEntity", Context.MODE_PRIVATE); + Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create(); + String matchedData = spf.getString("data", null); + if (matchedData!=null) { + List<RoadMatchEntity> dataList = gson.fromJson(matchedData, new TypeToken<List<RoadMatchEntity>>(){}.getType()); + roadMatchEntityList.addAll(dataList); + } + // 清空缓存数据 + spf.edit().remove("data"); + spf.edit().commit(); + } + + /** + * 根据网络数据和本地数据库数据,更新地图上渲染的道路任务 + * */ + private void initRoadLine2Map() { + if (Constant.USHERED != null) { + // 刷新筛选的本地数据 + tencentMarkerUtils.initLocalMarker(AutoTakePictureActivity.this, tencentMap, removablesLocality, removableHashMap, new TencentMarkerUtils.MarkerInitCallback<PoiEntity>() { + @Override + public void onMarkerInit(Map<String, List<Marker>> removableHashMap, List<Integer> uploadByNet, List<PoiEntity> listData) { + + } + }); + } + if (Constant.currentLocation != null) { //筛选从服务器获取到的数据 + // 注意,此处只获取道路数据 + tencentMarkerUtils.initNetMarkerList(AutoTakePictureActivity.this, Constant.currentLocation, tencentMap, removables, + "4"/*只获取道路数据*/,"0"/*只获取未领取的数据*/, removableHashMap, 50, new TencentMarkerUtils.MarkerInitCallback<JobSearchBean.BodyBean.ListBean>() { + + @Override + public void onMarkerInit(Map<String, List<Marker>> removableHashMap, List<Integer> uploadByNet, + List<JobSearchBean.BodyBean.ListBean> listData) { + // 根据获取到的网络数据,整理数据的起终点数据,方便接下来自动捕捉数据 + roadLinkEntityList.clear(); + if (listData!=null) { + listData.stream().forEach( + it -> { + String geometryStr = Geohash.getInstance().decode(it.getGeo()); + Geometry geometry = GeometryTools.createGeometry(geometryStr); + RoadMatchEntity roadMatchEntity = new RoadMatchEntity(); + roadMatchEntity.setId(it.getId()); + roadMatchEntity.setDataDetail(it); + roadMatchEntity.setGeometry((LineString) geometry); +// roadMatchEntity.setBuffer(geometry.buffer(MATCH_BUFFER_DISTANCE).toString()); + if (geometry instanceof LineString) { + LineString lineString = (LineString) geometry; + // 计算前两个点的坐标角度 + roadMatchEntity.setAngle(Angle.angle(lineString.getCoordinateN(0), lineString.getCoordinateN(0))); + roadMatchEntity.setsPoint(lineString.getStartPoint().toString()); + roadMatchEntity.setePoint(lineString.getEndPoint().toString()); + } + roadLinkEntityList.add(roadMatchEntity); + } + ); + } + } + }); + } else { + ToastUtils.Message(AutoTakePictureActivity.this, "未开启定位服务"); + } + } + + Observer receiveObserver = new Observer<PoiEntity>() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(PoiEntity poiEntity) { + + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + initRoadLine2Map(); + } + }; + + /** + * 开始自动匹配 + * */ + private void startMatchRoadLink(Point currentPoint) { + if (roadLinkEntityList == null/*没有需要匹配的道路数据*/ || currentPoint == null/*没有位置信息*/) { + return; + } + + // 此处开始匹配起点 + List<RoadMatchEntity> matchStartList = roadLinkEntityList.stream().filter(it-> GeometryTools.createGeometry(it.getsPoint()).distance(currentPoint)<MATCH_START_BUFFER_DISTANCE).collect(Collectors.toList()); + // 判断筛选出的数据是否已经在匹配列表中,如果不存在,需要自动领取该任务、记录开始采集时间 + matchStartList = matchStartList.stream().filter( + o -> roadMatchEntityList.stream().noneMatch(roadMatchEntity -> o.getId()==roadMatchEntity.getId()) + ).collect(Collectors.toList()); + if (matchStartList!=null&&!matchStartList.isEmpty()) { + // 存在新匹配到的数据 + matchStartList.stream().forEach( + roadMatchEntity -> { + // 记录开始采集时间 + roadMatchEntity.setStartMatchTime(System.currentTimeMillis()); + // TODO:自动发送请求领取任务 + receiverRoadTask(roadMatchEntity).subscribe(receiveObserver); + }); + // 将匹配到的数据加入到已匹配列表中 + roadMatchEntityList.addAll(matchStartList); + } + + // 尝试用当前位置点匹配已经匹配到的roadLink,如果能匹配到,需要将该点记录,如果无法匹配,则需要评估已匹配的link是否需要被剔除 + if (!roadMatchEntityList.isEmpty()) { + List<RoadMatchEntity> unMatchList = new ArrayList<>(); + Map<Integer, RoadMatchEntity> finishEntityMap = new HashMap<>(); + roadMatchEntityList.stream().forEach( + roadMatchEntity -> { + boolean isMatch=GeometryTools.createGeometry(roadMatchEntity.getGeometry()).distance(currentPoint)<MATCH_BUFFER_DISTANCE; // 当前点位是否可以和link匹配到 + if (isMatch) { // 可以匹配到 + roadMatchEntity.setMatchCount(roadMatchEntity.getMatchCount()+1); + roadMatchEntity.setUnMatchCount(0); // 有匹配的数据,则连续未匹配个数归0 + roadMatchEntity.getMatchPointList().add(new MyCoordinate(currentPoint.getX(), currentPoint.getY())); + // 匹配到终点、或匹配距离超过90% + if (roadMatchEntity.getMatchPointList().size()>=2&&GeometryTools.getLineStringByMyCoordinate(roadMatchEntity.getMatchPointList()).getLength()/roadMatchEntity.getLength()>=MATCH_CONFIRM_FINISH_BUFFER + || currentPoint.distance(GeometryTools.createGeometry(roadMatchEntity.getePoint()))<=MATCH_BUFFER_DISTANCE) { + roadMatchEntity.setEndMathchTime(System.currentTimeMillis()); + finishEntityMap.put(roadMatchEntity.getId(), roadMatchEntity); + } + } else { // 无法匹配 + // 将无法匹配的点位个数记录到对象中 + roadMatchEntity.setUnMatchCount(roadMatchEntity.getUnMatchCount()+1); + roadMatchEntity.setMatchCount(0); + roadMatchEntity.getUnMatchPointList().add(new MyCoordinate(currentPoint.getX(), currentPoint.getY())); + // 判断当前是否存在已匹配的点 + if (roadMatchEntity.getMatchPointList().size()>1) { // 存在匹配的点超过1个,根据长度判断 + if (GeometryTools.getLineStringByMyCoordinate(roadMatchEntity.getMatchPointList()).getLength()/roadMatchEntity.getLength()>UNMATCH_GIVE_UP_DISTANCE_BUFFER) { + // 匹配距离超过20%,根据匹配点和未匹配点个数的对比率判断是否需要放弃 + if (((float)roadMatchEntity.getUnMatchPointList().size())/roadMatchEntity.getMatchPointList().size()>UNMATCH_COUNT_BUFFER) { + unMatchList.add(roadMatchEntity); + } + } else {// 当前匹配距离不超过20%,则必须有连续多个点未匹配才可以放弃该Link + if (roadMatchEntity.getUnMatchCount()>UNMATCH_BUFFER_MIDDLE_BUFFER) { + unMatchList.add(roadMatchEntity); + } + } + } else { // 从未匹配过的数据 + // 未匹配个数超过指定阈值,也认为数据不匹配 + if (roadMatchEntity.getMatchPointList().size()==0) { // 已匹配的个数为0 + if (roadMatchEntity.getUnMatchCount()>UNMATCH_BUFFER_START_BUFFER) { + unMatchList.add(roadMatchEntity); + } + } else if (roadMatchEntity.getMatchPointList().size()==1) { // 已匹配的个数为1 + if (roadMatchEntity.getUnMatchCount()>UNMATCH_BUFFER_MIDDLE_BUFFER) { + unMatchList.add(roadMatchEntity); + } + } + } + } + } + ); + + + if (!finishEntityMap.isEmpty()) { + // 过滤掉已完成的link + for (RoadMatchEntity finishEntity: finishEntityMap.values()) { + roadMatchEntityList.remove(finishEntity); + } + // TODO 完成的entity数据,需要自动生成对应的数据,还需要自动复制对应的照片,通知服务器采集完成 + finishRoadTask(finishEntityMap); + } + + if (!unMatchList.isEmpty()) { + // 过滤需要舍弃的link + for (RoadMatchEntity unMatchEntity: unMatchList) { + roadMatchEntityList.remove(unMatchEntity); + } + cancelReciverTask(unMatchList).subscribe(new Consumer<PoiEntity>() { + @Override + public void accept(PoiEntity poiEntity) throws Exception { + } + }, new Consumer<Throwable>() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(AutoTakePictureActivity.this, throwable.getMessage(), Toast.LENGTH_SHORT).show(); + } + }, new Action() { + @Override + public void run() throws Exception { + // 重新刷新地图 + initRoadLine2Map(); + } + }); + } + } + // 如果当前已经不存在正在采集的数据,则停止记录经纬度和拍照 + if (roadMatchEntityList.isEmpty()) { + stopRecordLocation(); + } else { + startRecordLocation(); + } + } + + /** + * 初始化领取任务的管理栈 + * */ + private Observable<PoiEntity> receiverRoadTask(RoadMatchEntity entity) { + return Observable.just(entity).subscribeOn(Schedulers.io()).observeOn(Schedulers.computation()) + .filter(roadMatchEntity -> roadMatchEntity!=null) + .map(new Function<RoadMatchEntity, PoiEntity>() { + @Override + public PoiEntity apply(RoadMatchEntity roadMatchEntity) throws Exception { + + PoiEntity poiEntity = translateRoadMatchEntity(roadMatchEntity); + // 首先发送领取任务的请求 + OkGoBuilder okGoBuilder = OkGoBuilder + .getInstance() + .time(30) + .Builder(AutoTakePictureActivity.this) + .url(HttpInterface.RECEIVED_ROAD_TASK + "/" + entity.getDataDetail().getId()) + .cls(TaskByNetBean.class) + .params(new HttpParams()) + .token(Constant.ACCESS_TOKEN); + okhttp3.Response response = okGoBuilder.getSynchronization(); + Gson gson = new Gson(); + TaskByNetBean taskByNetBean = gson.fromJson(response.body().string(), TaskByNetBean.class); + if (taskByNetBean.getCode() == 200) { + // 继续保存 + TaskByNetBean.BodyBean listBean = taskByNetBean.getBody(); + if (listBean != null) { + PoiEntity taskIdPoiEntity = PoiDatabase.getInstance(AutoTakePictureActivity.this).getPoiDao() + .getTaskIdPoiEntity(poiEntity.getTaskId()); + if (taskIdPoiEntity == null) {//数据库没有这条数据 + PoiEntity poiListEntity = new PoiEntity(); + poiListEntity.setTaskId(poiEntity.getTaskId()); + poiListEntity.setName(listBean.getName()); + poiListEntity.setMemo(listBean.getMemo()); + poiListEntity.setCreateTime(listBean.getEndDate()); + poiListEntity.setAddress(listBean.getAddress()); + poiListEntity.setType(listBean.getType()); + poiListEntity.setPrecision(String.valueOf(listBean.getPrice())); + poiListEntity.setIsExclusive(listBean.getIsExclusive()); + poiListEntity.setTaskStatus(1); + poiListEntity.setGeoWkt(listBean.getGeo()); + String encodeStr = listBean.getGeo(); + String geo = Geohash.getInstance().decode(encodeStr); + // 生成对应的x和y poiEntity.setX + GeometryTools.obitainPoiEntityXY(geo, poiListEntity); + InsertAndUpdateUtils.getInstance().insertOrUpdate(AutoTakePictureActivity.this, poiListEntity); + } + } + } else if (taskByNetBean.getCode() == 230) { // Token过期 + systemTTS.playText("注意,Token过期,请重新登陆!"); + FlushTokenUtil.flushToken(AutoTakePictureActivity.this); + Message msg = handler.obtainMessage(0x103); + msg.obj = entity; + handler.sendMessageDelayed(msg, 10*1000); // 10秒后重试 + } else { + systemTTS.playText("注意,领取任务失败!"); + ToastUtils.Message(AutoTakePictureActivity.this,taskByNetBean.getMessage()); + Message msg = handler.obtainMessage(0x103); + msg.obj = entity; + handler.sendMessageDelayed(msg, 10*1000); // 10秒后重试 + } + return poiEntity; + } + } + ) + .observeOn(AndroidSchedulers.mainThread()); + } + + /** + * 取消领取任务 + * */ + private Observable cancelReciverTask(List<RoadMatchEntity> cancelMatchLinkList) { + return Observable.fromIterable(cancelMatchLinkList) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.computation()) + .filter(roadMatchEntity -> roadMatchEntity!=null) + .flatMap(roadMatchEntity -> { + PoiEntity poiEntity = poiDao.getTaskIdPoiEntity(roadMatchEntity.getId()); + if (poiEntity!=null) { + return sendCancelRequest(poiEntity); + } else { + return Observable.empty(); + } + }) + .observeOn(AndroidSchedulers.mainThread()); + } + + private Observable<PoiEntity> sendCancelRequest(PoiEntity origin) { + return Observable.just(origin) + .subscribeOn(Schedulers.io()).observeOn(Schedulers.computation()) + .map(new Function<PoiEntity, PoiEntity>() { + @Override + public PoiEntity apply(PoiEntity poiEntity) throws Exception { + if (poiEntity!=null) { + HttpParams httpParams = new HttpParams(); + httpParams.put("taskIds", poiEntity.getTaskId()); + httpParams.put("auditIds", ""); + OkGoBuilder okGoBuilder = OkGoBuilder.getInstance() + .time(30) + .Builder(AutoTakePictureActivity.this) + .url(HttpInterface.UNRECEIVED_POLYGON_TASK) + .cls(UnPolygonTaskBean.class) + .params(httpParams) + .token(Constant.ACCESS_TOKEN); + Response synchronization = okGoBuilder.getSynchronization(); + try { + String bodyString = synchronization.body().string(); + Gson gson = new Gson(); + UnPolygonTaskBean response = gson.fromJson(bodyString, UnPolygonTaskBean.class); + if (response.getCode() == 200) { + PoiDatabase.getInstance(AutoTakePictureActivity.this).getPoiDao().deletePoiEntity(poiEntity); + // 不需要删除照片,自动采集时照片是临时保存在tmp目录下 + } else if (response.getCode() == 230) { + FlushTokenUtil.flushToken(AutoTakePictureActivity.this); + Message msg = handler.obtainMessage(0x106); + msg.obj = poiEntity; + handler.sendMessageDelayed(msg, 10*1000); // 10秒后重试 + } else { + ToastUtils.Message(AutoTakePictureActivity.this, response.getMessage()); + Message msg = handler.obtainMessage(0x106); + msg.obj = poiEntity; + handler.sendMessageDelayed(msg, 10*1000); // 10秒后重试 + } + return poiEntity; + } catch (IOException e) { + throw e; + } + } else { + throw new Exception(""); + } + } + }); + } + + private PoiEntity translateRoadMatchEntity(RoadMatchEntity roadMatchEntity) { + PoiEntity poiListEntity = new PoiEntity(); + JobSearchBean.BodyBean.ListBean listBean = roadMatchEntity.getDataDetail(); + poiListEntity.setTaskId(listBean.getId()); + poiListEntity.setGeoWkt(listBean.getGeo()); + poiListEntity.setName(listBean.getName()); + poiListEntity.setAddress(listBean.getAddress()); + poiListEntity.setTelPhone(listBean.getTelephone()); + poiListEntity.setPrecision(listBean.getPrice() + ""); + poiListEntity.setDist(listBean.getDist() + ""); + poiListEntity.setDescribe(listBean.getMemo()); + poiListEntity.setCreateTime(listBean.getEndDate()); + poiListEntity.setType(listBean.getType()); + poiListEntity.setRecord_way(listBean.getCanReceived()); + poiListEntity.setIsExclusive(listBean.getIsExclusive()); + String beanGeo = listBean.getGeo(); + String geo = Geohash.getInstance().decode(beanGeo); + // 生成对应的x和y poiEntity.setX + GeometryTools.obitainPoiEntityXY(geo, poiListEntity); + return poiListEntity; + } + + /** + * 结束采集,对照片归档 + * */ + private void finishRoadTask(Map<Integer, RoadMatchEntity> finishEntityMap) { + Observable.fromIterable(finishEntityMap.values()) + .subscribeOn(Schedulers.io()).observeOn(Schedulers.computation()) + .filter(roadMatchEntity -> roadMatchEntity!=null) + .map(roadMatchEntity -> { + // 判断是否已领取,未领取则调用领取数据接口 + PoiEntity poiEntity = poiDao.getTaskIdPoiEntity(roadMatchEntity.getId()); + if (poiEntity == null) { + // 数据库中不存在,尝试再次领取 + InsertAndUpdateUtils.getInstance().insertOrUpdate(AutoTakePictureActivity.this, translateRoadMatchEntity(roadMatchEntity)); + // 调用网络领取任务 + receiverRoadTask(roadMatchEntity).subscribe(receiveObserver); + } + + List<LocationRecorder> recorderList = recorderDao.getLocationRecorderByTime(roadMatchEntity.getStartMatchTime(), roadMatchEntity.getEndMathchTime()); + File recorderFolder = new File(Constant.PICTURE_FOLDER+"/"+poiEntity.getId()); + if (!recorderFolder.exists()) { + recorderFolder.mkdirs(); + } + // 编辑paper.txt + // 复制图片文件 + File paperFile = new File(recorderFolder.getAbsolutePath(), "paper.txt"); + for (int i = 0; i < recorderList.size(); i++) { + File originImg = new File(recorderList.get(i).getImgFileName()); + File destFile = new File(recorderFolder.getAbsolutePath()+"/"+i+".jpg"); + if (!destFile.exists()) { + FileUtils.copyFile(originImg.getAbsolutePath(), destFile.getAbsolutePath()); + } + FileUtils.writeFile(paperFile.getAbsolutePath(), recorderList.get(i).toString(picFormatter ,i), true); + } + + return poiEntity; + }) + .doOnNext(poiEntity -> { + // 网络提交数据 + if (poiEntity!=null) { + // 提交数据,更新状态 + roadSaveWork(poiEntity); + /*poiEntity.setTaskStatus(3); + InsertAndUpdateUtils.getInstance().insertOrUpdate(AutoTakePictureActivity.this, poiEntity);*/ + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer<PoiEntity>() { + @Override + public void accept(PoiEntity poiEntity) { + + } + }, new Consumer<Throwable>() { + @Override + public void accept(Throwable throwable) { + // 此处异常可能是服务返回的数据无法解析,但http正常返回了,因此可能为程序问题,不再重复尝试上报 + systemTTS.playText("注意,领取任务失败!"); + ToastUtils.Message(AutoTakePictureActivity.this, throwable.getMessage()); + } + }, new Action() { + @Override + public void run() throws Exception { + // 重新绘制网络任务和本地任务 + initRoadLine2Map(); + } + }); + } + + private void roadSaveWork(PoiEntity poiEntity) throws IOException { + HttpParams httpParams = new HttpParams(); + httpParams.put("taskId", poiEntity.getTaskId()); + httpParams.put("name", poiEntity.getName()); + httpParams.put("address", poiEntity.getAddress()); + httpParams.put("workType", 0); + httpParams.put("memo", poiEntity.getMemo()); + // 增加对应九天平台的参数 + httpParams.put("existence", 0); + httpParams.put("description", ""); + + OkGoBuilder okGoBuilder = OkGoBuilder.getInstance() + .time(30) + .Builder(AutoTakePictureActivity.this) + .url(HttpInterface.ROAD_TASK_SUBMIT) + .cls(RoadSaveBean.class) + .params(httpParams) + .token(Constant.ACCESS_TOKEN); + Response synchronization = okGoBuilder.getSynchronization(); + Gson gson = new Gson(); + RoadSaveBean submitBean = gson.fromJson(synchronization.body().string(), RoadSaveBean.class); + if (submitBean.getCode() == 200) { + Integer body = submitBean.getBody(); + if (body != null && body != 0) { + poiEntity.setBodyId(body); + poiEntity.setTaskStatus(3); + // 更新数据库中状态 + InsertAndUpdateUtils.getInstance().insertOrUpdate(AutoTakePictureActivity.this, poiEntity); + } else { + Message obtain1 = Message.obtain(); + obtain1.what = Constant.NEST_WORD_REGISTER; + obtain1.obj = "道路:" + poiEntity.getName() + " 保存本地失败"; + EventBus.getDefault().post(obtain1); + } + } else if (submitBean.getCode() == 230) { // Token过期 + systemTTS.playText("注意,Token过期,请重新登陆!"); + FlushTokenUtil.flushToken(AutoTakePictureActivity.this); + Message msg = handler.obtainMessage(0x104); + msg.obj = poiEntity; + handler.sendMessageDelayed(msg, 10*1000); // 10秒后重试 + } else { + systemTTS.playText("注意,领取任务失败!"); + ToastUtils.Message(AutoTakePictureActivity.this,submitBean.getMessage()); + Message msg = handler.obtainMessage(0x104); + msg.obj = poiEntity; + handler.sendMessageDelayed(msg, 10*1000); // 10秒后重试 + } + } + + /** + * 开始记录位置信息 + * */ + private void startRecordLocation() { + handler.sendEmptyMessage(0x101); + } + /** + * 停止记录位置信息 + * */ + private void stopRecordLocation() { + if (handler.hasMessages(0x101)) { + handler.removeMessages(0x101); + } + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.btn_switch: +// handler.sendEmptyMessageDelayed(0x102, 2000);// 利用handler延迟发送更改状态信息 + benSwitch(); + break; + case R.id.iv_zoom_add://放大 + CameraUpdate cameraUpdateIn = CameraUpdateFactory.zoomIn(); + tencentMap.animateCamera(cameraUpdateIn); + break; + case R.id.iv_zoom_del://缩小 + CameraUpdate cameraUpdateOut = CameraUpdateFactory.zoomOut(); + tencentMap.animateCamera(cameraUpdateOut); + break; + case R.id.iv_location://定位: + if (Constant.currentLocation != null) { + CameraUpdate cameraSigma = CameraUpdateFactory + .newCameraPosition(new CameraPosition(new LatLng(Constant.currentLocation.getLatitude(), Constant.currentLocation.getLongitude()), //中心点坐标,地图目标经纬度 + 17, //目标缩放级别 + 0, //目标倾斜角[0.0 ~ 45.0] (垂直地图时为0) + 0)); //目标旋转角 0~360° (正北方为0) + tencentMap.animateCamera(cameraSigma); + } + break; + } + } + + private Bitmap getBitMap() { + Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.location_north_fill); + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + int newWidth = 55; + int newHeight = 55; + float widthScale = ((float) newWidth) / width; + float heightScale = ((float) newHeight) / height; + Matrix matrix = new Matrix(); + matrix.postScale(widthScale, heightScale); + bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); + return bitmap; + } + + /*设置定位图标样式*/ + private void setLocMarkerStyle(int type) { + tencentMap.setLocationSource(new MyTecentLocationSource(this)); + tencentMap.setMyLocationEnabled(true); + MyLocationStyle locationStyle = new MyLocationStyle(); + //LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER + locationStyle = locationStyle.myLocationType(type); + //创建图标 + BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(getBitMap()); + locationStyle.icon(bitmapDescriptor); + //设置定位圆形区域的边框宽度; + locationStyle.fillColor(getResources().getColor(android.R.color.transparent)); + locationStyle.strokeWidth(1); + tencentMap.setMyLocationStyle(locationStyle); + } + + public void benSwitch() { + FrameLayout.LayoutParams layoutParamsMap = (FrameLayout.LayoutParams) tvMapView.getLayoutParams();//地图的宽高 + int heightMap = tvMapView.getMeasuredHeight(); + int widthMap = tvMapView.getMeasuredWidth(); + FrameLayout.LayoutParams layoutParamsCamera = (FrameLayout.LayoutParams) camera.getLayoutParams();//相机的宽高 + int heightCamera = camera.getMeasuredHeight(); + int widthCamera = camera.getMeasuredWidth(); + layerChange.removeAllViews(); + if (widthMap > widthCamera) { + layoutParamsCamera.width = widthMap; + layoutParamsCamera.height = heightMap; + layoutParamsMap.height = heightCamera; + layoutParamsMap.width = widthCamera; + camera.setLayoutParams(layoutParamsCamera); + tvMapView.setLayoutParams(layoutParamsMap); + layerChange.addView(camera); + layerChange.addView(tvMapView); + initMapBig(); + } else { + layoutParamsMap.height = heightCamera; + layoutParamsMap.width = widthCamera; + layoutParamsCamera.height = heightMap; + layoutParamsCamera.width = widthMap; + camera.setLayoutParams(layoutParamsCamera); + tvMapView.setLayoutParams(layoutParamsMap); + layerChange.addView(tvMapView); + layerChange.addView(camera); + initMapShort(); + } + } + + //小图 + private void initMapBig() { + isMapSlide = false; + ivZoomAdd.setVisibility(View.GONE); + ivZoomDel.setVisibility(View.GONE); + ivLocation.setVisibility(View.GONE); + setLocMarkerStyle(LOCATION_TYPE_LOCATION_ROTATE); + } + + //大图 + private void initMapShort() { + isMapSlide = true; + ivZoomAdd.setVisibility(View.VISIBLE); + ivZoomDel.setVisibility(View.VISIBLE); + ivLocation.setVisibility(View.VISIBLE); + setLocMarkerStyle(LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER); + } + + @Override + protected void onStart() { + super.onStart(); + tvMapView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + camera.open(); + tvMapView.onResume(); + } + + /** + * 设置相机的拍照size + * */ + private void initCameraSize() { + SizeSelector maxWidth = SizeSelectors.maxWidth(1920); + SizeSelector maxHeight = SizeSelectors.maxHeight(1440); + SizeSelector minWidth = SizeSelectors.minWidth(1440); + SizeSelector minHeight = SizeSelectors.minHeight(1080); + SizeSelector maxDimensions = SizeSelectors.and(maxWidth, maxHeight); // Matches sizes bigger than 1000x2000. + SizeSelector minDimensions = SizeSelectors.and(minWidth, minHeight); // Matches sizes bigger than 1000x2000. + SizeSelector verticalRatio = SizeSelectors.aspectRatio(AspectRatio.of(1080, 1920), 0.2f); // Matches 1:1 sizes. + SizeSelector horzentalRatio = SizeSelectors.aspectRatio(AspectRatio.of(1920, 1080), 0.2f); // Matches 1:1 sizes. + + SizeSelector result = SizeSelectors.or( + SizeSelectors.and(verticalRatio, maxDimensions, minDimensions), // Try to match both constraints + SizeSelectors.and(horzentalRatio, maxDimensions, minDimensions), // Try to match both constraints + verticalRatio, // If none is found, at least try to match the aspect ratio + horzentalRatio, // If none is found, at least try to match the aspect ratio + SizeSelectors.biggest() // If none is found, take the biggest + ); + camera.setPictureSize(result); + camera.setPreviewStreamSize(result); + /** + * app:cameraPictureSizeAspectRatio="1920:1080" + * app:cameraPictureSizeBiggest="true" + * app:cameraPictureSizeMaxArea="3686400" + * app:cameraPictureSizeMaxHeight="1920" + * app:cameraPictureSizeMaxWidth="1920" + * app:cameraPictureSizeMinArea="1166400" + * app:cameraPictureSizeMinHeight="1080" + * app:cameraPictureSizeMinWidth="1080" + * app:cameraPictureSizeSmallest="true" + * */ + } + + @Override + protected void onRestart() { + super.onRestart(); + this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + tvMapView.onRestart(); + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + Message obtain = Message.obtain(); + obtain.what = Constant.PICTURE_VIDEO_WORD; + obtain.obj = true; + EventBus.getDefault().post(obtain); + } + + @Override + protected void onPause() { + super.onPause(); + tvMapView.onPause(); + camera.close(); + } + + @Override + protected void onStop() { + super.onStop(); + tvMapView.onStop(); + } + + + @Override + protected void onDestroy() { + super.onDestroy(); + camera.destroy(); + tvMapView.onDestroy(); + trackLocRemovables.stream().forEach(it->it.remove()); + trackLocRemovables.clear(); + if (EventBus.getDefault().isRegistered(this)) { + EventBus.getDefault().unregister(this); + } + if (roadMatchEntityList!=null&&!roadLinkEntityList.isEmpty()) { + // roadMatchEntity已匹配数据如果存在,缓存 + SharedPreferences.Editor editor = getSharedPreferences("MatchEntity", Context.MODE_PRIVATE).edit(); + Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create(); + editor.putString("data", gson.toJson(roadMatchEntityList)); + editor.commit(); + } + } + + @Override + public void onBackPressed() { + DialogSettings.style = DialogSettings.STYLE.STYLE_IOS; + MessageDialog.show(this, "提示", "退出自动采集模式?", "是", "否").setOnOkButtonClickListener(new OnDialogButtonClickListener() { + @Override + public boolean onClick(BaseDialog baseDialog, View v) { + if (roadMatchEntityList!=null&&!roadMatchEntityList.isEmpty()) { + cancelReciverTask(roadMatchEntityList) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(Object o) { + + } + + @Override + public void onError(Throwable e) { + Toast.makeText(AutoTakePictureActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onComplete() { + // 重新刷新地图 + initRoadLine2Map(); + // 执行结束后清空已匹配列表 + roadMatchEntityList.clear(); + AutoTakePictureActivity.this.finish(); + } + }); + } else { + AutoTakePictureActivity.this.finish(); + } + return false; + } + }); + } + + /** + * 添加轨迹点 + */ + public void addTrackMarker() { + LatLng latLng = null; + if (Constant.currentLocation.getGPSRssi() == 0) { + latLng = new LatLng(Constant.currentLocation.getLatitude(), Constant.currentLocation.getLongitude()); + } else { + if (gpsLocation == null) { + latLng = new LatLng(Constant.currentLocation.getLatitude(), Constant.currentLocation.getLongitude()); + } else { + double[] doubles = Gps.toGCJ02Point(gpsLocation.getLatitude(), gpsLocation.getLongitude()); + latLng = new LatLng(doubles[0],doubles[1]); + } + } + Marker marker = tencentMap.addMarker(new MarkerOptions(latLng) + .icon(pileDescriptor) + .alpha(0.9f) + .flat(true) + .clockwise(false)); + trackLocRemovables.add(marker); + } + + // 设置当前界面亮度 + private void setWindowBrightness(int brightness) { + Window window = getWindow(); + WindowManager.LayoutParams lp = window.getAttributes(); + lp.screenBrightness = brightness / 255.0f; + window.setAttributes(lp); + } + + private TencentLocation obtainTecentLocation(LatLng latLng) { + return new TencentLocation() { + @Override + public String getProvider() { + return "NetWork"; + } + + @Override + public double getLatitude() { + return latLng.getLatitude(); + } + + @Override + public double getLongitude() { + return latLng.getLongitude(); + } + + @Override + public double getAltitude() { + return latLng.getAltitude(); + } + + @Override + public float getAccuracy() { + return 100; + } + + @Override + public String getName() { + return "null"; + } + + @Override + public String getAddress() { + return "null"; + } + + @Override + public String getNation() { + return "null"; + } + + @Override + public String getProvince() { + return "null"; + } + + @Override + public String getCity() { + return "null"; + } + + @Override + public String getDistrict() { + return "null"; + } + + @Override + public String getTown() { + return null; + } + + @Override + public String getVillage() { + return null; + } + + @Override + public String getStreet() { + return null; + } + + @Override + public String getStreetNo() { + return null; + } + + @Override + public Integer getAreaStat() { + return null; + } + + @Override + public List<TencentPoi> getPoiList() { + return null; + } + + @Override + public float getBearing() { + return 0; + } + + @Override + public float getSpeed() { + return 0; + } + + @Override + public long getTime() { + return 0; + } + + @Override + public long getElapsedRealtime() { + return 0; + } + + @Override + public int getGPSRssi() { + return 0; + } + + @Override + public String getIndoorBuildingId() { + return null; + } + + @Override + public String getIndoorBuildingFloor() { + return null; + } + + @Override + public int getIndoorLocationType() { + return 0; + } + + @Override + public double getDirection() { + return 0; + } + + @Override + public String getCityCode() { + return null; + } + + @Override + public String getCityPhoneCode() { + return null; + } + + @Override + public int getCoordinateType() { + return 0; + } + + @Override + public int isMockGps() { + return 0; + } + + @Override + public Bundle getExtra() { + return null; + } + }; + } + + private Handler handler = new Handler(new Handler.Callback() { + @Override + public boolean handleMessage(@NonNull Message msg) { + if (msg.what == 0x101) { + System.out.println("收到拍照按钮请求"); + camera.takePictureSnapshot(); + handler.sendEmptyMessageDelayed(0x101, 1000); + } else if (msg.what == 0x102) { + } else if (msg.what == 0x103) { + RoadMatchEntity roadMatchEntity = (RoadMatchEntity) msg.obj; + receiverRoadTask(roadMatchEntity).subscribe(receiveObserver); + } else if (msg.what == 0x104) { + PoiEntity poiEntity = (PoiEntity) msg.obj; + try { + roadSaveWork(poiEntity); + } catch (Exception e) { + + } + } else if (msg.what == 0x105) { // 测试用例,当用户点击地图时,会自动返回当前点击位置 + if (locationEnable) { + return false; + } + TencentLocation tencentLocation = (TencentLocation) msg.obj; + if (tencentMap != null && !isMapSlide) { + CameraUpdate cameraSigma = CameraUpdateFactory.newCameraPosition(new CameraPosition( + new LatLng(tencentLocation.getLatitude(), tencentLocation.getLongitude()), //中心点坐标,地图目标经纬度 + 17, //目标缩放级别 + 0, //目标倾斜角 + tencentLocation.getBearing())); //目标旋转角 0~360° (正北方为0) + tencentMap.animateCamera(cameraSigma); + } + // 判断当前点位和上一个点位的距离,如果距离过近,忽略该点 + Point currentPoint = (Point) GeometryTools.createGeometry(new LatLng(tencentLocation.getLatitude(), tencentLocation.getLongitude())); + if (lastPositionPoint!=null&&lastPositionPoint.distance(currentPoint)<MATCH_BUFFER_DISTANCE) { // 如果当前点小于最小距离阈值,过滤该数据 + return false; + } + lastPositionPoint = currentPoint; + startMatchRoadLink(currentPoint); + } else if (msg.what == 0x106) { + PoiEntity poiEntity = (PoiEntity) msg.obj; + try { + sendCancelRequest(poiEntity).subscribe(new Observer<PoiEntity>() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(PoiEntity poiEntity) { + + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } catch (Exception e) { + + } + } + return false; + } + }); + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onEventMessageMainThread(Message msg) { + if (msg.what == Constant.EVENT_WHAT_LOCATION_CHANGE) { // 用户位置更新 + if (!locationEnable) { + return; + } + TencentLocation tencentLocation = (TencentLocation) msg.obj; + if (tencentMap != null && !isMapSlide) { + CameraUpdate cameraSigma = CameraUpdateFactory.newCameraPosition(new CameraPosition( + new LatLng(tencentLocation.getLatitude(), tencentLocation.getLongitude()), //中心点坐标,地图目标经纬度 + 17, //目标缩放级别 + 0, //目标倾斜角 + tencentLocation.getBearing())); //目标旋转角 0~360° (正北方为0) + tencentMap.animateCamera(cameraSigma); + } + // 判断当前点位和上一个点位的距离,如果距离过近,忽略该点 + Point currentPoint = (Point) GeometryTools.createGeometry(new LatLng(tencentLocation.getLatitude(), tencentLocation.getLongitude())); + if (lastPositionPoint!=null&&lastPositionPoint.distance(currentPoint)<MATCH_BUFFER_DISTANCE) { // 如果当前点小于最小距离阈值,过滤该数据 + return; + } + lastPositionPoint = currentPoint; + startMatchRoadLink(currentPoint); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/outdoor/activity/MyCoordinate.java b/app/src/main/java/com/navinfo/outdoor/activity/MyCoordinate.java new file mode 100644 index 0000000..ec0e7db --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/activity/MyCoordinate.java @@ -0,0 +1,30 @@ +package com.navinfo.outdoor.activity; + +public class MyCoordinate { + private double x; + private double Y; + + public MyCoordinate() { + } + + public MyCoordinate(double x, double y) { + this.x = x; + Y = y; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return Y; + } + + public void setY(double y) { + Y = y; + } +} diff --git a/app/src/main/java/com/navinfo/outdoor/activity/OkHttpUtils.java b/app/src/main/java/com/navinfo/outdoor/activity/OkHttpUtils.java new file mode 100644 index 0000000..68018cf --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/activity/OkHttpUtils.java @@ -0,0 +1,44 @@ +package com.navinfo.outdoor.activity; + +import com.lzy.okgo.OkGo; +import com.lzy.okgo.adapter.AdapterParam; +import com.lzy.okgo.adapter.Call; +import com.lzy.okgo.adapter.CallAdapter; +import com.lzy.okgo.convert.StringConvert; +import com.lzy.okgo.model.Response; +import com.lzy.okgo.request.GetRequest; +import com.lzy.okgo.request.PostRequest; +import com.lzy.okrx2.adapter.ObservableBody; +import com.lzy.okrx2.adapter.ObservableResponse; + +import java.util.Map; + +import io.reactivex.Flowable; +import io.reactivex.Observable; + +public class OkHttpUtils { + private static OkHttpUtils instance; + + public static OkHttpUtils getInstance() { + if (instance==null) { + instance = new OkHttpUtils(); + } + return instance; + } + + public <T>Observable<Response<T>> obtainOkGet(String url, Object tag, Map<String, String> params) { + GetRequest<T> getRequest = OkGo.getInstance().<T>get(url).tag(tag); + if (params!=null&&!params.isEmpty()) { + getRequest.params(params, true); + } + return getRequest.adapt(new ObservableResponse<T>()); + } + + public <T>Observable<Response<T>> obtainOkPost(String url, Object tag, Map<String, String> params) { + PostRequest<T> postRequest = OkGo.getInstance().<T>post(url).tag(tag); + if (params!=null&&!params.isEmpty()) { + postRequest.params(params, true); + } + return postRequest.adapt(new ObservableResponse<T>()); + } +} diff --git a/app/src/main/java/com/navinfo/outdoor/activity/PhotographActivity.java b/app/src/main/java/com/navinfo/outdoor/activity/PhotographActivity.java index f942c05..ba7f722 100644 --- a/app/src/main/java/com/navinfo/outdoor/activity/PhotographActivity.java +++ b/app/src/main/java/com/navinfo/outdoor/activity/PhotographActivity.java @@ -35,7 +35,7 @@ import com.otaliastudios.cameraview.CameraView; import com.otaliastudios.cameraview.FileCallback; import com.otaliastudios.cameraview.PictureResult; import com.otaliastudios.cameraview.controls.Mode; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import com.wanghong.webpnative.WebPNative; import org.greenrobot.eventbus.EventBus; diff --git a/app/src/main/java/com/navinfo/outdoor/activity/PictureActivity.java b/app/src/main/java/com/navinfo/outdoor/activity/PictureActivity.java index e5e94a5..2eb182d 100644 --- a/app/src/main/java/com/navinfo/outdoor/activity/PictureActivity.java +++ b/app/src/main/java/com/navinfo/outdoor/activity/PictureActivity.java @@ -61,7 +61,7 @@ import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions; import com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle; import com.tencent.tencentmap.mapsdk.maps.model.Polyline; import com.tencent.tencentmap.mapsdk.maps.model.PolylineOptions; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; diff --git a/app/src/main/java/com/navinfo/outdoor/activity/PicturesActivity.java b/app/src/main/java/com/navinfo/outdoor/activity/PicturesActivity.java index 692285c..134694c 100644 --- a/app/src/main/java/com/navinfo/outdoor/activity/PicturesActivity.java +++ b/app/src/main/java/com/navinfo/outdoor/activity/PicturesActivity.java @@ -17,6 +17,8 @@ import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -52,6 +54,7 @@ import com.navinfo.outdoor.util.TimestampUtil; import com.navinfo.outdoor.util.ToastUtils; import com.otaliastudios.cameraview.CameraListener; import com.otaliastudios.cameraview.CameraLogger; +import com.otaliastudios.cameraview.CameraOptions; import com.otaliastudios.cameraview.CameraView; import com.otaliastudios.cameraview.FileCallback; import com.otaliastudios.cameraview.PictureResult; @@ -78,9 +81,9 @@ import com.tencent.tencentmap.mapsdk.maps.model.Polyline; import com.tencent.tencentmap.mapsdk.maps.model.PolylineOptions; import com.umeng.commonsdk.internal.crash.UMCrashManager; import com.umeng.umcrash.UMCrash; -import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.LineString; -import com.vividsolutions.jts.geom.MultiLineString; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.MultiLineString; import com.wanghong.webpnative.WebPNative; import org.greenrobot.eventbus.EventBus; @@ -139,6 +142,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen private int videoIndex = -1; private int convertIndex = 0; private int startVideoIndex = -1; + private static int BRIGHTNESS=40, FRAMENESS=30; @SuppressLint("SimpleDateFormat") private SimpleDateFormat formatter; private Handler handler = new Handler(new Handler.Callback() { @@ -146,7 +150,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen public boolean handleMessage(@NonNull Message msg) { if (msg.what == 0x101) { System.out.println("收到拍照按钮请求"); - camera.takePicture(); + camera.takePictureSnapshot(); } else if (msg.what == 0x102) { if (imageView != null) { imageView.setEnabled(true); @@ -165,6 +169,17 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen }); private boolean booleanExtra; + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + SharedPreferences sharedPreferences = getSharedPreferences("pic", Context.MODE_PRIVATE); + BRIGHTNESS = sharedPreferences.getInt("brightness", 40); + FRAMENESS = sharedPreferences.getInt("framness", 30); + + // 设置当前界面亮度为40% + setWindowBrightness(BRIGHTNESS); + super.onCreate(savedInstanceState); + } + @Override protected int getLayout() { EventBus.getDefault().register(this); @@ -202,7 +217,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen tvMapView.setOnClickListener(this); ivPicRoadImage = findViewById(R.id.iv_pic_road); ivPicVideoImage = findViewById(R.id.iv_pic_video); - Button btnSwitch = findViewById(R.id.btn_switch); + ImageView btnSwitch = findViewById(R.id.btn_switch); btnSwitch.setOnClickListener(this); gpsUtils = new GPSUtils(PicturesActivity.this); gpsUtils.setOnClickGPSStatus(new GPSUtils.OnClickGPSStatus() { @@ -266,6 +281,10 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen ivLocation = findViewById(R.id.iv_location); ivLocation.setOnClickListener(this); camera = findViewById(R.id.camera); + CameraOptions cameraOptions = camera.getCameraOptions(); + camera.setPreviewFrameRate(FRAMENESS); + camera.setSnapshotMaxWidth(1920); + camera.setSnapshotMaxHeight(1440); camera.setOnClickListener(this); tvTitle = findViewById(R.id.tv_title); tvConvert = findViewById(R.id.tv_convert); @@ -372,7 +391,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen @Override public void run() { if (radioPicture == 1) { - camera.takePicture(); + camera.takePictureSnapshot(); } else { Message message = new Message(); message.what = 0x101; @@ -380,6 +399,14 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen } } }; + + Button btnSetting = findViewById(R.id.btn_setting); + btnSetting.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + } + }); } class Jpg2WebpRunnable implements Runnable { @@ -401,19 +428,20 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen @Override public void run() { if (file.exists() && file != null) { - if (initWeb(file, count, isBoolean, index)) { - if (PicturesActivity.this != null&&handler != null) { - if (radioPicture == 1) { - Message message = new Message(); - message.what = 0x103; - handler.sendMessage(message); - } else { - Message message = new Message(); - message.what = 0x104; - message.arg1 = index; - handler.sendMessage(message); - } +// if (initWeb(file, count, isBoolean, index)) { + initMarkerPaper(index); + if (PicturesActivity.this != null&&handler != null) { + if (radioPicture == 1) { + Message message = new Message(); + message.what = 0x103; + handler.sendMessage(message); + } else { + Message message = new Message(); + message.what = 0x104; + message.arg1 = index; + handler.sendMessage(message); } + } // runOnUiThread(new Runnable() { // @SuppressLint("SetTextI18n") // @Override @@ -421,7 +449,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen // // } // }); - } +// } } else { isBack = false; if (isOration) { @@ -726,14 +754,14 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen * 设置相机的拍照size * */ private void initCameraSize() { - SizeSelector maxWidth = SizeSelectors.maxWidth(1280); - SizeSelector maxHeight = SizeSelectors.maxHeight(1280); - SizeSelector minWidth = SizeSelectors.minWidth(720); - SizeSelector minHeight = SizeSelectors.minHeight(720); + SizeSelector maxWidth = SizeSelectors.maxWidth(1920); + SizeSelector maxHeight = SizeSelectors.maxHeight(1440); + SizeSelector minWidth = SizeSelectors.minWidth(1440); + SizeSelector minHeight = SizeSelectors.minHeight(1080); SizeSelector maxDimensions = SizeSelectors.and(maxWidth, maxHeight); // Matches sizes bigger than 1000x2000. SizeSelector minDimensions = SizeSelectors.and(minWidth, minHeight); // Matches sizes bigger than 1000x2000. - SizeSelector verticalRatio = SizeSelectors.aspectRatio(AspectRatio.of(720, 1280), 0.2f); // Matches 1:1 sizes. - SizeSelector horzentalRatio = SizeSelectors.aspectRatio(AspectRatio.of(1280, 720), 0.2f); // Matches 1:1 sizes. + SizeSelector verticalRatio = SizeSelectors.aspectRatio(AspectRatio.of(1080, 1920), 0.2f); // Matches 1:1 sizes. + SizeSelector horzentalRatio = SizeSelectors.aspectRatio(AspectRatio.of(1920, 1080), 0.2f); // Matches 1:1 sizes. SizeSelector result = SizeSelectors.or( SizeSelectors.and(verticalRatio, maxDimensions, minDimensions), // Try to match both constraints @@ -1026,7 +1054,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen @Override public void run() { if (radioPicture == 1) { - camera.takePicture(); + camera.takePictureSnapshot(); } else { Message message = new Message(); message.what = 0x101; @@ -1056,4 +1084,12 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen timerTask = null; } } + + // 设置当前界面亮度 + private void setWindowBrightness(int brightness) { + Window window = getWindow(); + WindowManager.LayoutParams lp = window.getAttributes(); + lp.screenBrightness = brightness / 255.0f; + window.setAttributes(lp); + } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/outdoor/api/Constant.java b/app/src/main/java/com/navinfo/outdoor/api/Constant.java index 954760d..a17634c 100644 --- a/app/src/main/java/com/navinfo/outdoor/api/Constant.java +++ b/app/src/main/java/com/navinfo/outdoor/api/Constant.java @@ -224,4 +224,20 @@ public class Constant { public static String REGION_YUE_PHONE = "892781071"; public static String REGION_YUN_NAME = "云贵-地图寻宝群"; public static String REGION_YUN_PHONE = "284447253"; + + /** + * 获取信号强度描述文字 + * */ + public static String getRssiDesStr(int rssi) { + if (rssi == 0) { + return "无信号"; + } else if (rssi == 1) { + return "弱"; + } else if (rssi == 2) { + return "中"; + } else if (rssi == 3) { + return "强"; + } + return "无信号"; // 默认为无信号 + } } diff --git a/app/src/main/java/com/navinfo/outdoor/api/UserApplication.java b/app/src/main/java/com/navinfo/outdoor/api/UserApplication.java index 572a271..ff6e505 100644 --- a/app/src/main/java/com/navinfo/outdoor/api/UserApplication.java +++ b/app/src/main/java/com/navinfo/outdoor/api/UserApplication.java @@ -161,7 +161,7 @@ public class UserApplication extends Application { //设置公共请求头 .addCommonHeaders(headers) //全局统一超时重连次数,默认为三次,那么最差的情况会请求4次(一次原始请求,三次重连请求),不需要可以设置为0; - .setRetryCount(0); + .setRetryCount(3); StrictMode.VmPolicy.Builder picBuilder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(picBuilder.build()); picBuilder.detectFileUriExposure(); diff --git a/app/src/main/java/com/navinfo/outdoor/bean/JobSearchBean.java b/app/src/main/java/com/navinfo/outdoor/bean/JobSearchBean.java index 78ed989..89cc0e0 100644 --- a/app/src/main/java/com/navinfo/outdoor/bean/JobSearchBean.java +++ b/app/src/main/java/com/navinfo/outdoor/bean/JobSearchBean.java @@ -88,7 +88,7 @@ public class JobSearchBean implements Serializable { this.list = list; } - public static class ListBean { + public static class ListBean implements Serializable{ /** * id : 8992 * geo : dy3feM6SkaeY3Q3FrUcdfMyvvsAqu2MktMG2JtDX/+gDQ7IT9aNcPn2v1Rvi diff --git a/app/src/main/java/com/navinfo/outdoor/bean/LocationRecorder.java b/app/src/main/java/com/navinfo/outdoor/bean/LocationRecorder.java new file mode 100644 index 0000000..c3b1276 --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/bean/LocationRecorder.java @@ -0,0 +1,135 @@ +package com.navinfo.outdoor.bean; + +import android.location.Location; + +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +import com.navinfo.outdoor.api.Constant; +import com.tencent.map.geolocation.TencentLocation; + +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Entity(tableName = "LocationRecorder") +public class LocationRecorder implements Serializable { + @PrimaryKey + private long time; // 采集时间 + private double tencentLocationX; + private double tencentLocationY; + private double gpsLocationX; + private double gpsLocationY; + private int rssi; // 信号强度 + private double bearing; // 角度方向 + private int satelliteCount; // 卫星颗数 + private String imgFileName; // 照片名称 + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public double getTencentLocationX() { + return tencentLocationX; + } + + public void setTencentLocationX(double tencentLocationX) { + this.tencentLocationX = tencentLocationX; + } + + public double getTencentLocationY() { + return tencentLocationY; + } + + public void setTencentLocationY(double tencentLocationY) { + this.tencentLocationY = tencentLocationY; + } + + public double getGpsLocationX() { + return gpsLocationX; + } + + public void setGpsLocationX(double gpsLocationX) { + this.gpsLocationX = gpsLocationX; + } + + public double getGpsLocationY() { + return gpsLocationY; + } + + public void setGpsLocationY(double gpsLocationY) { + this.gpsLocationY = gpsLocationY; + } + + public int getRssi() { + return rssi; + } + + public void setRssi(int rssi) { + this.rssi = rssi; + } + + public double getBearing() { + return bearing; + } + + public void setBearing(double bearing) { + this.bearing = bearing; + } + + public int getSatelliteCount() { + return satelliteCount; + } + + public void setSatelliteCount(int satelliteCount) { + this.satelliteCount = satelliteCount; + } + + public String getImgFileName() { + return imgFileName; + } + + public void setImgFileName(String imgFileName) { + this.imgFileName = imgFileName; + } + + @Override + public String toString() { + return "LocationRecorder{" + + "time=" + time + + ", tencentLocationX=" + tencentLocationX + + ", tencentLocationY=" + tencentLocationY + + ", gpsLocationX=" + gpsLocationX + + ", gpsLocationY=" + gpsLocationY + + ", rssi=" + rssi + + ", bearing=" + bearing + + ", satelliteCount=" + satelliteCount + + ", imgFileName='" + imgFileName + '\'' + + '}'; + } + public String toString(SimpleDateFormat dateFormat, int index) { + return new StringBuilder() + .append(dateFormat.format(new Date(time))) + .append(",") + .append(index) + .append(",") + .append(tencentLocationY) + .append(",") + .append(tencentLocationX) + .append(",") + .append(bearing) + .append(Constant.getRssiDesStr(rssi)) + .append(",") + .append(satelliteCount) + .append(",") + .append(gpsLocationY) + .append(",") + .append(gpsLocationX) + .append("\r\n") + .toString(); + } +} diff --git a/app/src/main/java/com/navinfo/outdoor/bean/RoadMatchEntity.java b/app/src/main/java/com/navinfo/outdoor/bean/RoadMatchEntity.java new file mode 100644 index 0000000..ed0b594 --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/bean/RoadMatchEntity.java @@ -0,0 +1,184 @@ +package com.navinfo.outdoor.bean; + +import androidx.room.ColumnInfo; + +import com.navinfo.outdoor.activity.MyCoordinate; +import com.tencent.tencentmap.mapsdk.maps.model.LatLng; + +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Envelope; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 道路匹配的封装类 + * */ +public class RoadMatchEntity implements Serializable { + private int id; // 唯一id + private JobSearchBean.BodyBean.ListBean dataDetail; // 具体的内容信息 + private double angle=0; // 起点匹配方向 + private double length=0; //geometry的长度 + private String geometry; // 数据的geometry,此处应该为lineString +// private String buffer; // line外扩的buffer,用来判断行驶过程中是否可以与当前geometry匹配 + private String sPoint; // 起点 + private String ePoint; // 起点 + private long startMatchTime; // 开始匹配的时间 + private long endMathchTime; // 结束匹配的时间 + private double lastDistance=0; // 上次匹配到的距离 + private int matchCount; // <连续>匹配到的点位个数 + private int unMatchCount; // <连续>未匹配到的点位个数 + private List<MyCoordinate> matchPointList = new ArrayList<>(); // 已匹配的点位列表 + private List<MyCoordinate> unMatchPointList = new ArrayList<>(); // 未匹配的点位列表 + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public JobSearchBean.BodyBean.ListBean getDataDetail() { + return dataDetail; + } + + public void setDataDetail(JobSearchBean.BodyBean.ListBean dataDetail) { + this.dataDetail = dataDetail; + } + + public double getAngle() { + return angle; + } + + public void setAngle(double angle) { + this.angle = angle; + } + + public String getGeometry() { + return geometry; + } + + public void setGeometry(LineString geometry) { + this.geometry = geometry.toString(); + this.length = geometry.getLength(); + } + + public double getLength() { + return length; + } + +// public String getBuffer() { +// return buffer; +// } +// +// public void setBuffer(String buffer) { +// this.buffer = buffer; +// } + + public String getsPoint() { + return sPoint; + } + + public void setsPoint(String sPoint) { + this.sPoint = sPoint; + } + + public String getePoint() { + return ePoint; + } + + public void setePoint(String ePoint) { + this.ePoint = ePoint; + } + + public long getStartMatchTime() { + return startMatchTime; + } + + public void setStartMatchTime(long startMatchTime) { + this.startMatchTime = startMatchTime; + } + + public long getEndMathchTime() { + return endMathchTime; + } + + public void setEndMathchTime(long endMathchTime) { + this.endMathchTime = endMathchTime; + } + + public double getLastDistance() { + return lastDistance; + } + + public void setLastDistance(double lastDistance) { + this.lastDistance = lastDistance; + } + + public int getMatchCount() { + return matchCount; + } + + public void setMatchCount(int matchCount) { + this.matchCount = matchCount; + } + + public int getUnMatchCount() { + return unMatchCount; + } + + public void setUnMatchCount(int unMatchCount) { + this.unMatchCount = unMatchCount; + } + + public List<MyCoordinate> getMatchPointList() { + return matchPointList; + } + + public void setMatchPointList(List<MyCoordinate> matchPointList) { + this.matchPointList = matchPointList; + } + + public List<MyCoordinate> getUnMatchPointList() { + return unMatchPointList; + } + + public void setUnMatchPointList(List<MyCoordinate> unMatchPointList) { + this.unMatchPointList = unMatchPointList; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RoadMatchEntity that = (RoadMatchEntity) o; + + if (id != that.id) return false; + return true; +// if (angle != that.angle) return false; +// if (dataDetail != null ? !dataDetail.equals(that.dataDetail) : that.dataDetail != null) +// return false; +// if (geometry != null ? !geometry.equals(that.geometry) : that.geometry != null) +// return false; +// if (buffer != null ? !buffer.equals(that.buffer) : that.buffer != null) return false; +// if (sPoint != null ? !sPoint.equals(that.sPoint) : that.sPoint != null) return false; +// return ePoint != null ? ePoint.equals(that.ePoint) : that.ePoint == null; + } + + @Override + public int hashCode() { + int result = id; + result = 31 * result + (dataDetail != null ? dataDetail.hashCode() : 0); + result = 31 * result + (geometry != null ? geometry.hashCode() : 0); + result = 31 * result + (sPoint != null ? sPoint.hashCode() : 0); + result = 31 * result + (ePoint != null ? ePoint.hashCode() : 0); + return result; + } +} diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/ChargingStationFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/ChargingStationFragment.java index a6adb47..ea61a00 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/ChargingStationFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/ChargingStationFragment.java @@ -84,7 +84,7 @@ import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; import com.tencent.tencentmap.mapsdk.maps.model.Marker; import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/FilterFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/FilterFragment.java index eafc1db..b4242ef 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/FilterFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/FilterFragment.java @@ -45,7 +45,7 @@ import com.navinfo.outdoor.util.GeometryTools; import com.navinfo.outdoor.util.TimestampUtil; import com.navinfo.outdoor.util.ToastUtils; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/GatherGetFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/GatherGetFragment.java index d6ff4af..2544ed1 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/GatherGetFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/GatherGetFragment.java @@ -44,7 +44,7 @@ import com.navinfo.outdoor.util.TimestampUtil; import com.navinfo.outdoor.util.ToastUtils; import com.tencent.lbssearch.httpresponse.Poi; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import org.greenrobot.eventbus.EventBus; diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/OtherFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/OtherFragment.java index d0d166e..1998b28 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/OtherFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/OtherFragment.java @@ -69,7 +69,7 @@ import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; import com.tencent.tencentmap.mapsdk.maps.model.Marker; import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/PhotoFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/PhotoFragment.java index 7879099..88b0f47 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/PhotoFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/PhotoFragment.java @@ -37,6 +37,9 @@ import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; + +import io.reactivex.Observable; /** * 图片-fragment @@ -107,33 +110,31 @@ public class PhotoFragment extends BaseFragment implements View.OnClickListener List<File> fileArrayList = new ArrayList<>(); if (fileListByUUID.size() >= 2) { for (int i = 0; i < fileListByUUID.size(); i++) { - if (!fileListByUUID.get(i).getPath().contains("paper.txt")) { + if (!fileListByUUID.get(i).getPath().endsWith("paper.txt")) { fileArrayList.add(fileListByUUID.get(i)); } else { fileTxt = fileListByUUID.get(i); } } } - Collections.sort(fileArrayList, new Comparator<File>() { + + fileArrayList = fileArrayList.stream().sorted(new Comparator<File>() { @Override public int compare(File o1, File o2) { - String[] split = o1.getName().split(".webp"); - int i = Integer.parseInt(split[0]); - String[] split2 = o2.getName().split(".webp"); - int i2 = Integer.parseInt(split2[0]); - if (i > i2) { + String o1Name = o1.getName().replace(".webp","").replace(".jpg", "").replace(".png", "").replace("jpeg", ""); + String o2Name = o2.getName().replace(".webp","").replace(".jpg", "").replace(".png", "").replace("jpeg", ""); + if (Integer.parseInt(o1Name)>Integer.parseInt(o2Name)) { return 1; } else { return -1; } } - }); + }).collect(Collectors.toList()); + if (fileArrayList.size() > 0) { for (int i = 0; i < fileArrayList.size(); i++) { - if (fileArrayList.get(i).getPath().contains(".webp") && !fileArrayList.get(i).getPath().contains("paper.txt")) { - if (fileArrayList.get(i).exists()) { - fileBeans.add(new FileBean(fileArrayList.get(i), false)); - } + if (fileArrayList.get(i).exists()) { + fileBeans.add(new FileBean(fileArrayList.get(i), false)); } } } diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/PoiFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/PoiFragment.java index d6d5694..4759e34 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/PoiFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/PoiFragment.java @@ -77,7 +77,7 @@ import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; import com.tencent.tencentmap.mapsdk.maps.model.Marker; import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/PoiVideoFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/PoiVideoFragment.java index 78b4ab2..d423124 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/PoiVideoFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/PoiVideoFragment.java @@ -66,7 +66,7 @@ import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; import com.tencent.tencentmap.mapsdk.maps.model.Marker; import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java index e5c3743..bd952db 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java @@ -34,10 +34,12 @@ import com.hjq.permissions.XXPermissions; import com.kongzue.dialog.interfaces.OnDialogButtonClickListener; import com.kongzue.dialog.util.BaseDialog; import com.kongzue.dialog.util.DialogSettings; +import com.kongzue.dialog.v3.CustomDialog; import com.kongzue.dialog.v3.MessageDialog; import com.kongzue.dialog.v3.WaitDialog; import com.lzy.okgo.model.HttpParams; import com.navinfo.outdoor.R; +import com.navinfo.outdoor.activity.AutoTakePictureActivity; import com.navinfo.outdoor.activity.FragmentManagement; import com.navinfo.outdoor.activity.PicturesActivity; import com.navinfo.outdoor.api.Constant; @@ -68,7 +70,7 @@ import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; import com.tencent.tencentmap.mapsdk.maps.model.Marker; import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -374,12 +376,13 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList if (describe != null && !describe.equals("")) { etDesc.setText(describe); } - String photoList = showPoiEntity.getPhoto();//存儲在數據庫中的數據 - if (!StringUtils.isEmpty(photoList)) { +// String photoList = showPoiEntity.getPhoto();//存儲在數據庫中的數據 +// if (!StringUtils.isEmpty(photoList)) { boolean isImageLoad = false; List<File> fileListByUUID = AWMp4ParserHelper.getInstance().getFileListByUUID(showPoiEntity.getId()); for (int i = 0; i < fileListByUUID.size(); i++) { - if (fileListByUUID.get(i).getPath().contains(".webp") && !fileListByUUID.get(i).getPath().contains("paper.txt")) { + if (fileListByUUID.get(i).getPath().endsWith(".webp") || fileListByUUID.get(i).getPath().endsWith(".png") + || fileListByUUID.get(i).getPath().endsWith(".jpg")|| fileListByUUID.get(i).getPath().endsWith(".jpeg")) { if (fileListByUUID.get(i).exists() && !isImageLoad) { // 使用glide加载视频的第一帧 Glide.with(Objects.requireNonNull(getActivity())).load(fileListByUUID.get(i)).into(ivRoadPicture); @@ -388,7 +391,7 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList } } fmRoadPic.setTag(fileListByUUID); - } +// } if (showPoiEntity.getTaskStatus() == 3) { disables(); } @@ -408,7 +411,8 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList if (!StringUtils.isEmpty(photo)) { File videoFile = new File(photo); videoFileList.add(new File(photo)); - if (videoFile.getPath().contains(".webp") && !videoFile.getPath().contains("paper.txt")) { + if (videoFile.getName().endsWith(".webp") || videoFile.getName().endsWith(".png") + || videoFile.getName().endsWith(".jpg")|| videoFile.getName().endsWith(".jpeg")) { if (videoFile.exists() && !isImageLoad) { // 使用glide加载视频的第一帧 AWMp4ParserHelper.getInstance().loadFirstWithGlide(getActivity(), Uri.fromFile(videoFile).toString(), ivRoadPicture, 500); @@ -456,7 +460,8 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList boolean isImageLoad = false; for (int i = 0; i < fileListByUUID.size(); i++) { File videoFile = fileListByUUID.get(i); - if (videoFile.getPath().contains(".webp") && !videoFile.getPath().contains("paper.txt")) { + if (videoFile.getName().endsWith(".webp") || videoFile.getName().endsWith(".png") + || videoFile.getName().endsWith(".jpg")|| videoFile.getName().endsWith(".jpeg")) { if (videoFile.exists() && !isImageLoad) { // 使用glide加载视频的第一帧 AWMp4ParserHelper.getInstance().loadFirstWithGlide(getActivity(), Uri.fromFile(videoFile).toString(), ivRoadPicture, 500); @@ -507,19 +512,54 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList return; } } - Intent intent = new Intent(getContext(), PicturesActivity.class); - File finalFile = AWMp4ParserHelper.getInstance().obtainWebpFilePath(new File(Constant.PICTURE_FOLDER, showPoiEntity.getId()).getAbsolutePath()); - intent.putExtra(Constant.INTENT_JPG_PATH, finalFile.getAbsolutePath()); - intent.putExtra(Constant.INTENT_TYPE, showPoiEntity.getType()); - intent.putExtra(Constant.INTENT_GEO_WKT, showPoiEntity.getGeoWkt()); - intent.putExtra(Constant.INTENT_DETAIL, showPoiEntity.getDetail()); - int gpsRssi = Constant.currentLocation.getGPSRssi(); - if (gpsRssi == 0) { - intent.putExtra(Constant.INTENT_BOOLEAN, false); - } else { - intent.putExtra(Constant.INTENT_BOOLEAN, true); - } - startActivityForResult(intent, 0x101); + + // 设置亮度和摄像机刷新率 + CustomDialog.show((AppCompatActivity) getActivity(), R.layout.camera_setting_pre, new CustomDialog.OnBindView() { + @Override + public void onBind(CustomDialog dialog, View v) { + SharedPreferences sharedPreferences = getActivity().getSharedPreferences("pic", Context.MODE_PRIVATE); + int brightness = sharedPreferences.getInt("brightness", 40); + EditText edtBrightness = v.findViewById(R.id.edt_camera_setting_brightness); + edtBrightness.setText(brightness+""); + + int framness = sharedPreferences.getInt("framness", 30); + EditText edtFramness = v.findViewById(R.id.edt_camera_setting_framness); + edtFramness.setText(framness+""); + + Button btnConfirm = v.findViewById(R.id.btn_camera_setting_confirm); + btnConfirm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + SharedPreferences.Editor editor = getActivity().getSharedPreferences("pic", Context.MODE_PRIVATE).edit(); + if (!edtBrightness.getText().toString().isEmpty()) { + int b = Integer.parseInt(edtBrightness.getText().toString()); + editor.putInt("brightness", b); + } + if (!edtFramness.getText().toString().isEmpty()) { + int f = Integer.parseInt(edtFramness.getText().toString()); + editor.putInt("framness", f); + } + editor.commit(); + Toast.makeText(getActivity(), "设置完成", Toast.LENGTH_SHORT).show(); + + Intent intent = new Intent(getContext(), PicturesActivity.class); + File finalFile = AWMp4ParserHelper.getInstance().obtainWebpFilePath(new File(Constant.PICTURE_FOLDER, showPoiEntity.getId()).getAbsolutePath()); + intent.putExtra(Constant.INTENT_JPG_PATH, finalFile.getAbsolutePath()); + intent.putExtra(Constant.INTENT_TYPE, showPoiEntity.getType()); + intent.putExtra(Constant.INTENT_GEO_WKT, showPoiEntity.getGeoWkt()); + intent.putExtra(Constant.INTENT_DETAIL, showPoiEntity.getDetail()); + int gpsRssi = Constant.currentLocation.getGPSRssi(); + if (gpsRssi == 0) { + intent.putExtra(Constant.INTENT_BOOLEAN, false); + } else { + intent.putExtra(Constant.INTENT_BOOLEAN, true); + } + startActivityForResult(intent, 0x101); + dialog.doDismiss(); + } + }); + } + }).setFullScreen(true); break; case R.id.road_upload: roadBuilder.append(TimestampUtil.time()).append(",").append("点击了上传的按钮 ,"); diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/TreasureFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/TreasureFragment.java index 973a73c..908b2da 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/TreasureFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/TreasureFragment.java @@ -10,6 +10,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Matrix; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -19,13 +20,17 @@ import android.view.Gravity; import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; +import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.widget.NestedScrollView; @@ -44,12 +49,14 @@ import com.jcodecraeer.xrecyclerview.XRecyclerView; import com.kongzue.dialog.interfaces.OnDialogButtonClickListener; import com.kongzue.dialog.util.BaseDialog; import com.kongzue.dialog.util.DialogSettings; +import com.kongzue.dialog.v3.CustomDialog; import com.kongzue.dialog.v3.MessageDialog; import com.kongzue.dialog.v3.ShareDialog; import com.lzy.okgo.OkGo; import com.lzy.okgo.model.HttpParams; import com.lzy.okgo.model.Progress; import com.navinfo.outdoor.R; +import com.navinfo.outdoor.activity.AutoTakePictureActivity; import com.navinfo.outdoor.activity.FragmentManagement; import com.navinfo.outdoor.activity.HomeActivity; import com.navinfo.outdoor.activity.WebActivity; @@ -76,6 +83,7 @@ import com.navinfo.outdoor.util.GeometryTools; import com.navinfo.outdoor.util.MapManager; import com.navinfo.outdoor.util.MyTecentLocationSource; import com.navinfo.outdoor.util.NetWorkUtils; +import com.navinfo.outdoor.util.TencentMarkerUtils; import com.navinfo.outdoor.util.TimestampUtil; import com.navinfo.outdoor.util.ToastUtils; import com.sothree.slidinguppanel.ScrollableViewHelper; @@ -101,9 +109,9 @@ import com.tencent.tencentmap.mapsdk.maps.model.Polyline; import com.tencent.tencentmap.mapsdk.maps.model.PolylineOptions; import com.umeng.message.UmengNotificationClickHandler; import com.umeng.message.entity.UMessage; -import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.MultiPoint; -import com.vividsolutions.jts.geom.Point; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.MultiPoint; +import org.locationtech.jts.geom.Point; import org.greenrobot.eventbus.EventBus; @@ -137,16 +145,13 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen private List<Removable> removables; private List<Removable> removableScreenMarker; private List<Removable> removablesLocality; + private final int MARKER_BIG = 4; /* * bitmapDescriptor1 */ //private BitmapDescriptor bitmapDescriptor1, bitmapDescriptor2, bitmapDescriptor3, bitmapDescriptor4, bitmapDescriptor5; private Marker bigMarker; private List<Integer> upload; - private final int MARKER_DOT = 3; - private final int MARKER_LINE = 2; - private final int MARKER_FACE = 1; - private final int MARKER_BIG = 4; private HashMap<String, List<Marker>> removableHashMap; private ArrayList<LatLng> latList; private ArrayList<PoiEntity> poiEntityArrayList; @@ -169,6 +174,8 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen } }); private TextView tvTenantGaps; + private TencentMarkerUtils tencentMarkerUtils; + private Button imgAutoMatchRoad; // 自动匹配道路 public static TreasureFragment newInstance(Bundle bundle) { TreasureFragment fragment = new TreasureFragment(); @@ -185,6 +192,7 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen @Override protected void initView() { super.initView(); + tencentMarkerUtils = new TencentMarkerUtils(); sharedPreferences = Objects.requireNonNull(getActivity()).getSharedPreferences(Constant.MESSAGE_TYPE, Context.MODE_PRIVATE); sharedEdit = sharedPreferences.edit(); //fragment 管理器 @@ -292,6 +300,49 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen tencentMap.setOnMarkerClickListener(Constant.markerClickListener); } }); + + imgAutoMatchRoad = findViewById(R.id.iv_auto_match_road); + imgAutoMatchRoad.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // 设置亮度和摄像机刷新率 + CustomDialog.show((AppCompatActivity) getActivity(), R.layout.camera_setting_pre, new CustomDialog.OnBindView() { + @Override + public void onBind(CustomDialog dialog, View v) { + SharedPreferences sharedPreferences = getActivity().getSharedPreferences("pic", Context.MODE_PRIVATE); + int brightness = sharedPreferences.getInt("brightness", 40); + EditText edtBrightness = v.findViewById(R.id.edt_camera_setting_brightness); + edtBrightness.setText(brightness+""); + + int framness = sharedPreferences.getInt("framness", 30); + EditText edtFramness = v.findViewById(R.id.edt_camera_setting_framness); + edtFramness.setText(framness+""); + + Button btnConfirm = v.findViewById(R.id.btn_camera_setting_confirm); + btnConfirm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + SharedPreferences.Editor editor = getActivity().getSharedPreferences("pic", Context.MODE_PRIVATE).edit(); + if (!edtBrightness.getText().toString().isEmpty()) { + int b = Integer.parseInt(edtBrightness.getText().toString()); + editor.putInt("brightness", b); + } + if (!edtFramness.getText().toString().isEmpty()) { + int f = Integer.parseInt(edtFramness.getText().toString()); + editor.putInt("framness", f); + } + editor.commit(); + Toast.makeText(getActivity(), "设置完成", Toast.LENGTH_SHORT).show(); + + Intent autoMatchIntent = new Intent(getContext(), AutoTakePictureActivity.class); + startActivity(autoMatchIntent); + dialog.doDismiss(); + } + }); + } + }).setFullScreen(true); + } + }); } private void initUM() { @@ -346,10 +397,35 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen dismissLoadingDialog(); removableHashMap.clear(); if (Constant.USHERED != null) { - initThread(); // 刷新筛选的本地数据 + // 刷新筛选的本地数据 + tencentMarkerUtils.initLocalMarker(getActivity(), tencentMap, removablesLocality, removableHashMap, new TencentMarkerUtils.MarkerInitCallback<PoiEntity>() { + @Override + public void onMarkerInit(Map<String, List<Marker>> removableHashMap, List<Integer> uploadByNet, List<PoiEntity> listData) { + + } + }); } - if (Constant.currentLocation != null) { - initList(Constant.currentLocation); // 刷新筛选的网络数据 + if (Constant.currentLocation != null) { //筛选从服务器获取到的数据 + tencentMarkerUtils.initNetMarkerList(getActivity(), Constant.currentLocation, tencentMap, removables,null, null, removableHashMap, 200, new TencentMarkerUtils.MarkerInitCallback<JobSearchBean.BodyBean.ListBean>() { + + @Override + public void onMarkerInit(Map<String, List<Marker>> removableHashMap, List<Integer> uploadByNet, List<JobSearchBean.BodyBean.ListBean> listData) { + latList.clear(); + for (Map.Entry<String, List<Marker>> entry : removableHashMap.entrySet()) { + String key = entry.getKey(); + LatLng lng = GeometryTools.createLatLng(key); + latList.add(lng); + } + + // 服务返回的目前已上报但未上传照片的数据列表 + upload = uploadByNet; + if (upload != null) { + ivSubmit.setEnabled(true); + } else { + ivSubmit.setEnabled(false); + } + } + }); } else { ToastUtils.Message(getActivity(), "未开启定位服务"); } @@ -564,306 +640,6 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen }); } - /** - * 网络删选接口 - * - * @param tencentLocation location - */ - private void initList(TencentLocation tencentLocation) { - int task_type = Constant.TASK_TYPE; - int limit_type = Constant.LIMIT_TYPE; - int taskStatus = Constant.TASK_STARTUP; - if (taskStatus == 1) { - Message obtain = Message.obtain(); - obtain.what = Constant.JOB_SEARCH_WORD; - obtain.obj = null; - EventBus.getDefault().post(obtain); - return; - } - //获取中心点位置 - LatLng mapCenterPoint = getMapCenterPoint(); - if (mapCenterPoint != null) { - centerEncode = Geohash.getInstance().encode(mapCenterPoint.latitude, mapCenterPoint.longitude); - } - String userEncode = Geohash.getInstance().encode(tencentLocation.getLatitude(), tencentLocation.getLongitude()); - OkGo.getInstance().cancelTag(this); - Log.d("TAG", "initList: " + Constant.USHERED); - // 请求方式和请求url - HttpParams httpParams = new HttpParams(); - httpParams.put("userGeo", userEncode); - httpParams.put("centerGeo", centerEncode); - httpParams.put("pageSize", Constant.NUMBER); - httpParams.put("pageNum", 1); - httpParams.put("type", task_type); - httpParams.put("isExclusive", limit_type); - if (taskStatus == 2) { - if (Constant.USHERED != null) { - httpParams.put("received", Constant.USHERED); - } - } - showLoadingDialog(); - OkGoBuilder okGoBuilder = OkGoBuilder.getInstance() - .time(30) - .Builder(getActivity()) - .url(HttpInterface.TASK_LIST) - .cls(JobSearchBean.class) - .params(httpParams) - .token(Constant.ACCESS_TOKEN); - okGoBuilder.getRequest(new Callback<JobSearchBean>() { - @Override - public void onSuccess(JobSearchBean response, int id) { - dismissLoadingDialog(); - if (response.getCode() == 200) { - JobSearchBean.BodyBean body = response.getBody(); - if (body != null) { - upload = response.getBody().getUpload(); - if (upload != null) { - ivSubmit.setEnabled(true); - } else { - ivSubmit.setEnabled(false); - } - Log.d("TAG", "onSuccess: " + response.getBody().toString()); - for (int i = 0; i < removables.size(); i++) { - removables.get(i).remove(); - } - removables.clear(); - List<JobSearchBean.BodyBean.ListBean> list = response.getBody().getList(); - for (int i = 0; i < list.size(); i++) { - JobSearchBean.BodyBean.ListBean listBean = list.get(i); - String encodeStr = list.get(i).getGeo(); - // 解密geo - String geo = Geohash.getInstance().decode(encodeStr); - Log.d("TAG", "onSuccess: " + geo); - Geometry geometry = GeometryTools.createGeometry(geo); - LatLng latLng = null; - switch (geometry.getGeometryType()) { - case "LineString": //线 - case "MultiLineString"://多线 - BitmapDescriptor bitmapLine = null; - if (listBean.getType() == 3) {//poi录像 - bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.road_arrows); - } else if (listBean.getType() == 4) {//道路录像 - bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.poi_video_arrows); - } - List<LatLng> latLineString = GeometryTools.getLatLags(geo); - // 构造 PolylineOptions - PolylineOptions polylineOptions = new PolylineOptions() - .addAll(latLineString) - // 折线设置圆形线头 - .lineCap(true) - // 折线的颜色为绿色 - .color(Color.parseColor("#0096FF")) - // 折线宽度为5像素 - .width(28) - // 还可以添加描边颜色 - //.borderColor(0xffff0000) - // 描边颜色的宽度,线宽还是 25 像素,不过填充的部分宽度为 `width` - 2 * `borderWidth` - //.borderWidth(1); - .arrow(true) - .arrowSpacing(80) - .arrowTexture(bitmapLine); - // 绘制折线 - Polyline polyline = tencentMap.addPolyline(polylineOptions); - if (polyline != null) { - polyline.setZIndex(MARKER_LINE); - removables.add(polyline); - if (latLineString != null && latLineString.size() > 0) { - latLng = latLineString.get(0); - } - } - break; - case "Point": //点 - latLng = GeometryTools.createLatLng(geo); - break; - case "Polygon": //面 - List<LatLng> latPolygon = GeometryTools.getLatLags(geo); - Polygon polygon = tencentMap.addPolygon(new PolygonOptions(). - //连接封闭图形的点 - addAll(latPolygon). - //填充颜色为红色 - fillColor(Color.parseColor("#97E0E7EC")). - //边线颜色为黑色 - strokeColor(0xff000000). - //边线宽度15像素 - strokeWidth(5)); - if (polygon != null) { - polygon.setZIndex(MARKER_FACE); - removables.add(polygon); - com.vividsolutions.jts.geom.Point centroid = geometry.getCentroid(); - double x = centroid.getX(); - double y = centroid.getY(); - latLng = new LatLng(); - latLng.setLatitude(y); - latLng.setLongitude(x); - } - break; - } - switch (list.get(i).getType()) { - case 1://poi - BitmapDescriptor poiDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_poi); - //poiDescriptor.getForager().setScale(50); - assert latLng != null; - Marker poiMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(poiDescriptor).alpha(0.9f) - .anchor(0.5f, 1.0f) - .flat(true) - .clockwise(false)); - if (poiMarker != null) { - if (listBean != null) { - poiMarker.setTag(listBean); - } - poiMarker.setZIndex(MARKER_DOT); - removables.add(poiMarker); - String poiGeo = initGeo(latLng); - geoMarker(poiGeo, poiMarker); - poiMarker.setClickable(true); - } - break; - case 2://充电站 - BitmapDescriptor chargeDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_charge); - assert latLng != null; - Marker stationMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(chargeDescriptor).alpha(0.9f) - .anchor(0.5f, 1.0f) - .flat(true) - .clockwise(false)); - if (stationMarker != null) { - if (listBean != null) { - stationMarker.setTag(listBean); - } - stationMarker.setZIndex(MARKER_DOT); - removables.add(stationMarker); - String stationGeo = initGeo(latLng); - geoMarker(stationGeo, stationMarker); - stationMarker.setClickable(true); - } - break; - case 3://poi录像 - BitmapDescriptor poiVideoDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_poi_video); - assert latLng != null; - Marker poiVideoMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(poiVideoDescriptor).alpha(0.9f) - .anchor(0.5f, 1.0f) - .flat(true) - .clockwise(false)); - if (poiVideoMarker != null) { - if (listBean != null) { - poiVideoMarker.setTag(listBean); - } - poiVideoMarker.setZIndex(MARKER_DOT); - removables.add(poiVideoMarker); - String poiVideoGeo = initGeo(latLng); - geoMarker(poiVideoGeo, poiVideoMarker); - poiVideoMarker.setClickable(true); - } - break; - case 4://道路录像 - BitmapDescriptor roadDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_road); - assert latLng != null; - Marker roadMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(roadDescriptor).alpha(0.9f) - .anchor(0.5f, 1.0f) - .flat(true) - .clockwise(false)); - if (roadMarker != null) { - if (listBean != null) { - roadMarker.setTag(listBean); - } - roadMarker.setZIndex(MARKER_DOT); - removables.add(roadMarker); - String roadGeo = initGeo(latLng); - geoMarker(roadGeo, roadMarker); - roadMarker.setClickable(true); - } - break; - case 5://其他 - BitmapDescriptor otherDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_other); - assert latLng != null; - Marker otherMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(otherDescriptor).alpha(0.9f) - .anchor(0.5f, 1.0f) - .flat(true) - .clockwise(false)); - if (otherMarker != null) { - if (listBean != null) { - otherMarker.setTag(listBean); - } - otherMarker.setZIndex(MARKER_DOT); - removables.add(otherMarker); - String otherGeo = initGeo(latLng); - geoMarker(otherGeo, otherMarker); - otherMarker.setClickable(true); - } - break; - case 6://面状任务 - BitmapDescriptor Descriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_facet); - assert latLng != null; - Marker planarMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(Descriptor).alpha(0.9f) - .anchor(0.5f, 1.0f) - .flat(true) - .clockwise(false)); - if (planarMarker != null) { - if (listBean != null) { - planarMarker.setTag(listBean); - } - planarMarker.setZIndex(MARKER_DOT); - removables.add(planarMarker); - String planarGeo = initGeo(latLng); - geoMarker(planarGeo, planarMarker); - planarMarker.setClickable(true); - } - break; - } - } - } - latList.clear(); - for (Map.Entry<String, List<Marker>> entry : removableHashMap.entrySet()) { - String key = entry.getKey(); - LatLng lng = GeometryTools.createLatLng(key); - latList.add(lng); - } - Message obtain = Message.obtain(); - obtain.what = Constant.JOB_SEARCH_WORD; - obtain.obj = response; - EventBus.getDefault().post(obtain); - } else if (response.getCode() == 230) { - FlushTokenUtil.flushToken(getActivity()); - } else { - ToastUtils.Message(getActivity(), response.getMessage()); - } - } - - @Override - public void onError(Throwable e, int id) { - dismissLoadingDialog(); - String message = e.getMessage(); - assert message != null; - if (message.equals("timeout") || message.equals("Read time out")) { - ToastUtils.Message(getActivity(), "请求超时"); - } else { - ToastUtils.Message(getActivity(), message); - } - } - }); - } - - /** - * geo 坐标点转成 - * - * @param latLng lat - */ - public String initGeo(LatLng latLng) { - return GeometryTools.createGeometry(latLng).toString(); - } - - public void geoMarker(String geo, Marker marker) { - if (!removableHashMap.containsKey(geo)) { - List<Marker> markers = new ArrayList<>(); - markers.add(marker); - removableHashMap.put(geo, markers); - } else { - List<Marker> markers = removableHashMap.get(geo); - assert markers != null; - markers.add(marker); - removableHashMap.put(geo, markers); - } - } - /** * marker 选中的状态 * @@ -927,7 +703,7 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen // 绘制折线 Polyline polyline = tencentMap.addPolyline(polylineOptions); if (polyline != null) { - polyline.setZIndex(MARKER_LINE); + polyline.setZIndex(TencentMarkerUtils.MARKER_LINE); removableScreenMarker.add(polyline); if (latLineString != null && latLineString.size() > 0) { latLng = latLineString.get(0); @@ -946,9 +722,9 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen //边线宽度15像素 strokeWidth(25)); if (polygon != null) { - polygon.setZIndex(MARKER_FACE); + polygon.setZIndex(TencentMarkerUtils.MARKER_FACE); removableScreenMarker.add(polygon); - com.vividsolutions.jts.geom.Point centroid = geometry.getCentroid(); + org.locationtech.jts.geom.Point centroid = geometry.getCentroid(); double x = centroid.getX(); double y = centroid.getY(); latLng = new LatLng(); @@ -1000,297 +776,6 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen } } - /*本地数据库数据*/ - private void initThread() { - int taskStatus = Constant.TASK_STARTUP; - int type = Constant.TASK_TYPE; - int limit = Constant.LIMIT_TYPE; - PoiDatabase poiDatabase = PoiDatabase.getInstance(getContext()); - if (poiDatabase == null) { - return; - } - new Thread(new Runnable() { - @Override - public void run() { - List<PoiEntity> allTaskStatus = poiDatabase.getPoiDao().getAllTaskStatus(taskStatus, taskStatus, type, type, limit, limit); - if (getActivity() != null) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - for (int i = 0; i < removablesLocality.size(); i++) { - removablesLocality.get(i).remove(); - } - removablesLocality.clear(); - for (int i = 0; i < allTaskStatus.size(); i++) { - PoiEntity poiEntity = allTaskStatus.get(i); - String geoWkt = allTaskStatus.get(i).getGeoWkt(); - LatLng latLng = null; - Log.d("TAG", "onSuccess: " + geoWkt); - if (geoWkt != null) { - String geo = Geohash.getInstance().decode(geoWkt);//解密geo - Geometry geometry = GeometryTools.createGeometry(geo); - switch (geometry.getGeometryType()) { - case "Point": //点 - latLng = GeometryTools.createLatLng(geo); - break; - case "LineString": //线 - case "MultiLineString"://多线 - BitmapDescriptor bitmapLine = null; - int color = 0; - if (poiEntity.getType() == 3) {//poi录像 - bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.road_arrows); - } else if (poiEntity.getType() == 4) {//道路录像 - bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.poi_video_arrows); - } - if (poiEntity.getTaskStatus() == 1) { - color = Color.parseColor("#FFE70C"); - } else { - color = Color.parseColor("#BDBDBD"); - } - List<LatLng> latLineString = GeometryTools.getLatLags(geo); - // 构造 PolylineOnions - PolylineOptions polylineOptions = new PolylineOptions() - .addAll(latLineString) - // 折线设置圆形线头 - .lineCap(true) - .color(color) - // 折线宽度为5像素 - .width(28) - .arrow(true) - .arrowSpacing(80) - .arrowTexture(bitmapLine); - // 绘制折线 - Polyline polyline = tencentMap.addPolyline(polylineOptions); - if (polyline != null) { - polyline.setZIndex(MARKER_LINE); - removablesLocality.add(polyline); - if (latLineString != null && latLineString.size() > 0) { - latLng = latLineString.get(0); - } - } - break; - case "Polygon": //面 - List<LatLng> latPolygon = GeometryTools.getLatLags(geo); - Polygon polygon = tencentMap.addPolygon(new PolygonOptions().//连接封闭图形的点 - addAll(latPolygon).//填充颜色为浅蓝色 - fillColor(Color.parseColor("#97E0E7EC")).//边线颜色为黑色 - strokeColor(0xff00ff00).//边线宽度15像素 - strokeWidth(5)); - if (polygon != null) { - polygon.setZIndex(MARKER_FACE); - removablesLocality.add(polygon); - Point centroid = geometry.getCentroid(); - double x = centroid.getX(); - double y = centroid.getY(); - latLng = new LatLng(); - latLng.setLatitude(y); - latLng.setLongitude(x); - } - break; - } - } else { - String detail = allTaskStatus.get(i).getDetail(); - if (detail != null) { - String geo = Geohash.getInstance().decode(detail);//解密geo - Geometry geometry = GeometryTools.createGeometry(geo); - switch (geometry.getGeometryType()) { - case "Point": //点 - latLng = GeometryTools.createLatLng(geo); - break; - case "LineString": //线 - case "MultiLineString"://多线 - BitmapDescriptor bitmapLine = null; - int color = 0; - if (poiEntity.getType() == 3) {//poi录像 - bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.road_arrows); - } else if (poiEntity.getType() == 4) {//道路录像 - bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.poi_video_arrows); - } - if (poiEntity.getTaskStatus() == 1) { - color = Color.parseColor("#FFE70C"); - } else { - color = Color.parseColor("#BDBDBD"); - } - List<LatLng> latLineString = GeometryTools.getLatLags(geo); - // 构造 PolylineOnions - PolylineOptions polylineOptions = new PolylineOptions() - .addAll(latLineString) - // 折线设置圆形线头 - .lineCap(true) - .color(color) - // 折线宽度为5像素 - .width(28) - .arrow(true) - .arrowSpacing(80) - .arrowTexture(bitmapLine); - // 绘制折线 - Polyline polyline = tencentMap.addPolyline(polylineOptions); - if (polyline != null) { - polyline.setZIndex(MARKER_LINE); - removablesLocality.add(polyline); - if (latLineString != null && latLineString.size() > 0) { - latLng = latLineString.get(0); - } - } - break; - case "Polygon": //面 - List<LatLng> latPolygon = GeometryTools.getLatLags(geo); - Polygon polygon = tencentMap.addPolygon(new PolygonOptions().//连接封闭图形的点 - addAll(latPolygon).//填充颜色为浅蓝色 - fillColor(Color.parseColor("#97E0E7EC")).//边线颜色为黑色 - strokeColor(0xff00ff00).//边线宽度15像素 - strokeWidth(5)); - if (polygon != null) { - polygon.setZIndex(MARKER_FACE); - removablesLocality.add(polygon); - Point centroid = geometry.getCentroid(); - double x = centroid.getX(); - double y = centroid.getY(); - latLng = new LatLng(); - latLng.setLatitude(y); - latLng.setLongitude(x); - } - break; - } - } else { - if (allTaskStatus.get(i).getX() != null && allTaskStatus.get(i).getY() != null) { - latLng = new LatLng(Double.parseDouble(allTaskStatus.get(i).getY()), Double.parseDouble(allTaskStatus.get(i).getX())); - } - } - } - switch (poiEntity.getType()) { - case 1://poi - BitmapDescriptor poiDescriptor = null; - if (poiEntity.getTaskStatus() == 1) { - poiDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_poi); - } else { - poiDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.graypoi); - } - assert latLng != null; - Marker poiMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(poiDescriptor) - .flat(true) - .anchor(0.5f, 1f) - .clockwise(false)); - poiMarker.setClickable(true); - poiMarker.setZIndex(MARKER_DOT); - poiMarker.setTitle(poiEntity.getName() + ""); - poiMarker.setTag(poiEntity); - removablesLocality.add(poiMarker); - String poiGeo = initGeo(latLng); - geoMarker(poiGeo, poiMarker); - break; - case 2://充电站 - BitmapDescriptor chargeDescriptor = null; - if (poiEntity.getTaskStatus() == 1) { - chargeDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_charge); - } else { - chargeDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.graycharge); - } - assert latLng != null; - Marker stationMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(chargeDescriptor) - .flat(true) - .anchor(0.5f, 1f) - .clockwise(false)); - stationMarker.setClickable(true); - stationMarker.setZIndex(MARKER_DOT); - stationMarker.setTitle(poiEntity.getName() + ""); - stationMarker.setTag(poiEntity); - removablesLocality.add(stationMarker); - String stationGeo = initGeo(latLng); - geoMarker(stationGeo, stationMarker); - break; - case 3://poi录像 - BitmapDescriptor poiVideoDescriptor = null; - if (poiEntity.getTaskStatus() == 1) { - poiVideoDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_poi_video); - } else { - poiVideoDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.graypoivideo); - } - assert latLng != null; - Marker poiVideoMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(poiVideoDescriptor) - .anchor(0.5f, 1f) - .flat(true) - .clockwise(false)); - poiVideoMarker.setClickable(true); - poiVideoMarker.setZIndex(MARKER_DOT); - poiVideoMarker.setTitle(poiEntity.getName() + ""); - poiVideoMarker.setTag(poiEntity); - removablesLocality.add(poiVideoMarker); - String poiVideoGeo = initGeo(latLng); - geoMarker(poiVideoGeo, poiVideoMarker); - break; - case 4://道路录像 - BitmapDescriptor roadDescriptor = null; - if (poiEntity.getTaskStatus() == 1) { - roadDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_road); - } else { - roadDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.grayroad); - } - assert latLng != null; - Marker roadMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(roadDescriptor) - .anchor(0.5f, 1f) - .flat(true) - .clockwise(false)); - roadMarker.setClickable(true); - roadMarker.setZIndex(MARKER_DOT); - roadMarker.setTitle(poiEntity.getName() + ""); - roadMarker.setTag(poiEntity); - removablesLocality.add(roadMarker); - String roadGeo = initGeo(latLng); - geoMarker(roadGeo, roadMarker); - break; - case 5://其他 - BitmapDescriptor otherDescriptor = null; - if (poiEntity.getTaskStatus() == 1) { - otherDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_other); - } else { - otherDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.grayother); - } - assert latLng != null; - Marker otherMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(otherDescriptor) - .anchor(0.5f, 1f) - .flat(true) - .clockwise(false)); - otherMarker.setClickable(true); - otherMarker.setZIndex(MARKER_DOT); - otherMarker.setTitle(poiEntity.getName() + ""); - otherMarker.setTag(poiEntity); - removablesLocality.add(otherMarker); - String otherGeo = initGeo(latLng); - geoMarker(otherGeo, otherMarker); - break; - case 6://面状任务 - BitmapDescriptor Descriptor = null; - if (poiEntity.getTaskStatus() == 1) { - Descriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_facet); - } else { - Descriptor = BitmapDescriptorFactory.fromResource(R.drawable.grayfacet); - } - assert latLng != null; - Marker planarMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(Descriptor) - .anchor(0.5f, 1f) - .clockwise(false) - .flat(true)); - planarMarker.setClickable(true); - planarMarker.setZIndex(MARKER_DOT); - planarMarker.setTitle(poiEntity.getName() + ""); - planarMarker.setTag(poiEntity); - removablesLocality.add(planarMarker); - String planarGeo = initGeo(latLng); - geoMarker(planarGeo, planarMarker); - break; - } - } - Message obtain = Message.obtain(); - obtain.what = Constant.JOB_SEARCH_POI_WORD; - obtain.obj = allTaskStatus; - EventBus.getDefault().post(obtain); - } - }); - } - } - }).start(); - } @Subscribe public void onEvent(Message data) { @@ -1973,7 +1458,7 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen point.set(minX, minY); lngArrayList.add(new LatLng(projection.fromScreenLocation(point))); poiEntityArrayList = new ArrayList<>(); - com.vividsolutions.jts.geom.Polygon polygon = GeometryTools.createPolygon(lngArrayList); + org.locationtech.jts.geom.Polygon polygon = GeometryTools.createPolygon(lngArrayList); //多点 MultiPoint multiPoint = GeometryTools.createMultiPoint(latList); //拿到覆蓋點 @@ -2124,11 +1609,6 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen } } - /*获取屏幕中心点位置*/ - public LatLng getMapCenterPoint() { - return tencentMap.getCameraPosition().target; - } - /*自定义dialog*/ public void customDialog(List<PoiEntity> list, Marker marker) { AlertDialog dialog = builder.create(); @@ -2251,4 +1731,16 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen } } + private void geoMarker(String geo, Marker marker) { + if (!removableHashMap.containsKey(geo)) { + List<Marker> markers = new ArrayList<>(); + markers.add(marker); + removableHashMap.put(geo, markers); + } else { + List<Marker> markers = removableHashMap.get(geo); + assert markers != null; + markers.add(marker); + removableHashMap.put(geo, markers); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/outdoor/room/LocationRecorderDao.java b/app/src/main/java/com/navinfo/outdoor/room/LocationRecorderDao.java new file mode 100644 index 0000000..9d69ac5 --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/room/LocationRecorderDao.java @@ -0,0 +1,58 @@ +package com.navinfo.outdoor.room; + +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.outdoor.bean.LocationRecorder; + +import java.util.List; + +/** + * 访问数据库操作的接口 + */ +@Dao +public interface LocationRecorderDao { + /* + * 查询 + */ + @Query("SELECT * FROM LocationRecorder") + List<LocationRecorder> getAllLocationRecorder(); + + @Query("SELECT * FROM LocationRecorder where time >= :startTime and time<=:endTime order by time") + List<LocationRecorder> getLocationRecorderByTime(long startTime, long endTime); + + /** + * 添加 + */ + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insertLocationRecorder(LocationRecorder... locationRecorders); + + /** + * 更新 + */ + @Update + void updateLocationRecorder(LocationRecorder... locationRecorders); + + /** + * 删除 + */ + @Delete + void deleteLocationRecorder(LocationRecorder... locationRecorders); + + /** + * 根据条件删除 + */ + @Query("DELETE FROM LocationRecorder where time >= :startTime and time<=:endTime ") + void deleteForTime(long startTime, long endTime); + + + /** + * 全部删除 + */ + @Query("DELETE FROM LocationRecorder") + void deleteAllLocationRecorder(); +} diff --git a/app/src/main/java/com/navinfo/outdoor/room/PoiDatabase.java b/app/src/main/java/com/navinfo/outdoor/room/PoiDatabase.java index 0922f9e..4205139 100644 --- a/app/src/main/java/com/navinfo/outdoor/room/PoiDatabase.java +++ b/app/src/main/java/com/navinfo/outdoor/room/PoiDatabase.java @@ -10,6 +10,7 @@ import androidx.room.migration.Migration; import androidx.sqlite.db.SupportSQLiteDatabase; import com.navinfo.outdoor.api.Constant; +import com.navinfo.outdoor.bean.LocationRecorder; import com.navinfo.outdoor.util.SdkFolderCreate; import java.io.File; @@ -27,7 +28,7 @@ import java.io.File; * 如果需要在主线程调用则使用allowMainThreadQueries进行说明。 */ -@Database(entities = {PoiEntity.class,ChargingPileEntity.class}, version = 2, exportSchema = false) +@Database(entities = {PoiEntity.class,ChargingPileEntity.class, LocationRecorder.class}, version = 3, exportSchema = false) public abstract class PoiDatabase extends RoomDatabase { private static final String DB_NAME = "navinfo.db"; private static volatile PoiDatabase instance; @@ -50,6 +51,7 @@ public abstract class PoiDatabase extends RoomDatabase { getDbName=dbFolder.getAbsolutePath()+"/"+DB_NAME; return Room.databaseBuilder(context, PoiDatabase.class, Constant.POI_DAO+"/"+DB_NAME) .addMigrations(migration_1_2) + .addMigrations(migration_2_3) //.fallbackToDestructiveMigration()//数据库更新时删除数据重新创建 改动特别大的时候在用 .build(); } @@ -65,23 +67,20 @@ public abstract class PoiDatabase extends RoomDatabase { private static Migration migration_2_3 = new Migration(2, 3) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { - database.execSQL("ALTER TABLE poi ADD stage TEXT DEFAULT ''"); - } - }; - private static Migration migration_3_4 = new Migration(3, 4) { - @Override - public void migrate(@NonNull SupportSQLiteDatabase database) { - database.execSQL("ALTER TABLE poi ADD views INTEGER NOT NULL DEFAULT 0"); - } - }; - private static Migration migration_4_5 = new Migration(4, 5) { - @Override - public void migrate(@NonNull SupportSQLiteDatabase database) { - database.execSQL("ALTER TABLE poi ADD partner INTEGER NOT NULL DEFAULT 0"); + database.execSQL("CREATE TABLE LocationRecorder (" + + "time INTEGER PRIMARY KEY NOT NULL ," + + "tencentLocationX REAL NOT NULL ," + + "tencentLocationY REAL NOT NULL ," + + "gpsLocationX REAL NOT NULL ," + + "gpsLocationY REAL NOT NULL ," + + "rssi INTEGER NOT NULL ," + + "bearing REAL NOT NULL," + + "satelliteCount INTEGER NOT NULL ," + + "imgFileName TEXT)");//添加轨迹记录功能 } }; public abstract PoiDao getPoiDao();//其他信息 public abstract ChargingPileDao getChargingPileDao();//充电桩 - + public abstract LocationRecorderDao getRecorderDao(); } diff --git a/app/src/main/java/com/navinfo/outdoor/util/Geohash.java b/app/src/main/java/com/navinfo/outdoor/util/Geohash.java index 2f8dcdc..a80e276 100644 --- a/app/src/main/java/com/navinfo/outdoor/util/Geohash.java +++ b/app/src/main/java/com/navinfo/outdoor/util/Geohash.java @@ -1,7 +1,7 @@ package com.navinfo.outdoor.util; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; -import com.vividsolutions.jts.geom.Geometry; +import org.locationtech.jts.geom.Geometry; import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; diff --git a/app/src/main/java/com/navinfo/outdoor/util/GeometryTools.java b/app/src/main/java/com/navinfo/outdoor/util/GeometryTools.java index c234d98..0edf89e 100644 --- a/app/src/main/java/com/navinfo/outdoor/util/GeometryTools.java +++ b/app/src/main/java/com/navinfo/outdoor/util/GeometryTools.java @@ -3,17 +3,18 @@ package com.navinfo.outdoor.util; import android.graphics.Point; import android.util.Log; +import com.navinfo.outdoor.activity.MyCoordinate; import com.navinfo.outdoor.room.PoiEntity; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; -import com.vividsolutions.jts.geom.Coordinate; -import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.GeometryFactory; -import com.vividsolutions.jts.geom.LineString; -import com.vividsolutions.jts.geom.MultiLineString; -import com.vividsolutions.jts.geom.MultiPoint; -import com.vividsolutions.jts.geom.MultiPolygon; -import com.vividsolutions.jts.geom.Polygon; -import com.vividsolutions.jts.io.WKTReader; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.MultiLineString; +import org.locationtech.jts.geom.MultiPoint; +import org.locationtech.jts.geom.MultiPolygon; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.io.WKTReader; import java.math.BigDecimal; import java.util.ArrayList; @@ -263,8 +264,8 @@ public class GeometryTools { /** * 创建点 */ - public com.vividsolutions.jts.geom.Point createPoint(Coordinate chord) { - com.vividsolutions.jts.geom.Point point = null; + public org.locationtech.jts.geom.Point createPoint(Coordinate chord) { + org.locationtech.jts.geom.Point point = null; GeometryFactory factory = new GeometryFactory(); point = factory.createPoint(chord); return point; @@ -286,7 +287,7 @@ public class GeometryTools { try { geometers = reader.read(geometry); if (geometers != null) { - com.vividsolutions.jts.geom.Point point = geometers.getInteriorPoint(); + org.locationtech.jts.geom.Point point = geometers.getInteriorPoint(); LatLng geoInteriorPoint = new LatLng(point.getY(), point.getX()); if (geometers.getGeometryType().equalsIgnoreCase("Point")) { Coordinate coordinate = geometers.getCoordinate(); @@ -570,6 +571,42 @@ public class GeometryTools { return null; } + /* + * 获取线型 + * @param list + * @return + */ + public static LineString getLineStringByPointList(List<org.locationtech.jts.geom.Point> list) { + + if (list != null && list.size() > 1) { + int size = list.size(); + Coordinate[] coors = new Coordinate[size]; + for (int i = 0; i < size; i++) { + org.locationtech.jts.geom.Point point = list.get(i); + coors[i] = new Coordinate(point.getX(), point.getY()); + } + return getLineStrinGeo(coors); + } + return null; + } + /* + * 获取线型 + * @param list + * @return + */ + public static LineString getLineStringByMyCoordinate(List<MyCoordinate> list) { + + if (list != null && list.size() > 1) { + int size = list.size(); + Coordinate[] coors = new Coordinate[size]; + for (int i = 0; i < size; i++) { + coors[i] = new Coordinate(list.get(i).getX(), list.get(i).getY()); + } + return getLineStrinGeo(coors); + } + return null; + } + /* * 获取线型 * @param coors @@ -941,7 +978,7 @@ public class GeometryTools { if (wkts == null || wkts.size() == 0 || LatLng == null) { return -1; } - com.vividsolutions.jts.geom.Point point = createPoint(new Coordinate(LatLng.getLongitude(), LatLng.getLatitude())); + org.locationtech.jts.geom.Point point = createPoint(new Coordinate(LatLng.getLongitude(), LatLng.getLatitude())); for (int i = 0; i < wkts.size(); i++) { Geometry geometry = createGeometry(wkts.get(i)); if (geometry != null && geometry.getGeometryType().equals("Polygon")) { @@ -1187,4 +1224,5 @@ public class GeometryTools { break; } } + } diff --git a/app/src/main/java/com/navinfo/outdoor/util/TencentMarkerUtils.java b/app/src/main/java/com/navinfo/outdoor/util/TencentMarkerUtils.java new file mode 100644 index 0000000..7227eaa --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/util/TencentMarkerUtils.java @@ -0,0 +1,646 @@ +package com.navinfo.outdoor.util; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Color; +import android.os.Message; +import android.util.Log; + +import com.lzy.okgo.OkGo; +import com.lzy.okgo.model.HttpParams; +import com.navinfo.outdoor.R; +import com.navinfo.outdoor.api.Constant; +import com.navinfo.outdoor.bean.JobSearchBean; +import com.navinfo.outdoor.http.Callback; +import com.navinfo.outdoor.http.HttpInterface; +import com.navinfo.outdoor.http.OkGoBuilder; +import com.navinfo.outdoor.room.PoiDatabase; +import com.navinfo.outdoor.room.PoiEntity; +import com.tencent.map.geolocation.TencentLocation; +import com.tencent.tencentmap.mapsdk.maps.interfaces.Removable; +import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor; +import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory; +import com.tencent.tencentmap.mapsdk.maps.model.LatLng; +import com.tencent.tencentmap.mapsdk.maps.model.Marker; +import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions; +import com.tencent.tencentmap.mapsdk.maps.model.Polygon; +import com.tencent.tencentmap.mapsdk.maps.model.PolygonOptions; +import com.tencent.tencentmap.mapsdk.maps.model.Polyline; +import com.tencent.tencentmap.mapsdk.maps.model.PolylineOptions; +import org.locationtech.jts.geom.Geometry; +import com.tencent.tencentmap.mapsdk.maps.TencentMap; +import org.locationtech.jts.geom.Point; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 处理marker的公共类 + * */ +public class TencentMarkerUtils { + public static final int MARKER_DOT = 3; + public static final int MARKER_LINE = 2; + public static final int MARKER_FACE = 1; + public static final int MARKER_BIG = 4; + // 根据当前位置和屏幕中心点位置,获取marker列表数据 + /** + * 网络删选接口 + * + * @param tencentLocation location 用户当前位置 + */ + public void initNetMarkerList(Activity mContext, TencentLocation tencentLocation, TencentMap tencentMap, List<Removable> removables, String taskTypeStr, String taskStatusStr, Map<String, List<Marker>> removableHashMap, int pageSize, MarkerInitCallback callback) { + int task_type = Constant.TASK_TYPE; + if (taskTypeStr != null) { + task_type = Integer.parseInt(taskTypeStr); + } + int limit_type = Constant.LIMIT_TYPE; + int taskStatus = Constant.TASK_STARTUP; + if (taskTypeStr!=null) { + taskStatus = Integer.parseInt(taskStatusStr); + } + if (taskStatus == 1) { + Message obtain = Message.obtain(); + obtain.what = Constant.JOB_SEARCH_WORD; + obtain.obj = null; + EventBus.getDefault().post(obtain); + return; + } + LatLng mapCenterPoint = tencentMap.getCameraPosition().target; + if (mapCenterPoint == null) { + mapCenterPoint = new LatLng(tencentLocation.getLatitude(), tencentLocation.getLongitude()); + } + + //获取中心点位置 + String centerEncode = Geohash.getInstance().encode(mapCenterPoint.latitude, mapCenterPoint.longitude); + String userEncode = Geohash.getInstance().encode(tencentLocation.getLatitude(), tencentLocation.getLongitude()); + OkGo.getInstance().cancelTag(this); + Log.d("TAG", "initList: " + Constant.USHERED); + // 请求方式和请求url + HttpParams httpParams = new HttpParams(); + httpParams.put("userGeo", userEncode); + httpParams.put("centerGeo", centerEncode); + if (pageSize>0) { + httpParams.put("pageSize", pageSize); + } else { + httpParams.put("pageSize", Constant.NUMBER); + } + httpParams.put("pageNum", 1); + httpParams.put("type", task_type); + httpParams.put("isExclusive", limit_type); + if (taskStatus == 2) { + if (Constant.USHERED != null) { + httpParams.put("received", Constant.USHERED); + } + } + OkGoBuilder okGoBuilder = OkGoBuilder.getInstance() + .time(30) + .Builder(mContext) + .url(HttpInterface.TASK_LIST) + .cls(JobSearchBean.class) + .params(httpParams) + .token(Constant.ACCESS_TOKEN); + okGoBuilder.getRequest(new Callback<JobSearchBean>() { + @Override + public void onSuccess(JobSearchBean response, int id) { + if (response.getCode() == 200) { + JobSearchBean.BodyBean body = response.getBody(); + if (body != null) { + Log.d("TAG", "onSuccess: " + response.getBody().toString()); + for (int i = 0; i < removables.size(); i++) { + removables.get(i).remove(); + } + removables.clear(); + List<JobSearchBean.BodyBean.ListBean> list = response.getBody().getList(); + for (int i = 0; i < list.size(); i++) { + JobSearchBean.BodyBean.ListBean listBean = list.get(i); + String encodeStr = list.get(i).getGeo(); + // 解密geo + String geo = Geohash.getInstance().decode(encodeStr); + Log.d("TAG", "onSuccess: " + geo); + Geometry geometry = GeometryTools.createGeometry(geo); + LatLng latLng = null; + switch (geometry.getGeometryType()) { + case "LineString": //线 + case "MultiLineString"://多线 + BitmapDescriptor bitmapLine = null; + if (listBean.getType() == 3) {//poi录像 + bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.road_arrows); + } else if (listBean.getType() == 4) {//道路录像 + bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.poi_video_arrows); + } + List<LatLng> latLineString = GeometryTools.getLatLags(geo); + // 构造 PolylineOptions + PolylineOptions polylineOptions = new PolylineOptions() + .addAll(latLineString) + // 折线设置圆形线头 + .lineCap(true) + // 折线的颜色为绿色 + .color(Color.parseColor("#0096FF")) + // 折线宽度为5像素 + .width(28) + // 还可以添加描边颜色 + //.borderColor(0xffff0000) + // 描边颜色的宽度,线宽还是 25 像素,不过填充的部分宽度为 `width` - 2 * `borderWidth` + //.borderWidth(1); + .arrow(true) + .arrowSpacing(80) + .arrowTexture(bitmapLine); + // 绘制折线 + Polyline polyline = tencentMap.addPolyline(polylineOptions); + if (polyline != null) { + polyline.setZIndex(MARKER_LINE); + removables.add(polyline); + if (latLineString != null && latLineString.size() > 0) { + latLng = latLineString.get(0); + } + } + break; + case "Point": //点 + latLng = GeometryTools.createLatLng(geo); + break; + case "Polygon": //面 + List<LatLng> latPolygon = GeometryTools.getLatLags(geo); + Polygon polygon = tencentMap.addPolygon(new PolygonOptions(). + //连接封闭图形的点 + addAll(latPolygon). + //填充颜色为红色 + fillColor(Color.parseColor("#97E0E7EC")). + //边线颜色为黑色 + strokeColor(0xff000000). + //边线宽度15像素 + strokeWidth(5)); + if (polygon != null) { + polygon.setZIndex(MARKER_FACE); + removables.add(polygon); + org.locationtech.jts.geom.Point centroid = geometry.getCentroid(); + double x = centroid.getX(); + double y = centroid.getY(); + latLng = new LatLng(); + latLng.setLatitude(y); + latLng.setLongitude(x); + } + break; + } + switch (list.get(i).getType()) { + case 1://poi + BitmapDescriptor poiDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_poi); + //poiDescriptor.getForager().setScale(50); + assert latLng != null; + Marker poiMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(poiDescriptor).alpha(0.9f) + .anchor(0.5f, 1.0f) + .flat(true) + .clockwise(false)); + if (poiMarker != null) { + if (listBean != null) { + poiMarker.setTag(listBean); + } + poiMarker.setZIndex(MARKER_DOT); + removables.add(poiMarker); + String poiGeo = initGeo(latLng); + geoMarker(poiGeo, poiMarker, removableHashMap); + poiMarker.setClickable(true); + } + break; + case 2://充电站 + BitmapDescriptor chargeDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_charge); + assert latLng != null; + Marker stationMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(chargeDescriptor).alpha(0.9f) + .anchor(0.5f, 1.0f) + .flat(true) + .clockwise(false)); + if (stationMarker != null) { + if (listBean != null) { + stationMarker.setTag(listBean); + } + stationMarker.setZIndex(MARKER_DOT); + removables.add(stationMarker); + String stationGeo = initGeo(latLng); + geoMarker(stationGeo, stationMarker, removableHashMap); + stationMarker.setClickable(true); + } + break; + case 3://poi录像 + BitmapDescriptor poiVideoDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_poi_video); + assert latLng != null; + Marker poiVideoMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(poiVideoDescriptor).alpha(0.9f) + .anchor(0.5f, 1.0f) + .flat(true) + .clockwise(false)); + if (poiVideoMarker != null) { + if (listBean != null) { + poiVideoMarker.setTag(listBean); + } + poiVideoMarker.setZIndex(MARKER_DOT); + removables.add(poiVideoMarker); + String poiVideoGeo = initGeo(latLng); + geoMarker(poiVideoGeo, poiVideoMarker, removableHashMap); + poiVideoMarker.setClickable(true); + } + break; + case 4://道路录像 + BitmapDescriptor roadDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_road); + assert latLng != null; + Marker roadMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(roadDescriptor).alpha(0.9f) + .anchor(0.5f, 1.0f) + .flat(true) + .clockwise(false)); + if (roadMarker != null) { + if (listBean != null) { + roadMarker.setTag(listBean); + } + roadMarker.setZIndex(MARKER_DOT); + removables.add(roadMarker); + String roadGeo = initGeo(latLng); + geoMarker(roadGeo, roadMarker, removableHashMap); + roadMarker.setClickable(true); + } + break; + case 5://其他 + BitmapDescriptor otherDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_other); + assert latLng != null; + Marker otherMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(otherDescriptor).alpha(0.9f) + .anchor(0.5f, 1.0f) + .flat(true) + .clockwise(false)); + if (otherMarker != null) { + if (listBean != null) { + otherMarker.setTag(listBean); + } + otherMarker.setZIndex(MARKER_DOT); + removables.add(otherMarker); + String otherGeo = initGeo(latLng); + geoMarker(otherGeo, otherMarker, removableHashMap); + otherMarker.setClickable(true); + } + break; + case 6://面状任务 + BitmapDescriptor Descriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_facet); + assert latLng != null; + Marker planarMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(Descriptor).alpha(0.9f) + .anchor(0.5f, 1.0f) + .flat(true) + .clockwise(false)); + if (planarMarker != null) { + if (listBean != null) { + planarMarker.setTag(listBean); + } + planarMarker.setZIndex(MARKER_DOT); + removables.add(planarMarker); + String planarGeo = initGeo(latLng); + geoMarker(planarGeo, planarMarker, removableHashMap); + planarMarker.setClickable(true); + } + break; + } + } + callback.onMarkerInit(removableHashMap, response.getBody().getUpload(), list); + Message obtain = Message.obtain(); + obtain.what = Constant.JOB_SEARCH_WORD; + obtain.obj = response; + EventBus.getDefault().post(obtain); + } + } else if (response.getCode() == 230) { + FlushTokenUtil.flushToken(mContext); + } else { + ToastUtils.Message(mContext, response.getMessage()); + } + } + + @Override + public void onError(Throwable e, int id) { + String message = e.getMessage(); + assert message != null; + if (message.equals("timeout") || message.equals("Read time out")) { + ToastUtils.Message(mContext, "请求超时"); + } else { + ToastUtils.Message(mContext, message); + } + } + }); + } + + /*本地数据库数据*/ + public void initLocalMarker(Activity mContext, TencentMap tencentMap, List<Removable> removablesLocality, Map<String, List<Marker>> removableHashMap, MarkerInitCallback callback) { + int taskStatus = Constant.TASK_STARTUP; + int type = Constant.TASK_TYPE; + int limit = Constant.LIMIT_TYPE; + PoiDatabase poiDatabase = PoiDatabase.getInstance(mContext); + if (poiDatabase == null) { + return; + } + new Thread(new Runnable() { + @Override + public void run() { + List<PoiEntity> allTaskStatus = poiDatabase.getPoiDao().getAllTaskStatus(taskStatus, taskStatus, type, type, limit, limit); + if (mContext != null) { + mContext.runOnUiThread(new Runnable() { + @Override + public void run() { + for (int i = 0; i < removablesLocality.size(); i++) { + removablesLocality.get(i).remove(); + } + removablesLocality.clear(); + for (int i = 0; i < allTaskStatus.size(); i++) { + PoiEntity poiEntity = allTaskStatus.get(i); + String geoWkt = allTaskStatus.get(i).getGeoWkt(); + LatLng latLng = null; + Log.d("TAG", "onSuccess: " + geoWkt); + if (geoWkt != null) { + String geo = Geohash.getInstance().decode(geoWkt);//解密geo + Geometry geometry = GeometryTools.createGeometry(geo); + switch (geometry.getGeometryType()) { + case "Point": //点 + latLng = GeometryTools.createLatLng(geo); + break; + case "LineString": //线 + case "MultiLineString"://多线 + BitmapDescriptor bitmapLine = null; + int color = 0; + if (poiEntity.getType() == 3) {//poi录像 + bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.road_arrows); + } else if (poiEntity.getType() == 4) {//道路录像 + bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.poi_video_arrows); + } + if (poiEntity.getTaskStatus() == 1) { + color = Color.parseColor("#FFE70C"); + } else { + color = Color.parseColor("#BDBDBD"); + } + List<LatLng> latLineString = GeometryTools.getLatLags(geo); + // 构造 PolylineOnions + PolylineOptions polylineOptions = new PolylineOptions() + .addAll(latLineString) + // 折线设置圆形线头 + .lineCap(true) + .color(color) + // 折线宽度为5像素 + .width(28) + .arrow(true) + .arrowSpacing(80) + .arrowTexture(bitmapLine); + // 绘制折线 + Polyline polyline = tencentMap.addPolyline(polylineOptions); + if (polyline != null) { + polyline.setZIndex(MARKER_LINE); + removablesLocality.add(polyline); + if (latLineString != null && latLineString.size() > 0) { + latLng = latLineString.get(0); + } + } + break; + case "Polygon": //面 + List<LatLng> latPolygon = GeometryTools.getLatLags(geo); + Polygon polygon = tencentMap.addPolygon(new PolygonOptions().//连接封闭图形的点 + addAll(latPolygon).//填充颜色为浅蓝色 + fillColor(Color.parseColor("#97E0E7EC")).//边线颜色为黑色 + strokeColor(0xff00ff00).//边线宽度15像素 + strokeWidth(5)); + if (polygon != null) { + polygon.setZIndex(MARKER_FACE); + removablesLocality.add(polygon); + Point centroid = geometry.getCentroid(); + double x = centroid.getX(); + double y = centroid.getY(); + latLng = new LatLng(); + latLng.setLatitude(y); + latLng.setLongitude(x); + } + break; + } + } else { + String detail = allTaskStatus.get(i).getDetail(); + if (detail != null) { + String geo = Geohash.getInstance().decode(detail);//解密geo + Geometry geometry = GeometryTools.createGeometry(geo); + switch (geometry.getGeometryType()) { + case "Point": //点 + latLng = GeometryTools.createLatLng(geo); + break; + case "LineString": //线 + case "MultiLineString"://多线 + BitmapDescriptor bitmapLine = null; + int color = 0; + if (poiEntity.getType() == 3) {//poi录像 + bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.road_arrows); + } else if (poiEntity.getType() == 4) {//道路录像 + bitmapLine = BitmapDescriptorFactory.fromResource(R.drawable.poi_video_arrows); + } + if (poiEntity.getTaskStatus() == 1) { + color = Color.parseColor("#FFE70C"); + } else { + color = Color.parseColor("#BDBDBD"); + } + List<LatLng> latLineString = GeometryTools.getLatLags(geo); + // 构造 PolylineOnions + PolylineOptions polylineOptions = new PolylineOptions() + .addAll(latLineString) + // 折线设置圆形线头 + .lineCap(true) + .color(color) + // 折线宽度为5像素 + .width(28) + .arrow(true) + .arrowSpacing(80) + .arrowTexture(bitmapLine); + // 绘制折线 + Polyline polyline = tencentMap.addPolyline(polylineOptions); + if (polyline != null) { + polyline.setZIndex(MARKER_LINE); + removablesLocality.add(polyline); + if (latLineString != null && latLineString.size() > 0) { + latLng = latLineString.get(0); + } + } + break; + case "Polygon": //面 + List<LatLng> latPolygon = GeometryTools.getLatLags(geo); + Polygon polygon = tencentMap.addPolygon(new PolygonOptions().//连接封闭图形的点 + addAll(latPolygon).//填充颜色为浅蓝色 + fillColor(Color.parseColor("#97E0E7EC")).//边线颜色为黑色 + strokeColor(0xff00ff00).//边线宽度15像素 + strokeWidth(5)); + if (polygon != null) { + polygon.setZIndex(MARKER_FACE); + removablesLocality.add(polygon); + Point centroid = geometry.getCentroid(); + double x = centroid.getX(); + double y = centroid.getY(); + latLng = new LatLng(); + latLng.setLatitude(y); + latLng.setLongitude(x); + } + break; + } + } else { + if (allTaskStatus.get(i).getX() != null && allTaskStatus.get(i).getY() != null) { + latLng = new LatLng(Double.parseDouble(allTaskStatus.get(i).getY()), Double.parseDouble(allTaskStatus.get(i).getX())); + } + } + } + switch (poiEntity.getType()) { + case 1://poi + BitmapDescriptor poiDescriptor = null; + if (poiEntity.getTaskStatus() == 1) { + poiDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_poi); + } else { + poiDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.graypoi); + } + assert latLng != null; + Marker poiMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(poiDescriptor) + .flat(true) + .anchor(0.5f, 1f) + .clockwise(false)); + poiMarker.setClickable(true); + poiMarker.setZIndex(MARKER_DOT); + poiMarker.setTitle(poiEntity.getName() + ""); + poiMarker.setTag(poiEntity); + removablesLocality.add(poiMarker); + String poiGeo = initGeo(latLng); + geoMarker(poiGeo, poiMarker, removableHashMap); + break; + case 2://充电站 + BitmapDescriptor chargeDescriptor = null; + if (poiEntity.getTaskStatus() == 1) { + chargeDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_charge); + } else { + chargeDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.graycharge); + } + assert latLng != null; + Marker stationMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(chargeDescriptor) + .flat(true) + .anchor(0.5f, 1f) + .clockwise(false)); + stationMarker.setClickable(true); + stationMarker.setZIndex(MARKER_DOT); + stationMarker.setTitle(poiEntity.getName() + ""); + stationMarker.setTag(poiEntity); + removablesLocality.add(stationMarker); + String stationGeo = initGeo(latLng); + geoMarker(stationGeo, stationMarker, removableHashMap); + break; + case 3://poi录像 + BitmapDescriptor poiVideoDescriptor = null; + if (poiEntity.getTaskStatus() == 1) { + poiVideoDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_poi_video); + } else { + poiVideoDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.graypoivideo); + } + assert latLng != null; + Marker poiVideoMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(poiVideoDescriptor) + .anchor(0.5f, 1f) + .flat(true) + .clockwise(false)); + poiVideoMarker.setClickable(true); + poiVideoMarker.setZIndex(MARKER_DOT); + poiVideoMarker.setTitle(poiEntity.getName() + ""); + poiVideoMarker.setTag(poiEntity); + removablesLocality.add(poiVideoMarker); + String poiVideoGeo = initGeo(latLng); + geoMarker(poiVideoGeo, poiVideoMarker, removableHashMap); + break; + case 4://道路录像 + BitmapDescriptor roadDescriptor = null; + if (poiEntity.getTaskStatus() == 1) { + roadDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_road); + } else { + roadDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.grayroad); + } + assert latLng != null; + Marker roadMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(roadDescriptor) + .anchor(0.5f, 1f) + .flat(true) + .clockwise(false)); + roadMarker.setClickable(true); + roadMarker.setZIndex(MARKER_DOT); + roadMarker.setTitle(poiEntity.getName() + ""); + roadMarker.setTag(poiEntity); + removablesLocality.add(roadMarker); + String roadGeo = initGeo(latLng); + geoMarker(roadGeo, roadMarker, removableHashMap); + break; + case 5://其他 + BitmapDescriptor otherDescriptor = null; + if (poiEntity.getTaskStatus() == 1) { + otherDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_other); + } else { + otherDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.grayother); + } + assert latLng != null; + Marker otherMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(otherDescriptor) + .anchor(0.5f, 1f) + .flat(true) + .clockwise(false)); + otherMarker.setClickable(true); + otherMarker.setZIndex(MARKER_DOT); + otherMarker.setTitle(poiEntity.getName() + ""); + otherMarker.setTag(poiEntity); + removablesLocality.add(otherMarker); + String otherGeo = initGeo(latLng); + geoMarker(otherGeo, otherMarker, removableHashMap); + break; + case 6://面状任务 + BitmapDescriptor Descriptor = null; + if (poiEntity.getTaskStatus() == 1) { + Descriptor = BitmapDescriptorFactory.fromResource(R.drawable.marker_facet); + } else { + Descriptor = BitmapDescriptorFactory.fromResource(R.drawable.grayfacet); + } + assert latLng != null; + Marker planarMarker = tencentMap.addMarker(new MarkerOptions(latLng).icon(Descriptor) + .anchor(0.5f, 1f) + .clockwise(false) + .flat(true)); + planarMarker.setClickable(true); + planarMarker.setZIndex(MARKER_DOT); + planarMarker.setTitle(poiEntity.getName() + ""); + planarMarker.setTag(poiEntity); + removablesLocality.add(planarMarker); + String planarGeo = initGeo(latLng); + geoMarker(planarGeo, planarMarker, removableHashMap); + break; + } + } + callback.onMarkerInit(removableHashMap, null, allTaskStatus); + Message obtain = Message.obtain(); + obtain.what = Constant.JOB_SEARCH_POI_WORD; + obtain.obj = allTaskStatus; + EventBus.getDefault().post(obtain); + } + }); + } + } + }).start(); + } + + + /** + * geo 坐标点转成 + * + * @param latLng lat + */ + private String initGeo(LatLng latLng) { + return GeometryTools.createGeometry(latLng).toString(); + } + + + private void geoMarker(String geo, Marker marker, Map<String, List<Marker>> removableHashMap) { + if (!removableHashMap.containsKey(geo)) { + List<Marker> markers = new ArrayList<>(); + markers.add(marker); + removableHashMap.put(geo, markers); + } else { + List<Marker> markers = removableHashMap.get(geo); + assert markers != null; + markers.add(marker); + removableHashMap.put(geo, markers); + } + } + + public interface MarkerInitCallback<T> { + public void onMarkerInit(Map<String, List<Marker>> removableHashMap, List<Integer> uploadByNet/*服务器返回的该用户需要上传的数据列表*/, List<T> listData); + } +} diff --git a/app/src/main/res/layout/activity_auto_take_pictures.xml b/app/src/main/res/layout/activity_auto_take_pictures.xml new file mode 100644 index 0000000..415b794 --- /dev/null +++ b/app/src/main/res/layout/activity_auto_take_pictures.xml @@ -0,0 +1,256 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#FF444444" + tools:context=".activity.PicturesActivity"> + + <FrameLayout + android:id="@+id/layer_change" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <com.otaliastudios.cameraview.CameraView + android:id="@+id/camera" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:keepScreenOn="true" + app:cameraPictureFormat="jpeg" + app:cameraPictureMetering="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <com.tencent.tencentmap.mapsdk.maps.TextureMapView + android:id="@+id/text_map_view" + android:layout_width="200dp" + android:layout_height="157dp" + app:layout_constraintHeight_default="percent" + app:layout_constraintHeight_percent="0.4" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintWidth_default="percent" + app:layout_constraintWidth_percent="0.4" /> + + </FrameLayout> + + <ImageView + android:id="@+id/image_view" + android:layout_width="300dp" + android:layout_height="157dp" + app:layout_constraintHeight_default="percent" + app:layout_constraintHeight_percent="0.4" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintWidth_default="percent" + app:layout_constraintWidth_percent="0.4" /> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + android:orientation="vertical"> + <TextView + android:id="@+id/tv_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="25dp" + android:textColor="@color/white" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <TextView + android:id="@+id/tv_convert" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/white" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + </LinearLayout> + + <ImageView + android:id="@+id/iv_zoom_add" + android:layout_width="50dp" + android:layout_height="50dp" + android:layout_marginEnd="25dp" + android:src="@mipmap/zoom_add" + android:visibility="gone" + app:layout_constraintBottom_toTopOf="@+id/btn_stop_picture" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/iv_zoom_del" + android:layout_width="50dp" + android:layout_height="50dp" + android:layout_marginTop="15dp" + android:src="@mipmap/zoom_del" + android:visibility="gone" + app:layout_constraintLeft_toLeftOf="@id/iv_zoom_add" + app:layout_constraintTop_toBottomOf="@id/iv_zoom_add" /> + + <!--<CheckBox + android:id="@+id/cb_map_type" + android:layout_width="50dp" + android:layout_height="50dp" + android:layout_marginTop="15dp" + android:background="@drawable/atlas_selector" + android:button="@null" + android:checked="false" + android:visibility="gone" + app:layout_constraintLeft_toLeftOf="@id/iv_zoom_del" + app:layout_constraintTop_toBottomOf="@id/iv_zoom_del" />--> + + <ImageView + android:id="@+id/iv_location" + android:layout_width="50dp" + android:layout_height="50dp" + android:layout_marginTop="15dp" + android:src="@mipmap/mine_location" + android:visibility="gone" + app:layout_constraintLeft_toLeftOf="@id/iv_zoom_del" + app:layout_constraintTop_toBottomOf="@id/iv_zoom_del" /> + + <ImageView + android:id="@+id/btn_switch" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="20dp" + android:layout_marginEnd="25dp" + android:src="@mipmap/switcher" + android:padding="@dimen/default_widget_padding" + android:text="切换" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <Button + android:id="@+id/btn_setting" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="设置" + android:layout_marginTop="@dimen/default_widget_padding" + app:layout_constraintTop_toBottomOf="@id/btn_switch" + app:layout_constraintRight_toRightOf="parent"></Button> + + <Switch + android:id="@+id/location_switch" + android:text="启用定位" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:checked="true" + android:padding="@dimen/default_widget_padding" + app:layout_constraintTop_toBottomOf="@id/btn_setting" + app:layout_constraintRight_toRightOf="parent"></Switch> + + <RadioGroup + android:id="@+id/radio_group_picture" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="35dp" + android:orientation="vertical" + android:visibility="gone" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/image_view"> + + <RadioButton + android:id="@+id/radio_btn_hand" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="15dp" + android:layout_marginBottom="15dp" + android:button="@null" + android:text="手动" + android:textColor="@color/rbtn_text_color_selector" /> + + <RadioButton + android:id="@+id/radio_btn_half_sec" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="15dp" + android:layout_marginBottom="15dp" + android:button="@null" + android:text="自动0.5秒" + android:textColor="@color/rbtn_text_color_selector" /> + + <RadioButton + android:id="@+id/radio_btn_auto" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="15dp" + android:layout_marginBottom="15dp" + android:button="@null" + android:text="自动1秒" + android:textColor="@color/rbtn_text_color_selector" /> + + <RadioButton + android:id="@+id/radio_btn_auto_sec" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="15dp" + android:layout_marginBottom="15dp" + android:button="@null" + android:text="自动2秒" + android:textColor="@color/rbtn_text_color_selector" /> + + </RadioGroup> + + <ImageView + android:id="@+id/iv_pic_road" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@mipmap/take_pic_arrow" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/iv_pic_video" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@mipmap/take_poi_video_arrow" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <Button + android:id="@+id/clear_all_match_data" + style="@style/user_data_style" + android:layout_width="100dp" + android:layout_height="wrap_content" + android:layout_marginBottom="20dp" + android:background="@drawable/user_style" + android:button="@null" + android:gravity="center" + android:padding="@dimen/fab_margin" + android:text="清空匹配" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toLeftOf="@id/btn_stop_picture" /> + + <Button + android:id="@+id/btn_stop_picture" + android:layout_width="100dp" + android:layout_height="wrap_content" + android:background="@drawable/uploding_shape" + android:text="结束采集" + android:textColor="@color/colorBlue" + app:layout_constraintBottom_toBottomOf="@id/clear_all_match_data" + app:layout_constraintLeft_toRightOf="@id/clear_all_match_data" + app:layout_constraintRight_toRightOf="parent" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_pictures.xml b/app/src/main/res/layout/activity_pictures.xml index 53b8153..260ff12 100644 --- a/app/src/main/res/layout/activity_pictures.xml +++ b/app/src/main/res/layout/activity_pictures.xml @@ -122,17 +122,27 @@ app:layout_constraintLeft_toLeftOf="@id/iv_zoom_del" app:layout_constraintTop_toBottomOf="@id/iv_zoom_del" /> - <Button + <ImageView android:id="@+id/btn_switch" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_marginEnd="25dp" android:text="切换" - android:visibility="gone" + android:src="@mipmap/switcher" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> + <Button + android:id="@+id/btn_setting" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="设置" + android:layout_marginTop="@dimen/default_widget_padding" + android:visibility="gone" + app:layout_constraintTop_toBottomOf="@id/btn_switch" + app:layout_constraintRight_toRightOf="parent"></Button> + <RadioGroup android:id="@+id/radio_group_picture" android:layout_width="wrap_content" diff --git a/app/src/main/res/layout/camera_setting.xml b/app/src/main/res/layout/camera_setting.xml new file mode 100644 index 0000000..38b5e90 --- /dev/null +++ b/app/src/main/res/layout/camera_setting.xml @@ -0,0 +1,165 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/dialogButtonMIUITextGray" + android:padding="@dimen/fab_margin" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="屏幕亮度"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_brightness" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="number" + android:hint="屏幕亮度" + ></EditText> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="相机刷新"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_framness" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="number" + android:hint="相机刷新" + ></EditText> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="起点距离阈值"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_start_distance" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="起点距离阈值" + ></EditText> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="过程点距离阈值"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_mid_distance" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="过程点距离阈值" + ></EditText> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="起点放弃个数"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_start_count" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="number" + android:hint="起点放弃个数" + ></EditText> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="过程点放弃个数"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_mid_count" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="number" + android:hint="过程点放弃个数" + ></EditText> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="放弃匹配距离阈值"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_unmatch_pecent" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="放弃匹配距离百分比" + ></EditText> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="完全匹配距离百分比"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_match_pecent" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="完全匹配距离百分比" + ></EditText> + </LinearLayout> + + <Button + android:id="@+id/btn_camera_setting_confirm" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="确定" + android:layout_gravity="center"></Button> +</LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/camera_setting_pre.xml b/app/src/main/res/layout/camera_setting_pre.xml new file mode 100644 index 0000000..dc49790 --- /dev/null +++ b/app/src/main/res/layout/camera_setting_pre.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/dialogButtonMIUITextGray" + android:padding="@dimen/fab_margin" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="屏幕亮度"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_brightness" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="number" + android:hint="屏幕亮度" + ></EditText> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="@dimen/default_widget_padding" + android:text="相机刷新"></TextView> + + <EditText + android:id="@+id/edt_camera_setting_framness" + android:layout_width="150dp" + android:layout_height="wrap_content" + android:inputType="number" + android:hint="相机刷新" + ></EditText> + </LinearLayout> + + + <Button + android:id="@+id/btn_camera_setting_confirm" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="确定" + android:layout_gravity="center"></Button> +</LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/treasure_fragment.xml b/app/src/main/res/layout/treasure_fragment.xml index f1802c1..b74ac2c 100644 --- a/app/src/main/res/layout/treasure_fragment.xml +++ b/app/src/main/res/layout/treasure_fragment.xml @@ -41,6 +41,7 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> + <ImageView android:id="@+id/iv_mas_notification" android:layout_width="10dp" @@ -115,6 +116,16 @@ app:layout_constraintLeft_toLeftOf="@id/cb_map_type" app:layout_constraintTop_toTopOf="@+id/iv_refrish" /> + <Button + android:id="@+id/iv_auto_match_road" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="12dp" + android:text="道路自动匹配" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent"/> + <ImageView android:id="@+id/iv_zoom_add" android:layout_width="50dp" diff --git a/app/src/main/res/mipmap-xxhdpi/switcher.png b/app/src/main/res/mipmap-xxhdpi/switcher.png new file mode 100644 index 0000000..f50db6d Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/switcher.png differ diff --git a/app/src/test/java/com/navinfo/outdoor/ExampleUnitTest.java b/app/src/test/java/com/navinfo/outdoor/ExampleUnitTest.java index 9adf66f..761a4b1 100644 --- a/app/src/test/java/com/navinfo/outdoor/ExampleUnitTest.java +++ b/app/src/test/java/com/navinfo/outdoor/ExampleUnitTest.java @@ -1,9 +1,16 @@ package com.navinfo.outdoor; import org.junit.Test; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.Point; import static org.junit.Assert.*; +import com.tencent.tencentmap.mapsdk.maps.model.LatLng; + +import java.util.ArrayList; +import java.util.List; + /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +21,15 @@ public class ExampleUnitTest { public void addition_isCorrect() { assertEquals(4, 2 + 2); } + @Test + public void testDistance() { + Point point = (Point) GeometryTools.createGeometry(new LatLng(4,4)); + List<LatLng> latLngList = new ArrayList<>(); + latLngList.add(new LatLng(0,0)); + latLngList.add(new LatLng(1,1)); + + LineString lineString = GeometryTools.getLineStainGeo(latLngList); + + System.out.println("距离:"+lineString.distance(point)); + } } \ No newline at end of file diff --git a/app/src/test/java/com/navinfo/outdoor/GeometryTools.java b/app/src/test/java/com/navinfo/outdoor/GeometryTools.java new file mode 100644 index 0000000..1d73407 --- /dev/null +++ b/app/src/test/java/com/navinfo/outdoor/GeometryTools.java @@ -0,0 +1,1229 @@ +package com.navinfo.outdoor; + +import android.graphics.Point; +import android.util.Log; + +import com.navinfo.outdoor.activity.MyCoordinate; +import com.navinfo.outdoor.room.PoiEntity; +import com.tencent.tencentmap.mapsdk.maps.model.LatLng; + +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.MultiLineString; +import org.locationtech.jts.geom.MultiPoint; +import org.locationtech.jts.geom.MultiPolygon; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.io.WKTReader; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * @author qj 几何工具类 + */ +public class GeometryTools { + + static final double PI = 3.14159216; + private static volatile GeometryTools mInstance; + + public static String POINT_GEOMETRY_TYPE = "Point", LINE_GEOMETRY_TYPE = "LineString", POLYGON_GEOMETRY_TYPE = "Polygon"; + + public static GeometryTools getInstance() { + + if (mInstance == null) { + synchronized (GeometryTools.class) { + if (mInstance == null) { + mInstance = new GeometryTools(); + } + } + } + return mInstance; + } + + + /** + * 返回点几何 + */ + public static Geometry createGeometry(LatLng gp) { + if (gp != null) { + Coordinate coordinate = new Coordinate(gp.getLongitude(), gp.getLatitude()); + GeometryFactory factory = new GeometryFactory(); + return factory.createPoint(coordinate); + } + + return null; + + } + + /** + * 返回点几何 + */ + public static Geometry createGeometry(LatLng gp, boolean formatDouble5) { + if (gp != null) { + Coordinate coordinate = null; + if (formatDouble5) { + coordinate = new Coordinate(gp.getLongitude(), gp.getLatitude()); + } else { + coordinate = new Coordinate(gp.getLongitude(), gp.getLatitude()); + } + GeometryFactory factory = new GeometryFactory(); + return factory.createPoint(coordinate); + } + return null; + } + + public static Geometry createGeometry(double[] coor) { + if (coor != null && coor.length == 2) { + Coordinate coordinate = new Coordinate(coor[0], coor[1]); + GeometryFactory factory = new GeometryFactory(); + Geometry geo = factory.createPoint(coordinate); + return geo; + } + return null; + } + + /* + * 获取多面 + * @param polygons + * @return + */ + public static MultiPolygon createMultiPolygon(Polygon[] polygons) { + if (polygons == null || polygons.length == 0) + return null; + MultiPolygon multiPolygon = null; + GeometryFactory factory = new GeometryFactory(); + try { + multiPolygon = factory.createMultiPolygon(polygons); + } catch (Exception e) { + e.printStackTrace(); + } + return multiPolygon; + } + + /* + * 获取多线 + * @param lineStrings + * @return + */ + public static MultiLineString createMultiLine(LineString[] lineStrings) { + if (lineStrings == null || lineStrings.length == 0) + return null; + MultiLineString multiLineString = null; + GeometryFactory factory = new GeometryFactory(); + + try { + + multiLineString = factory.createMultiLineString(lineStrings); + + } catch (Exception e) { + e.printStackTrace(); + } + + return multiLineString; + } + + /* + * 创建集合 + * + * @param Coordinate [] + * @return Geometry + */ + public MultiPoint createMultiPoint(Coordinate[] coords) { + + if (coords == null || coords.length == 0) + return null; + + MultiPoint createMultiPoint = null; + + GeometryFactory factory = new GeometryFactory(); + + try { + + createMultiPoint = factory.createMultiPoint(coords); + + } catch (Exception e) { + e.printStackTrace(); + } + + return createMultiPoint; + } + + /** + * 创建集合 + * + * @param list [] + * @return Geometry + */ + public static MultiPoint createMultiPoint(List<LatLng> list) { + + if (list == null || list.size() == 0) + return null; + + MultiPoint createMultiPoint = null; + GeometryFactory factory = new GeometryFactory(); + try { + Coordinate[] coords = new Coordinate[list.size()]; + for (int i = 0; i < list.size(); i++) { + coords[i] = new Coordinate(list.get(i).getLongitude(), list.get(i).getLatitude()); + } + createMultiPoint = factory.createMultiPoint(coords); + } catch (Exception e) { + e.getLocalizedMessage(); + } + return createMultiPoint; + } + + + /* + * 返回点几何 + * + * @param wkt + * @return Geometry + */ + public static Geometry createGeometry(String wkt) { + + if (wkt == null || wkt.equals("")) + return null; + + WKTReader reader = new WKTReader(); + Geometry geometry; + try { + geometry = reader.read(wkt); + if (geometry != null) { + return geometry; + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + // BaseToast.makeText(context, "初始化任务失败!!!", Toast.LENGTH_SHORT).show(); + } + return null; + } + + /* + * 创建多边形几何 + * + * @param Coordinate [] + * @return Geometry + */ + public static String createPolygon(Coordinate[] coords) { + GeometryFactory factory = new GeometryFactory(); + + Polygon gon = factory.createPolygon(coords); + + if (gon == null) + return null; + return gon.toString(); + } + + /* + * 创建多边形几何 + * @param LatLngList + * @return Polygon + */ + public static Polygon createPolygon(List<LatLng> LatLngList) { + if (LatLngList != null && LatLngList.size() >= 3) { + Coordinate[] coordinates = new Coordinate[LatLngList.size()]; + for (int i = 0; i < LatLngList.size(); i++) { + coordinates[i] = new Coordinate(LatLngList.get(i).getLongitude(), LatLngList.get(i).getLatitude()); + } + GeometryFactory factory = new GeometryFactory(); + return factory.createPolygon(coordinates); + } + return null; + } + + /* + * 创建线 + * @param coords [] + * @return Geometry + * */ + /* + public String createLineString(Coordinate[] coords) { + LineString lineString = null; + GeometryFactory factory = new GeometryFactory(); + lineString = factory.createLineString(coords); + return lineString.toString(); + }*/ + + /* + * 创建线 + * @param coords [] + * @return Geometry + */ + public LineString createLineString(Coordinate[] coords) { + LineString lineString = null; + GeometryFactory factory = new GeometryFactory(); + lineString = factory.createLineString(coords); + return lineString; + } + + /** + * 创建点 + */ + public org.locationtech.jts.geom.Point createPoint(Coordinate chord) { + org.locationtech.jts.geom.Point point = null; + GeometryFactory factory = new GeometryFactory(); + point = factory.createPoint(chord); + return point; + } + + + /** + * 点几何转换为LatLng + * + * @param geometry POINT (116.4087300000000056 39.9392050000000012) + * @return LatLng + */ + public static LatLng createLatLng(String geometry) { + + if (geometry == null || geometry.equals("")) + return null; + WKTReader reader = new WKTReader(); + Geometry geometers; + try { + geometers = reader.read(geometry); + if (geometers != null) { + org.locationtech.jts.geom.Point point = geometers.getInteriorPoint(); + LatLng geoInteriorPoint = new LatLng(point.getY(), point.getX()); + if (geometers.getGeometryType().equalsIgnoreCase("Point")) { + Coordinate coordinate = geometers.getCoordinate(); + return new LatLng(coordinate.y, coordinate.x); + } else if (geometers.getGeometryType().equalsIgnoreCase("LineString") || geometers.getGeometryType().equalsIgnoreCase("MultiLineString")) { + Coordinate[] coordinates = geometers.getCoordinates(); + if (coordinates != null && coordinates.length > 0) { + return new LatLng(coordinates[0].y, coordinates[0].x); + } else { + return geoInteriorPoint; + } + } else { + return geoInteriorPoint; + } + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + // BaseToast.makeText(context, "初始化任务失败!!!", Toast.LENGTH_SHORT).show(); + } + return null; + } + + /* + * 计算两点距离 + * @param startLatLng + * @param endLatLng + * @return double:单位 米 + */ + public static double distanceToDouble(LatLng startLatLng, LatLng endLatLng) { + if (startLatLng != null && endLatLng != null) { + Geometry startGeo = createGeometry(startLatLng); + Geometry endGeo = createGeometry(endLatLng); + double d = startGeo.distance(endGeo); + return d * 100000; + } + return 0; + } + + public static LatLng getLineStringCenter(String lineString) { + List<LatLng> points = getLatLags(lineString); + return getLineStringCenter(points); + } + + public static LatLng getLineStringCenter(List<LatLng> points) { + if (points != null && points.size() > 1) { + if (points.size() == 2) { + double x1 = points.get(0).getLongitude(); + double y1 = points.get(0).getLatitude(); + double x2 = points.get(1).getLongitude(); + double y2 = points.get(1).getLatitude(); + return new LatLng((y1 + y2) / 2, (x1 + x2) / 2); + } else { + double total = 0; + ArrayList<Double> dList = new ArrayList<Double>(); + for (int i = 0; i < points.size() - 1; i++) { + double lt = total; + double dis = distanceToDouble(points.get(i), points.get(i + 1)); + dList.add(lt + dis); + total += dis; + } + Log.e("jingo", "line lengh =" + total); + total = total / 2; + for (int i = 0; i < dList.size(); i++) { + double a = dList.get(i); + double b = 0; + if (i > 0) { + b = dList.get(i - 1); + } + if (a > total) { + if (a - total < 4) { + return points.get(i); + } + double dx = (a - total) * 0.5 / (a - b); + LatLng point1 = points.get(i); + LatLng point2 = points.get(i + 1); + double x; + if (point1.getLongitude() < point2.getLongitude()) { + x = (point2.getLongitude() - point1.getLongitude()) * dx; + x = point2.getLongitude() - x; + } else { + x = (point1.getLongitude() - point2.getLongitude()) * dx; + x = point2.getLongitude() + x; + } + double y; + if (point1.getLatitude() > point2.getLatitude()) { + y = (point1.getLatitude() - point2.getLatitude()) * dx; + y = point2.getLatitude() + y; + } else { + y = (point2.getLatitude() - point1.getLatitude()) * dx; + y = point2.getLatitude() - y; + } + return new LatLng(y, x); + } else { + if (total - a < 4) { + return points.get(i + 1); + } + } + } + } + } + return null; + } + + public static LatLng getLineStringCenter(List<LatLng> points, int[] index) { + if (points != null && points.size() > 1) { + if (points.size() == 2) { + double x1 = points.get(0).getLongitude(); + double y1 = points.get(0).getLatitude(); + double x2 = points.get(1).getLongitude(); + double y2 = points.get(1).getLatitude(); + LatLng newPoint = new LatLng((y1 + y2) / 2, (x1 + x2) / 2); + if (index != null && index.length > 1) { + index[0] = 0; + index[1] = 1; + } + return newPoint; + } else { + double total = 0; + ArrayList<Double> dList = new ArrayList<Double>(); + for (int i = 0; i < points.size() - 1; i++) { + double lt = total; + double dis = distance(points.get(i).toString(), points.get(i + 1).toString()); + dList.add(lt + dis); + total += dis; + } + Log.e("jingo", "line lengh =" + total); + total = total / 2; + for (int i = 0; i < dList.size(); i++) { + double a = dList.get(i); + double b = 0; + if (i > 0) { + b = dList.get(i - 1); + } + if (a > total) { + if (a - total < 4) { + if (index != null && index.length > 1) { + index[0] = i; + index[1] = i + 1; + } + return points.get(i); + } + double dx = (a - total) * 0.5 / (a - b); + LatLng point1 = points.get(i); + LatLng point2 = points.get(i + 1); + double x; + if (point1.getLongitude() < point2.getLongitude()) { + x = (point2.getLongitude() - point1.getLongitude()) * dx; + x = point2.getLongitude() - x; + } else { + x = (point1.getLongitude() - point2.getLongitude()) * dx; + x = point2.getLongitude() + x; + } + double y; + if (point1.getLatitude() > point2.getLatitude()) { + y = (point1.getLatitude() - point2.getLatitude()) * dx; + y = point2.getLatitude() + y; + } else { + y = (point2.getLatitude() - point1.getLatitude()) * dx; + y = point2.getLatitude() - y; + } + LatLng LatLng = new LatLng(y, x); + if (index != null && index.length > 1) { + index[0] = i; + index[1] = i + 1; + } + return LatLng; + } else { + if (total - a < 4) { + if (index != null && index.length > 1) { + index[0] = i; + index[1] = i + 1; + } + return points.get(i + 1); + } + } + } + } + } + return null; + } + + /** + * LINESTRING (116.4206899999999933 39.9620999999999995, + * 116.4184900000000056 39.9620600000000010) + * @param str s + * @return list<LatLng> + */ + public static List<LatLng> getLatLags(String str) { + if (isEmpty(str)) + return null; + List<LatLng> list = null; + Geometry geometry = createGeometry(str); + if (geometry != null) { + Coordinate[] coordinates = geometry.getCoordinates(); + if (coordinates != null && coordinates.length > 0) { + list = new ArrayList<>(); + for (Coordinate color : coordinates) { + list.add(new LatLng(color.y, color.x)); + } + } + } + return list; + } + + public static List<LatLng> getLatList(Geometry geo){ + List<LatLng> list = null; + Coordinate[] coordinates = geo.getCoordinates(); + if (coordinates != null && coordinates.length > 0) { + list = new ArrayList<>(); + for (Coordinate color : coordinates) { + list.add(new LatLng(color.y, color.x)); + } + } + return list; + } + + + + + public static Coordinate[] getLatLngs2(String str) { + Coordinate[] coordinates = null; + if (str == null || str.trim().equals("")) + return coordinates; + Geometry geometry = createGeometry(str); + if (geometry != null) { + coordinates = geometry.getCoordinates(); + } + return coordinates; + } + + public static String getLineString(List<LatLng> list) { + if (list != null && list.size() > 1) { + int size = list.size(); + Coordinate[] coors = new Coordinate[size]; + for (int i = 0; i < size; i++) { + LatLng gp = list.get(i); + coors[i] = new Coordinate(gp.getLongitude(), gp.getLatitude()); + } + GeometryFactory factory = new GeometryFactory(); + Geometry geo = factory.createLineString(coors); + if (geo != null) + return geo.toString(); + } + return null; + } + + public static String getLineStringNoDouble5(List<LatLng> list) { + + if (list != null && list.size() > 1) { + int size = list.size(); + Coordinate[] coors = new Coordinate[size]; + for (int i = 0; i < size; i++) { + LatLng gp = list.get(i); + coors[i] = new Coordinate(gp.getLongitude(), gp.getLatitude()); + } + GeometryFactory factory = new GeometryFactory(); + Geometry geo = factory.createLineString(coors); + if (geo != null) + return geo.toString(); + } + return null; + } + + /* + * 获取线型 + * @param list + * @return + */ + public static LineString getLineStainGeo(List<LatLng> list) { + + if (list != null && list.size() > 1) { + int size = list.size(); + Coordinate[] coors = new Coordinate[size]; + for (int i = 0; i < size; i++) { + LatLng gp = list.get(i); + coors[i] = new Coordinate(gp.getLongitude(), gp.getLatitude()); + } + return getLineStrinGeo(coors); + } + return null; + } + + /* + * 获取线型 + * @param list + * @return + */ + public static LineString getLineStringByPointList(List<org.locationtech.jts.geom.Point> list) { + + if (list != null && list.size() > 1) { + int size = list.size(); + Coordinate[] coors = new Coordinate[size]; + for (int i = 0; i < size; i++) { + org.locationtech.jts.geom.Point point = list.get(i); + coors[i] = new Coordinate(point.getX(), point.getY()); + } + return getLineStrinGeo(coors); + } + return null; + } + /* + * 获取线型 + * @param list + * @return + */ + public static LineString getLineStringByMyCoordinate(List<MyCoordinate> list) { + + if (list != null && list.size() > 1) { + int size = list.size(); + Coordinate[] coors = new Coordinate[size]; + for (int i = 0; i < size; i++) { + coors[i] = new Coordinate(list.get(i).getX(), list.get(i).getY()); + } + return getLineStrinGeo(coors); + } + return null; + } + + /* + * 获取线型 + * @param coors + * @return + */ + public static LineString getLineStrinGeo(Coordinate[] coors) { + + if (coors != null && coors.length > 1) { + GeometryFactory factory = new GeometryFactory(); + return factory.createLineString(coors); + } + return null; + } + + /** + * 获取线型的外扩矩形 + * + * @param list l + * @return h + */ + public static Polygon getPolygonEnvelope(List<LatLng> list) { + LineString lineString = getLineStainGeo(list); + if (lineString != null) { + Geometry geometry = lineString.getEnvelope(); + if (geometry != null && geometry.getGeometryType().equals("Polygon")) { + return (Polygon) geometry; + } + } + return null; + + } + + public static String getPolygonString(List<LatLng> list) { + if (list != null && list.size() > 2) { + LatLng first = list.get(0); + LatLng last = list.get(list.size() - 1); + if (first.getLongitude() != last.getLongitude() || first.getLatitude() != last.getLatitude()) { + return null; + } + Coordinate[] coors = new Coordinate[list.size()]; + for (int i = 0; i < list.size(); i++) { + LatLng gp = list.get(i); + coors[i] = new Coordinate(gp.getLongitude(), gp.getLatitude()); + } + GeometryFactory factory = new GeometryFactory(); + Geometry geo = factory.createPolygon(coors); + if (geo != null) + return geo.toString(); + } + + return null; + + } + + public static String getMultiLineString(List<List<LatLng>> list) { + if (list != null && !list.isEmpty()) { + StringBuilder result = new StringBuilder(); + result.append("MULTILINESTRING("); + for (int i = 0; i < list.size(); ++i) { + List<LatLng> pointList = list.get(i); + if (pointList != null && !pointList.isEmpty()) { + result.append("("); + for (int j = 0; j < pointList.size(); ++j) { + result.append(pointList.get(j).getLongitude()); + result.append(" "); + result.append(pointList.get(j).getLatitude()); + if (j == pointList.size() - 1) { + result.append(")"); + } else { + result.append(","); + } + } + if (i != list.size() - 1) { + result.append(","); + } + } + } + result.append(")"); + return result.toString(); + } + return null; + } + + public static List<List<LatLng>> getLatLngArrFromMultiLineString(String multiLintString) { + if (isEmpty(multiLintString)) + return null; + multiLintString = multiLintString.substring(multiLintString.indexOf("(") + 1, + multiLintString.length() - 1); + if (!isEmpty(multiLintString)) { + List<List<LatLng>> resultList = new ArrayList<List<LatLng>>(); + while (!isEmpty(multiLintString)) { + int startIndex = multiLintString.indexOf("("); + int endIndex = multiLintString.indexOf(")"); + if (startIndex < endIndex) { + endIndex++; + String geometry = multiLintString.substring(startIndex, endIndex); + if (isEmpty(geometry)) + continue; + if (geometry.startsWith("(")) { + geometry = geometry.substring(1, geometry.length()); + } + if (geometry.endsWith(")")) { + geometry = geometry.substring(0, geometry.length() - 1); + } + String points[] = geometry.split(","); + List<LatLng> list = new ArrayList<LatLng>(); + for (int i = 0; i < points.length; i++) { + String point[] = points[i].trim().split(" "); + if (point.length == 2) { + list.add(new LatLng(Double.parseDouble(point[1].trim()), Double.parseDouble(point[0].trim()))); + } + } + if (list != null && !list.isEmpty()) { + resultList.add(list); + } + multiLintString = multiLintString.substring(endIndex); + } + } + if (!resultList.isEmpty()) { + return resultList; + } + } + + return null; + } + + + public Geometry focalPoint(Geometry geo1, Geometry geo2) { + if (geo1 == null || geo2 == null) + return null; + + Geometry geo = geo1.intersection(geo2); + Log.i("geo", geo.toString() + "===1"); + geo = geo1.union(geo2); + Log.i("geo", geo.toString() + "===2"); + geo = geo1.symDifference(geo2); + Log.i("geo", geo.toString() + "===3"); + return null; + } + + /* + * 角度变换 + * + * @param angle + * @return angle; + */ + public double angleSwap(double angle) { + if (angle >= 180) + angle = angle - 180; + else + angle = angle + 180; + angle = formatDouble5(angle); + return angle; + } + + /* + * 是否第一个点 + * + * @param lineString + * @param point + * @return boolean; + */ + public boolean isFirstPoint(String lineString, String point) { + if (isEmpty(lineString) || isEmpty(point)) + return false; + + Geometry lineGeo = createGeometry(lineString); + + Geometry pGeo = createGeometry(point); + + if (lineGeo != null && lineGeo.getGeometryType().equals("LineString") && pGeo != null && pGeo.getGeometryType().equals("Point")) { + Coordinate[] coords = lineGeo.getCoordinates(); + if (coords.length > 0) { + if (coords[0].x == pGeo.getCoordinate().x && coords[0].y == pGeo.getCoordinate().y) + return true; + } + } + + return false; + } + + /* + * 是否最后点 + * + * @param lineString + * @param point + * @return boolean; + */ + public boolean isEndPoint(String lineString, String point) { + + if (isEmpty(lineString) || isEmpty(point)) + return false; + + Geometry lineGeo = createGeometry(lineString); + + Geometry pGeo = createGeometry(point); + + if (lineGeo != null && lineGeo.getGeometryType().equals("LineString") && pGeo != null && pGeo.getGeometryType().equals("Point")) { + Coordinate[] coords = lineGeo.getCoordinates(); + if (coords.length > 0) { + if (coords[coords.length - 1].x == pGeo.getCoordinate().x && coords[coords.length - 1].y == pGeo.getCoordinate().y) + return true; + } + } + return false; + + } + + /** + * 是否起点或终点 + * + * @param lineString + * @param point + * @return boolean; + */ + public boolean isFirstOrEndPoint(String lineString, String point) { + + + if (isEmpty(lineString) ||isEmpty(point)) + return false; + Geometry lineGeo = createGeometry(lineString); + + Geometry pGeo = createGeometry(point); + + if (lineGeo != null && lineGeo.getGeometryType().equals("LineString") && pGeo != null && pGeo.getGeometryType().equals("Point")) { + Coordinate[] chords = lineGeo.getCoordinates(); + if (chords.length > 0) { + + if (chords[chords.length - 1].x == pGeo.getCoordinate().x && chords[chords.length - 1].y == pGeo.getCoordinate().y) + return true; + + if (chords[chords.length - 1].x == pGeo.getCoordinate().x && chords[chords.length - 1].y == pGeo.getCoordinate().y) + return true; + } + } + + return false; + + } + + /** + * 判断捕捉集合中是否包含传入的点位信息 + * @param geoList geo + * @return int; + */ + public int isListContain(List<LatLng> geoList, LatLng mLatLng) { + + if (geoList != null && geoList.size() > 0 && mLatLng != null) { + for (int i = 0; i < geoList.size(); i++) { + if (geoList.get(i).equals(mLatLng)) { + return i; + } + } + } + + return -1; + } + + + public int LocatePointInPath(List<LatLng> list, LatLng point) { + int index = -1; + + if (list == null || list.size() < 2 || point == null) { + return index; + } +// createPolygon(getEnvelope(new LatLng(formatDouble5(point.getLongitude()), formatDouble5(point.getLatitude())), 6, 2)) + Geometry geomerty = createGeometry(point); + + Coordinate[] coods = new Coordinate[2]; + HashMap<Integer, Double> distance = new HashMap<Integer, Double>(); + //遍历线节点,判断垂足在哪个线段上,并将垂足插入 + for (int i = 0; i < list.size(); i++) { + if (i != list.size() - 1) { + + coods[0] = new Coordinate(list.get(i).getLongitude(), list.get(i).getLatitude()); + + coods[1] = new Coordinate(list.get(i + 1).getLongitude(), list.get(i + 1).getLatitude()); + + LineString line = createLineString(coods); + + double dou = line.distance(geomerty); + distance.put(i, dou); + } + } + double temp = distance.get(0); + for (int i = 1; i < distance.size(); i++) { + if (temp > distance.get(i)) { + temp = distance.get(i); + } + } + for (int i = 0; i < distance.size(); i++) { + if (temp == distance.get(i)) { + return i; + } + } + return index; + } + + + //是否是相交面 + public static boolean isSimplePolygon(List<LatLng> list) { + + if (list != null && list.size() > 0) { + Geometry polygon = createGeometry(getPolygonString(list)); + if (polygon != null) { + return polygon.isSimple(); + } + } + + return false; + } + + /** + * @param list list + * @param endPoint point + * @return boolean + */ + public static boolean isSimplePolygon(List<Point> list, Point endPoint) { + if (list != null && list.size() > 0) { + if (list != null && list.size() > 2) { + Point frist = list.get(0); + Point last = list.get(list.size() - 1); + if (frist.x != last.x || frist.y != last.y) { + return false; + } + int size = list.size(); + if (endPoint != null) { + size++; + } + Coordinate[] coors = new Coordinate[size]; + for (int i = 0; i < list.size(); i++) { + Point gp = list.get(i); + coors[i] = new Coordinate(gp.x, gp.y); + } + if (endPoint != null) { + coors[coors.length - 1] = coors[coors.length - 2]; + coors[coors.length - 2] = new Coordinate(endPoint.x, endPoint.y); + } + GeometryFactory factory = new GeometryFactory(); + Geometry geo = factory.createPolygon(coors); + if (geo != null) { + return geo.isSimple(); + } + } + } + return false; + } + + /** + * 小数点后四舍五入 精确到第5位 + * + * @param d + * @return + */ + private double formatDouble5(double d) { + BigDecimal bg = new BigDecimal(d); + double f1 = bg.setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue(); + return f1; + } + + /** + * 是否包含点 + * + * @param //List<String> wkts + * @param //LatLng LatLng + * @return int + */ + public int isContainsGeo(List<String> wkts, LatLng LatLng) { + if (wkts == null || wkts.size() == 0 || LatLng == null) { + return -1; + } + org.locationtech.jts.geom.Point point = createPoint(new Coordinate(LatLng.getLongitude(), LatLng.getLatitude())); + for (int i = 0; i < wkts.size(); i++) { + Geometry geometry = createGeometry(wkts.get(i)); + if (geometry != null && geometry.getGeometryType().equals("Polygon")) { + Polygon polygon = (Polygon) geometry; + boolean result = geometry.contains(point); + if (result) + return i; + } + } + return -1; + } + + + public static List<LatLng> getLineIntersectionLatLng(LineString lineString) { + if (lineString != null) { + Coordinate[] coords = lineString.getCoordinates(); + List<LineString> list = new ArrayList<LineString>(); + GeometryFactory factory = new GeometryFactory(); + for (int i = 0; i < coords.length; i++) { + if (i != coords.length - 1) { + Coordinate[] coord = new Coordinate[2]; + coord[0] = coords[i]; + coord[1] = coords[i + 1]; + LineString line = factory.createLineString(coord); + if (line != null) + list.add(line); + } + } + List<LatLng> listLatLng = new ArrayList<LatLng>(); + if (list != null && list.size() > 0) { + for (int i = 0; i < list.size(); i++) { + LineString line1 = list.get(i); + for (int j = 0; j < list.size(); j++) { + if (i != j) { + LineString line2 = list.get(j); + Geometry geometry = line1.intersection(line2); + if (geometry != null && !geometry.isEmpty() && geometry.getGeometryType().equalsIgnoreCase("Point")) { + if (!line2.getStartPoint().equals(geometry) && !line2.getEndPoint().equals(geometry)) { + listLatLng.add(new LatLng(geometry.getCoordinate().y, geometry.getCoordinate().x)); + } + } + } + } + } + } + if (listLatLng != null && listLatLng.size() > 0) { + return listLatLng; + } + } + return null; + } + + /** + * 点与几何最近点位置 + * + * @param list + * @param LatLng + * @return LatLng + * @author qiji + */ + public static LatLng getZuijinLatLng(List<LatLng> list, LatLng LatLng) {//MapManager.getInstance().getMap().getMapCenterGeoLocation()屏幕中心点 + if (list == null || list.size() == 0 || LatLng == null) + return null; + double dis = 0; + LatLng geo = null; + for (LatLng latLng : list) { + double disTemp = distanceToDouble(latLng, latLng); + if (dis == 0 || dis < disTemp) { + dis = disTemp; + geo = LatLng; + } + } + return geo; + } + + public static String GeometryFormatDouble5(String geometry) { + try { + LatLng point = createLatLng(geometry); + return createGeometry(point).toString(); + } catch (Exception e) { + e.getLocalizedMessage(); + } + return ""; + } + + + public static double distance(String geo1, String geo2) { + if (isEmpty(geo1)||isEmpty(geo2)) { + return -1; + } + Geometry mGeo = createGeometry(geo1); + + Geometry mGeo2 = createGeometry(geo2); + + if (mGeo != null && mGeo2 != null) { + + return mGeo.distance(mGeo2); + } + return -1; + } + + + public enum SNAP_TYPE { + SNAP_PIXEL, SNAP_METER; + } + + + //经纬度转墨卡托 + public static LatLng lonLat2Mercator(LatLng lonLat) { + + double x = lonLat.getLongitude() * 20037508.34 / 180; + double y = Math.log(Math.tan((90 + lonLat.getLatitude()) * Math.PI / 360)) / (Math.PI / 180); + y = y * 20037508.34 / 180; + LatLng mercator = new LatLng(y, x); + return mercator; + } + + //墨卡托转经纬度 + public static LatLng Mercator2lonLat(LatLng mercator) { + + double x = mercator.getLongitude() / 20037508.34 * 180; + double y = mercator.getLatitude() / 20037508.34 * 180; + y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2); + LatLng lonLat = new LatLng(y, x); + return lonLat; + } + + public static boolean isCheckError(double lon, double lat) { +/* if(lon==0&&lat==0){ + return true; + }*/ + + if (lon > 180 || lon < -180 || lat > 90 || lat < -90) { + return true; + } + return false; + } + + + /** + * @param isFormatDouble5 是否只保留小数点后5位 + * @return + */ + public static Geometry getPolygonGeometry(List<LatLng> mArrLatLng, boolean isFormatDouble5) { + if (mArrLatLng != null && mArrLatLng.size() > 0) { + + if (mArrLatLng != null && mArrLatLng.size() > 0) { + Coordinate[] coordinates = new Coordinate[mArrLatLng.size()]; + for (int i = 0; i < mArrLatLng.size(); i++) { + Coordinate coordinate = null; + if (isFormatDouble5) + coordinate = new Coordinate(mArrLatLng.get(i).getLongitude(), mArrLatLng.get(i).getLatitude()); + else + coordinate = new Coordinate(mArrLatLng.get(i).getLongitude(), mArrLatLng.get(i).getLatitude()); + coordinates[i] = coordinate; + } + return getPolygonGeometry(coordinates); + } + + } + return null; + } + + /** + * @return + */ + public static Geometry getPolygonGeometry(Coordinate[] coordinates) { + if (coordinates!=null&&coordinates.length>0) { + GeometryFactory factory = new GeometryFactory(); + Polygon polygon = factory.createPolygon(coordinates); + if (polygon != null) + return polygon; + } + return null; + } + +// public static String getGeoJsonStr(Geometry geometry) throws ParseException { +// GeoJSON geoJSONObject = geoJsonWriter.write(wktReader.read(geometry.toString())); +// return geoJSONObject.toString(); +// } + + +// /** +// * 经纬度转WEB墨卡托 +// * @param geom +// * @return +// */ +// public static Geometry lonlat2WebMactor(Geometry geom){ +// try{ +// //这里是以OGC WKT形式定义的是World Mercator投影,网页地图一般使用该投影 +// //CoordinateReferenceSystem crsTarget = CRS.parseWKT(strWKTMercator); +//// CoordinateReferenceSystem crsTarget = CRS.decode("EPSG:3857"); +// // 这里是以OGC WKT形式定义的是World Mercator投影,网页地图一般使用该投影 +// final String strWKTMercator = "PROJCS[\"World_Mercator\"," +// + "GEOGCS[\"GCS_WGS_1984\"," +// + "DATUM[\"WGS_1984\"," +// + "SPHEROID[\"WGS_1984\",6378137,298.257223563]]," +// + "PRIMEM[\"Greenwich\",0]," +// + "UNIT[\"Degree\",0.017453292519943295]]," +// + "PROJECTION[\"Mercator_1SP\"]," +// + "PARAMETER[\"False_Easting\",0]," +// + "PARAMETER[\"False_Northing\",0]," +// + "PARAMETER[\"Central_Meridian\",0]," +// + "PARAMETER[\"latitude_of_origin\",0]," +// + "UNIT[\"Meter\",1]]"; +// CoordinateReferenceSystem mercatroCRS = CRS.parseWKT(strWKTMercator); +// +// // 投影转换 +// MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, mercatroCRS); +// return JTS.transform(geom, transform); +// } +// catch (Exception e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// return null; +// } +// } + + private static boolean isEmpty(String str) { + return str == null || str.trim().equals(""); + } + + /** + * 根据geometry的string生成PoiEntity的代表点经纬度x和y + * */ + public static void obitainPoiEntityXY(String geo, PoiEntity poiEntity) { + Geometry geometry = GeometryTools.createGeometry(geo); + switch (geometry.getGeometryType()) { + case "Point": //点 + LatLng lng = GeometryTools.createLatLng(geo); + poiEntity.setX(lng.longitude + ""); + poiEntity.setY(lng.latitude + ""); + break; + case "LineString": //线 + case "MultiLineString": // 多线 + case "Polygon": //面 + case "MultiPolygon": //多面 + case "MultiPoint": //多点 + List<LatLng> latLineString = GeometryTools.getLatLags(geo); + assert latLineString != null; + poiEntity.setX(latLineString.get(0).longitude + ""); + poiEntity.setY(latLineString.get(0).latitude + ""); + break; + } + } + +}