From d830315c6b7098d3b7e2f28c6891c3514d9ba16a Mon Sep 17 00:00:00 2001 From: xiaoyan-5800X Date: Fri, 25 Nov 2022 17:34:46 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- .../activity/AutoTakePictureActivity.java | 258 +++++++++++------- .../navinfo/outdoor/bean/RoadMatchEntity.java | 9 + .../outdoor/fragment/RoadFragment.java | 18 +- .../navinfo/outdoor/http/HttpInterface.java | 4 +- .../main/res/drawable/selector_direction.xml | 14 + .../drawable/selector_picture_map_change.xml | 14 + .../layout/activity_auto_take_pictures.xml | 28 +- .../main/res/layout/fragment_gather_get.xml | 1 + app/src/main/res/layout/treasure_fragment.xml | 1 + app/src/main/res/mipmap-xxhdpi/direction.png | Bin 0 -> 2747 bytes .../res/mipmap-xxhdpi/direction_press.png | Bin 0 -> 2741 bytes app/src/main/res/mipmap-xxhdpi/exchange.png | Bin 0 -> 2557 bytes .../main/res/mipmap-xxhdpi/exchange_press.png | Bin 0 -> 3152 bytes 14 files changed, 233 insertions(+), 118 deletions(-) create mode 100644 app/src/main/res/drawable/selector_direction.xml create mode 100644 app/src/main/res/drawable/selector_picture_map_change.xml create mode 100644 app/src/main/res/mipmap-xxhdpi/direction.png create mode 100644 app/src/main/res/mipmap-xxhdpi/direction_press.png create mode 100644 app/src/main/res/mipmap-xxhdpi/exchange.png create mode 100644 app/src/main/res/mipmap-xxhdpi/exchange_press.png diff --git a/app/build.gradle b/app/build.gradle index deefe1c..2dfe5be 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { applicationId "com.navinfo.outdoor" minSdkVersion 23 targetSdkVersion 30 - versionCode 31 - versionName "8.221118" + versionCode 32 + versionName "8.221125" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } lintOptions { diff --git a/app/src/main/java/com/navinfo/outdoor/activity/AutoTakePictureActivity.java b/app/src/main/java/com/navinfo/outdoor/activity/AutoTakePictureActivity.java index ebe9b95..99a439f 100644 --- a/app/src/main/java/com/navinfo/outdoor/activity/AutoTakePictureActivity.java +++ b/app/src/main/java/com/navinfo/outdoor/activity/AutoTakePictureActivity.java @@ -17,6 +17,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.DisplayMetrics; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.Window; @@ -214,10 +215,11 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic private Switch locationSwitch; private boolean locationEnable=true; private ImageView imgViewSettingHook; // 调起隐藏设置的按钮 - private TencentLocation oldCurrentLocation = null; + private Point oldCurrentLocation = null; // 记录上一次的位置信息 private MediaPlayer mediaPlayer; - private ImageView imgNaviDistance; // 自动规划到距离最近的数据开关 + private ImageView imgNaviDistance/*自动规划到距离最近的数据开关*/, imgRoadDirection; // 道路方向匹配开关 private Polyline currentNaviLine; // 当前界面上正显示的导航路径线,重绘路径时需要清除此前已绘制的路径 + private boolean startMatchEnableDirection = false; // 是否启用方向匹配起点 @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -268,6 +270,7 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic btnClearMatch = findViewById(R.id.clear_all_match_data); btnStopPicture = findViewById(R.id.btn_stop_picture); imgNaviDistance = findViewById(R.id.img_navi_distance); + imgRoadDirection = findViewById(R.id.img_road_direction); //获取地图 tencentMap = tvMapView.getMap(); @@ -278,6 +281,8 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic uiSettings.setRotateGesturesEnabled(false);//禁止地图旋转手势. uiSettings.setTiltGesturesEnabled(false);//禁止倾斜手势. setLocMarkerStyle(LOCATION_TYPE_LOCATION_ROTATE); + tencentMap.setLocationSource(new MyTecentLocationSource(this)); + tencentMap.setMyLocationEnabled(true); DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); FrameLayout.LayoutParams layoutParamsMap = (FrameLayout.LayoutParams) tvMapView.getLayoutParams();//相机的宽高 @@ -443,6 +448,14 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic } } }); + + imgRoadDirection.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + view.setSelected(!view.isSelected()); + startMatchEnableDirection = view.isSelected(); + } + }); } private long lastClickTime = 0; private int settingHookClickCount = 1; @@ -507,9 +520,7 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic @Override public boolean onDown(float v, float v1) { - if (isMapSlide) { - setLocMarkerStyle(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER); - } + setLocMarkerStyle(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER); return false; } @@ -589,13 +600,13 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic SharedPreferences spf = getSharedPreferences("MatchEntity", Context.MODE_PRIVATE); Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create(); - String matchedData = spf.getString("data", null); + String matchedData = spf.getString("match-data", null); if (matchedData!=null) { List dataList = gson.fromJson(matchedData, new TypeToken>(){}.getType()); roadMatchEntityList.addAll(dataList); } // 清空缓存数据 - spf.edit().remove("data"); + spf.edit().remove("match-data"); spf.edit().commit(); } @@ -632,10 +643,26 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic 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))); + // 获取当前数据的前两个点的方向 + Coordinate[] coordinates = lineString.getCoordinates(); + // 循环取出当前数据的坐标点,为防止出现重复点,需要循环做判断 + Coordinate[] lineCoordinates = new Coordinate[2]; + lineCoordinates[0] = coordinates[0]; + lineCoordinates[1] = coordinates[0]; + for (Coordinate c: coordinates) { + if (c.x!=lineCoordinates[0].x&&c.y!=lineCoordinates[0].y) { + lineCoordinates[1] = c; + break; + } + } + if (lineCoordinates[0]!=lineCoordinates[1]) { + double dataBearing = getBearing(lineCoordinates[0].x, lineCoordinates[1].x, lineCoordinates[0].y, lineCoordinates[1].y); + roadMatchEntity.setAngle(dataBearing); + } roadMatchEntity.setsPoint(lineString.getStartPoint().toString()); roadMatchEntity.setePoint(lineString.getEndPoint().toString()); } @@ -679,24 +706,39 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic /** * 开始自动匹配 * */ + private double minDistance = MATCH_START_BUFFER_DISTANCE; // 最小距离,需要在匹配过程点时判断哪个任务是距离最小的 private void startMatchRoadLink(Point currentPoint) { if (roadLinkEntityList == null/*没有需要匹配的道路数据*/ || currentPoint == null/*没有位置信息*/) { return; } - float currentSpeed = getSpeed(); - double matchStartDistance = MATCH_BUFFER_DISTANCE; + double[] speedAndBearing = getSpeedAndBearing(currentPoint); + double currentSpeed = speedAndBearing[0]; // 当前速度 + double currentBearing = speedAndBearing[1]; // 当前方向 + double matchMiddleDistance = MATCH_BUFFER_DISTANCE; // 如果速度大于70,则动态调整起点捕捉范围 if (currentSpeed>=70) { - matchStartDistance = MATCH_BUFFER_DISTANCE*1.5; + matchMiddleDistance = MATCH_BUFFER_DISTANCE*1.5; } // 此处开始匹配起点 List matchStartList = roadLinkEntityList.stream() + // 筛选当前任务与起点距离 .filter(it-> GeometryTools.createGeometry(it.getsPoint()).distance(currentPoint) { + if (startMatchEnableDirection) { + double dataBearing = it.getAngle(); + if (currentBearing!=0&&(Math.abs(dataBearing-currentBearing)<=90 || Math.abs(dataBearing-currentBearing)>=270)) { + return true; + } + return false; + } else { + return true; + } + }) + // 判断筛选出的数据是否已经在匹配列表中,如果不存在,需要自动领取该任务、记录开始采集时间 + .filter( + o -> roadMatchEntityList.stream().noneMatch(roadMatchEntity -> o.getId()==roadMatchEntity.getId())) .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( @@ -723,37 +765,47 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic } // 尝试用当前位置点匹配已经匹配到的roadLink,如果能匹配到,需要将该点记录,如果无法匹配,则需要评估已匹配的link是否需要被剔除 + minDistance = MATCH_START_BUFFER_DISTANCE; // 使用距离起终点的最大阈值初始化最小距离 if (!roadMatchEntityList.isEmpty()) { // 因为单个点位只能匹配一条任务,需要获取当前点位距离所有任务最近的距离 - roadMatchEntityList.stream().forEach(it->it.setCurrentLineDistance(GeometryTools.createGeometry(it.getGeometry()).distance(currentPoint))); - // 筛选出本次距离最近的线 - RoadMatchEntity minRoadMatchEntity = roadMatchEntityList.stream().min((o1, o2)-> { - if (o1.getCurrentLineDistance(){ + double currentDistance = GeometryTools.createGeometry(it.getGeometry()).distance(currentPoint); + it.setCurrentLineDistance(currentDistance); + if (currentDistance<=minDistance) { + minDistance = currentDistance; } - }).get(); + }); List unMatchList = new ArrayList<>(); Map finishEntityMap = new HashMap<>(); - double finalMatchStartDistance = matchStartDistance; + double finalMatchMiddleDistance = matchMiddleDistance; roadMatchEntityList.stream().forEach( roadMatchEntity -> { double currentDistance = roadMatchEntity.getCurrentLineDistance(); - boolean isMatch=currentDistance<= finalMatchStartDistance; // 当前点位是否可以和link匹配到 + boolean isMatch=currentDistance<= finalMatchMiddleDistance; // 当前点位是否可以和link匹配到 if (isMatch) { // 可以匹配到 - if (minRoadMatchEntity.getId() == roadMatchEntity.getId()) { // 并且该条数据还是最近的点, 将当前点位匹配到此任务下 - // 可以匹配到,并且是最近的任务,更新任务的开始时间 - if (roadMatchEntity.getMatchPointList().size() == 0) { + if (roadMatchEntity.getCurrentLineDistance()<=minDistance) { // 并且该条数据还是最近的点, 将当前点位匹配到此任务下(注意,当距离完全相等时,同一点位可能同时匹配到多个任务) + if (roadMatchEntity.getMatchPointList().size() == 0) { // 可以匹配到,并且从未匹配过,更新任务的开始时间 roadMatchEntity.setStartMatchTime(System.currentTimeMillis()); } + // 更新连续匹配的个数 roadMatchEntity.setMatchCount(roadMatchEntity.getMatchCount()+1); - roadMatchEntity.setUnMatchCount(0); // 有匹配的数据,则连续未匹配个数归0 + // 匹配到最近的任务,将当前点加入到已匹配道路中 roadMatchEntity.getMatchPointList().add(new MyCoordinate(currentPoint.getX(), currentPoint.getY())); + // 如果连续匹配个数大于1(可以连成线),更新已匹配长度 + if (roadMatchEntity.getMatchCount()>1) { + roadMatchEntity.setMatchedLength( + roadMatchEntity.getMatchedLength() + + + // 加上最后两个点的长度 + GeometryTools.getLineStringByMyCoordinate(roadMatchEntity.getMatchPointList().subList(roadMatchEntity.getMatchPointList().size()-2, roadMatchEntity.getMatchPointList().size())).getLength() + ); + } + } else { // 在阈值内,但是并非最近的点 + roadMatchEntity.setMatchCount(0); // 连续匹配个数置为0 } + roadMatchEntity.setUnMatchCount(0); // 有匹配的数据,则连续未匹配个数归0(即使不是最近的数据,在阈值内即认为可匹配,未匹配点数也置为0) + double currentEndDistance = currentPoint.distance(GeometryTools.createGeometry(roadMatchEntity.getePoint())); // 当前距离终点的距离 // 记录本次的匹配距离,如果本次匹配距离大于上一次,且上一次匹配终点时间不为0(说明已经提前匹配到终点了),则结束匹配,否则继续等待匹配,设置过EndMathchTime的数据即为可以结束匹配的数据,下一次如果未匹配,也可以结束 if (roadMatchEntity.getEndMathchTime()>0/*endMatchTime不为0,说明该数据已经匹配到终点*/&¤tEndDistance>roadMatchEntity.getLastEndDistance()) { @@ -761,17 +813,17 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic // 更新终点时间为距离终点逐渐变大时的时间 roadMatchEntity.setEndMathchTime(System.currentTimeMillis()); } - // 匹配到终点、或匹配距离超过90% - if ((roadMatchEntity.getMatchPointList().size()>=2&&GeometryTools.getLineStringByMyCoordinate(roadMatchEntity.getMatchPointList()).getLength()/roadMatchEntity.getLength()>=MATCH_CONFIRM_FINISH_BUFFER) - || currentEndDistance<= finalMatchStartDistance) { + // 匹配距离超过指定阈值,认为该条数据可完成,记录当前位置与终点的距离,当距离从小变大时,完成该任务 + if (roadMatchEntity.getMatchPointList().size()>=2&&roadMatchEntity.getMatchedLength()/roadMatchEntity.getLength()>=MATCH_CONFIRM_FINISH_BUFFER) { roadMatchEntity.setEndMathchTime(System.currentTimeMillis()); // 匹配到终点后,记录该条数据的最新一次匹配距离,当下一次匹配距离大于当前距离,则认为该数据完全匹配,结束匹配 roadMatchEntity.setLastEndDistance(currentEndDistance); } //=============如果在匹配范围内,但是该数据并非最近的点,不需要记录匹配,也无需增加未匹配点的个数 } else { // 无法匹配 - // 将无法匹配的点位个数记录到对象中 + // 更新连续无法匹配的点位个数 roadMatchEntity.setUnMatchCount(roadMatchEntity.getUnMatchCount()+1); + // 有未匹配的数据,连续匹配个数也归0 roadMatchEntity.setMatchCount(0);// 设置连续匹配的数据个数为0 roadMatchEntity.getUnMatchPointList().add(new MyCoordinate(currentPoint.getX(), currentPoint.getY())); // 当连续未匹配个数大于等于20个时,该任务被认为可以结束(舍弃或完成-需根据匹配到的数据长度与任务长度做对比) @@ -780,7 +832,7 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic if (matchPointList == null || matchPointList.size()<2) { // 已匹配的点位不足2个,无法计算长度,直接放弃该任务 unMatchList.add(roadMatchEntity); } else { - if (GeometryTools.getLineStringByMyCoordinate(matchPointList).getLength()/roadMatchEntity.getLength()>=MATCH_CONFIRM_FINISH_BUFFER) { // 已匹配距离与任务长度距离比例超过指定阈值,该任务可完成 + if (roadMatchEntity.getMatchedLength()/roadMatchEntity.getLength()>=MATCH_CONFIRM_FINISH_BUFFER) { // 已匹配距离与任务长度距离比例超过指定阈值,该任务可完成 roadMatchEntity.setEndMathchTime(System.currentTimeMillis()); finishEntityMap.put(roadMatchEntity.getId(), roadMatchEntity); } else { @@ -788,35 +840,6 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic } } } -// // 该数据未匹配,但是如果此前已经匹配到结束点,则仍然认为匹配成功 -// if (roadMatchEntity.getEndMathchTime()>0) { -// finishEntityMap.put(roadMatchEntity.getId(), roadMatchEntity); -// } else { -// // 判断当前是否存在已匹配的点 -// 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); -// } -// } -// } -// } } } ); @@ -838,22 +861,27 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic } if (!unMatchList.isEmpty()) { - // 过滤需要舍弃的link - for (RoadMatchEntity unMatchEntity: unMatchList) { - roadMatchEntityList.remove(unMatchEntity); - } - cancelReciverTask(unMatchList).subscribe(new Consumer() { + cancelReciverTask(unMatchList).subscribe(new Observer() { @Override - public void accept(PoiEntity poiEntity) throws Exception { + public void onSubscribe(Disposable d) { + // 过滤需要舍弃的link + for (RoadMatchEntity unMatchEntity: unMatchList) { + roadMatchEntityList.remove(unMatchEntity); + } } - }, new Consumer() { + @Override - public void accept(Throwable throwable) throws Exception { - Toast.makeText(AutoTakePictureActivity.this, throwable.getMessage(), Toast.LENGTH_SHORT).show(); + public void onNext(PoiEntity poiEntity) { + } - }, new Action() { + @Override - public void run() throws Exception { + public void onError(Throwable e) { + Toast.makeText(AutoTakePictureActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onComplete() { // 重新刷新地图 initRoadLine2Map(); } @@ -1102,7 +1130,9 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic .token(Constant.ACCESS_TOKEN); Response response = okGoBuilder.getSynchronization(); Gson gson = new Gson(); - TaskByNetBean taskByNetBean = gson.fromJson(response.body().string(), TaskByNetBean.class); + String body = response.body().string(); + TaskByNetBean taskByNetBean = gson.fromJson(body, TaskByNetBean.class); + Log.d("AutoTake:", body); if (taskByNetBean.getCode() == 200) { // 继续保存 TaskByNetBean.BodyBean listBean = taskByNetBean.getBody(); @@ -1382,12 +1412,12 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic case R.id.iv_zoom_add://放大 CameraUpdate cameraUpdateIn = CameraUpdateFactory.zoomIn(); tencentMap.animateCamera(cameraUpdateIn); - setLocMarkerStyle(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER); + setLocMarkerStyle(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER); break; case R.id.iv_zoom_del://缩小 CameraUpdate cameraUpdateOut = CameraUpdateFactory.zoomOut(); tencentMap.animateCamera(cameraUpdateOut); - setLocMarkerStyle(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER); + setLocMarkerStyle(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER); break; case R.id.iv_location://定位: if (Constant.currentLocation != null) { @@ -1420,8 +1450,6 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic /*设置定位图标样式*/ 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); @@ -1432,7 +1460,7 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic locationStyle.fillColor(getResources().getColor(android.R.color.transparent)); locationStyle.strokeWidth(1); tencentMap.setMyLocationStyle(locationStyle); - if (LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER == type) { + if (LOCATION_TYPE_LOCATION_ROTATE == type) { ivLocation.setEnabled(false); } else { ivLocation.setEnabled(true); @@ -1592,7 +1620,7 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic // roadMatchEntity已匹配数据如果存在,缓存 SharedPreferences.Editor editor = getSharedPreferences("MatchEntity", Context.MODE_PRIVATE).edit(); Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create(); - editor.putString("data", gson.toJson(roadMatchEntityList)); + editor.putString("match-data", gson.toJson(roadMatchEntityList)); editor.commit(); } if (gpsUtils!=null) { @@ -1956,7 +1984,7 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic } // 判断当前点位和上一个点位的距离,如果距离过近,忽略该点 Point currentPoint = (Point) GeometryTools.createGeometry(new LatLng(tencentLocation.getLatitude(), tencentLocation.getLongitude())); - if (lastPositionPoint!=null&&lastPositionPoint.distance(currentPoint)0&&y<0)||(x<0&&y<0)){ + angle=angle+180; + } + angle = (angle+720)%360; + return angle; } @Subscribe(threadMode = ThreadMode.MAIN) @@ -2026,17 +2074,17 @@ public class AutoTakePictureActivity extends BaseActivity implements View.OnClic return; } TencentLocation tencentLocation = (TencentLocation) msg.obj; - if (tencentMap != null && ivLocation!=null && !ivLocation.isEnabled()) { // 当定位按钮禁用, - CameraUpdate cameraSigma = CameraUpdateFactory.newCameraPosition(new CameraPosition( - new LatLng(tencentLocation.getLatitude(), tencentLocation.getLongitude()), //中心点坐标,地图目标经纬度 - 17, //目标缩放级别 - 0, //目标倾斜角 - 0)); //目标旋转角 0~360° (正北方为0) - tencentMap.animateCamera(cameraSigma); - } +// if (tencentMap != null && ivLocation!=null && !ivLocation.isEnabled()) { // 当定位按钮禁用, +// CameraUpdate cameraSigma = CameraUpdateFactory.newCameraPosition(new CameraPosition( +// new LatLng(tencentLocation.getLatitude(), tencentLocation.getLongitude()), //中心点坐标,地图目标经纬度 +// 17, //目标缩放级别 +// 0, //目标倾斜角 +// 0)); //目标旋转角 0~360° (正北方为0) +// tencentMap.animateCamera(cameraSigma); +// } // 判断当前点位和上一个点位的距离,如果距离过近,忽略该点 Point currentPoint = (Point) GeometryTools.createGeometry(new LatLng(tencentLocation.getLatitude(), tencentLocation.getLongitude())); - if (lastPositionPoint!=null&&lastPositionPoint.distance(currentPoint)未匹配到的点位个数 private List matchPointList = new ArrayList<>(); // 已匹配的点位列表 private List unMatchPointList = new ArrayList<>(); // 未匹配的点位列表 + private double matchedLength = 0; public int getId() { return id; @@ -162,6 +163,14 @@ public class RoadMatchEntity implements Serializable { this.currentLineDistance = currentLineDistance; } + public double getMatchedLength() { + return matchedLength; + } + + public void setMatchedLength(double matchedLength) { + this.matchedLength = matchedLength; + } + @Override public boolean equals(Object o) { if (this == o) return true; 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 b29b987..440d66c 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java @@ -103,6 +103,7 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList private RadioButton rbtnRoadOpen/*道路已开通*/, rbtnRoadPartOpen/*道路部分开通*/, rbtnRoadHasntOpen/*道路未开通*/, rbtnRoadHasntFind/*道路未找到*/, rbtnRoadOther/*其他*/; private RadioGroup rgRoadStatus; // 道路状态的radioGroup private EditText edtCheckedOther; + private int existence = 0; // 是否存在 public static RoadFragment newInstance(Bundle bundle) { RoadFragment fragment = new RoadFragment(); @@ -230,6 +231,10 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList @Override public void onCheckedChanged(RadioGroup group, int checkedId) { rgRoadStatus.setTag(findViewById(checkedId).getTag()); + existence = (int) findViewById(checkedId).getTag(); + if (showPoiEntity!=null) { + showPoiEntity.setExistence(existence); + } switch (checkedId) { case R.id.rbtn_road_other: edtCheckedOther.setVisibility(View.VISIBLE); @@ -400,6 +405,15 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList if (showPoiEntity.getTaskId()>0) { etRoadName.setEnabled(false); } + if (rgRoadStatus!=null) { + for (int i = 0; i < rgRoadStatus.getChildCount(); i++) { + RadioButton childAt = (RadioButton) rgRoadStatus.getChildAt(i); + if (childAt.getTag().equals(showPoiEntity.getExistence())) { + childAt.setChecked(true); + break; + } + } + } } } @@ -648,7 +662,7 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList httpParams.put("workType", 0); httpParams.put("memo", poiEntity.getMemo()); // 增加对应九天平台的参数 - httpParams.put("existence", rgRoadStatus.getTag().toString()); + httpParams.put("existence", existence); httpParams.put("description", edtCheckedOther!=null&&edtCheckedOther.isShown()? edtCheckedOther.getText().toString().trim(): ""); OkGoBuilder okGoBuilder = OkGoBuilder.getInstance() @@ -719,7 +733,7 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList httpParams.put("workType", 0); httpParams.put("memo", poiEntity.getMemo()); // 增加对应九天平台的参数 - httpParams.put("existence", rgRoadStatus.getTag().toString()); + httpParams.put("existence", existence); httpParams.put("description", edtCheckedOther!=null&&edtCheckedOther.isShown()? edtCheckedOther.getText().toString().trim(): ""); OkGoBuilder okGoBuilder = OkGoBuilder.getInstance() .time(30) diff --git a/app/src/main/java/com/navinfo/outdoor/http/HttpInterface.java b/app/src/main/java/com/navinfo/outdoor/http/HttpInterface.java index 720779c..e73822a 100644 --- a/app/src/main/java/com/navinfo/outdoor/http/HttpInterface.java +++ b/app/src/main/java/com/navinfo/outdoor/http/HttpInterface.java @@ -3,8 +3,8 @@ package com.navinfo.outdoor.http; public class HttpInterface { // public static final String IP = "http://172.23.138.133:9999/m4";//测试接口-IP public static final String IPm = "http://dtxbmaps.navinfo.com/dtxb/dev/m4";//开发接口-外网 - public static final String IP = "http://dtxbmaps.navinfo.com/dtxb/test/m4";//测试接口-外网 - public static final String IP1 = "http://dtxbmaps.navinfo.com/dtxb/m4";//正式接口 + public static final String IP1 = "http://dtxbmaps.navinfo.com/dtxb/test/m4";//测试接口-外网 + public static final String IP = "http://dtxbmaps.navinfo.com/dtxb/m4";//正式接口 public static final String USER_PATH = "/user/";//我的 public static final String MSG_LIST_PATH = "/msgList/";//发现 public static final String USER_LOGIN_PATH = "/userlogin/";//登录 diff --git a/app/src/main/res/drawable/selector_direction.xml b/app/src/main/res/drawable/selector_direction.xml new file mode 100644 index 0000000..90adb01 --- /dev/null +++ b/app/src/main/res/drawable/selector_direction.xml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_picture_map_change.xml b/app/src/main/res/drawable/selector_picture_map_change.xml new file mode 100644 index 0000000..f69bdea --- /dev/null +++ b/app/src/main/res/drawable/selector_picture_map_change.xml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_auto_take_pictures.xml b/app/src/main/res/layout/activity_auto_take_pictures.xml index 17093ac..6326eaa 100644 --- a/app/src/main/res/layout/activity_auto_take_pictures.xml +++ b/app/src/main/res/layout/activity_auto_take_pictures.xml @@ -127,12 +127,13 @@ @@ -160,16 +161,29 @@ + + FR<_a-xjkw^JhB1LT+GysOjg0G%hFb2qWGZGeLy0t{spM8F zT3%+cGD8PcrY6Cy9OS~CLqLBEu&?L z_XG(F-%ljGn_Yo14<|vvD{`~d+q@;G+0<0K=(vP+;x94>ni_XY>HsYy3@%^|-O*O=H4sS_p z@5WHw2>GaO4`>`spsK1`T2?bN1n%;~t%G#d3q)(@isE-E^BTjSY18uZUOfzv1BrpK z{=5e2eRGeiv8}WYYf#`j3-8n3l3;Xj24K4!4*^ocVGEOZ7-pg(VepjJr@g~{c3u@f z4=gRbd-tviona{tkgYoaI<{%j3h+MhE2bk}lxL8~xfxa*U6*hSa)NefI-1>a5JzZP z>5S@Sa?sTF;NiuziE{)Pui&lhl6S<<#Dv$H1n#d%KvFo{UvIhKDT@ZgJ>JN(0Eir(*?eL0ixsiV1@s<}+E_rH zJF~U4kU+g}>ala(DFoONuql8G$ScMGX=YGa(|zE~{w zH|p3je0o$y3-~wpP*Xy*ByoAWkv#q1ufM-2zmPvinTn zLj~Yoa?RHTzEEkxFd)u)3K!u(A7YGL|M)G)%a)lg8I3B2Qe41SQttr&neoJRlt;3Y z=k!k5jjw+pNF&RK1wt0hCS9MIxNR5EKW$Q(13uFiY=!N8I!(`yIv2%3czsh&^sFA? zd^A*yCeg}P0@m;#?#C;>AKR!aGbX?g!*5>Ge`8ZM{@wNnbMQ1Z_1Aowh$x`Ik`uv0#LnJ-eezpfH9oBj*aaPB4b5TB`x-$hq%{A!zABf)SoDAXjTSnk^M0+^n}jcsZPSeSvU)0b)6g%_&0> zU*o}NzunBiChGk=tHWJpm;6=L)Ha{}x_jOhN-;e=>BP-t)Ia@ay;8KsD(_D%f`k15 zo`kPeJ}y>q!TIlV^O|@e`p5m(uA1?*u3%KSLu& z?+8rNf%`&$kKRwRx+p7m@Y@3?x>Z<2n?LVD4kJa6GzU{>I>}RT;pBzuE2%A`9FZgJ z-;VLBw}E3-K?NBeJ}f_Gjdhc<6@aw7y!vOtIuMsx_U{)8^=LL$ik}W0PJ)D_7o^CE;r;bj&MYdmu}*5uc^VWeK>D-&F*qweGP9Y#nLBd z8EO6IlfqNSHDAThRyzcP3ERl;aCI(!+4ahQt$8`7?|o(j(^W5dO5zufdkv-5NYN)L z4CiU}+5%@qxFiL7^4=a&%2Rnt1#$vH*dJIwykpM-Q>hD#FBA>56ED_7v@hknbWYOAK#TN{BX*ry7hJ`!rW z`Z#x2XJ&8dzAv-OYfwT`*?EUB$0I-;lv?=R3|+Oqd+@Px-!X{s1(sI7Cb00kqaLIM z4&EmsydXFJpDGk`-D5<&g1$_rqn%Pei{TZIerqQ8ZH$eL62{0eRq-_h}Q56cs+I zUj$y(94&i&rx~dCnGl*)yt$XCZG1jI(`U&b(e$8?CukJy`ek6Lk;sl1-f{I&l^j!! zLN$a^>~%?Rm>lkt$q_eY;HiKUIW!Ac-NIR#&2v3JPq=}BnHnIR$W3<>rK9VY2rP1F_0t{&)lvYQI+=Fb55&sU4aJe2N?bs^einm)Nl|I2&4}o2 zH!9{AJ9EvETb3SI53K8u>tx3*L0r>idM<2E7BD^1>wwfYX3ztux?n*?xDjDqZltIl zf8;8P6*!n6hcoA>!=)ek11@4;LE0|0+Dx(0-1jhwq}umm540%j%);$E4USRl*p!(- znd>W?#*2TW4GKr3`$7*`-TQrRZjk75x*>lrXqn#J+^o1%Nfw~~+^7~2je9OGy@8Me zl|{%2IX3@^uxK~QP}q}G=Pet{qIhJZ25OFQQJBLx5KVhf&tm02606AZ=$7=!Gs1I6 zSn-8nQ@?DtH?woQ3GC2{v+(#)6gse$!)@{@a&}64_Z>VA<%vAdijKM@ZhzMqvr}Xy zxDmha{$Gqv*NYlP14L=Hb*-~qd?X+TZgN zqu5ggSF0CNxUda`-zNODsScEFxj#lKP#XOzZ)7R~1>KOsW~oAl?Oma>H!4WBlmZVo LZ$jO{(DVNV(^2_V literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/direction_press.png b/app/src/main/res/mipmap-xxhdpi/direction_press.png new file mode 100644 index 0000000000000000000000000000000000000000..a9e4f4dba30efee0cb9a9b96071a43373149addb GIT binary patch literal 2741 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 F(!WIrqelP$ literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/exchange_press.png b/app/src/main/res/mipmap-xxhdpi/exchange_press.png new file mode 100644 index 0000000000000000000000000000000000000000..89fd72b71611744e1e1a8e3d7872abf737389efe GIT binary patch literal 3152 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 qNkxV@0Tj8q8e?+;&>*SEkpBW)07%