diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 7fa9baf..ec30f70 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -81,5 +81,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index fbfd8fa..80fdb30 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -86,6 +86,7 @@ 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 project(path: ':ocr')
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
diff --git a/app/src/main/java/com/navinfo/outdoor/activity/HomeActivity.java b/app/src/main/java/com/navinfo/outdoor/activity/HomeActivity.java
index fe52099..0d6954c 100644
--- a/app/src/main/java/com/navinfo/outdoor/activity/HomeActivity.java
+++ b/app/src/main/java/com/navinfo/outdoor/activity/HomeActivity.java
@@ -7,6 +7,7 @@ import com.kongzue.dialog.interfaces.OnDialogButtonClickListener;
import com.kongzue.dialog.util.BaseDialog;
import com.kongzue.dialog.util.DialogSettings;
import com.kongzue.dialog.v3.MessageDialog;
+import com.navinfo.ocr.OCRManager;
import com.navinfo.outdoor.api.Constant;
import com.navinfo.outdoor.api.UserApplication;
import com.navinfo.outdoor.base.BaseActivity;
@@ -115,7 +116,8 @@ public class HomeActivity extends BaseActivity {
// 注册位置更新的lifeCycle
getLifecycle().addObserver(LocationLifeCycle.getInstance());
-
+ // 初始化图像识别组件
+ OCRManager.Companion.getInstance().init(HomeActivity.this);
} else {
finish();
}
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 1f45986..95cd743 100644
--- a/app/src/main/java/com/navinfo/outdoor/activity/PicturesActivity.java
+++ b/app/src/main/java/com/navinfo/outdoor/activity/PicturesActivity.java
@@ -29,15 +29,20 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
+import com.elvishew.xlog.XLog;
import com.github.lazylibrary.util.FileUtils;
import com.kongzue.dialog.interfaces.OnDialogButtonClickListener;
import com.kongzue.dialog.util.BaseDialog;
import com.kongzue.dialog.util.DialogSettings;
import com.kongzue.dialog.v3.MessageDialog;
+import com.navinfo.ocr.OCRManager;
+import com.navinfo.ocr.model.OcrViewResultModel;
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.LocationRecorder;
+import com.navinfo.outdoor.util.BitmapUtil;
import com.navinfo.outdoor.util.GPSUtils;
import com.navinfo.outdoor.util.Geohash;
import com.navinfo.outdoor.util.GeometryTools;
@@ -51,6 +56,7 @@ 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.CameraUtils;
import com.otaliastudios.cameraview.CameraView;
import com.otaliastudios.cameraview.FileCallback;
import com.otaliastudios.cameraview.PictureResult;
@@ -82,13 +88,16 @@ import org.locationtech.jts.geom.MultiLineString;
import com.wanghong.webpnative.WebPNative;
import org.greenrobot.eventbus.EventBus;
+import org.reactivestreams.Subscription;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
@@ -96,12 +105,21 @@ import java.util.concurrent.TimeUnit;
import static com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE;
+import io.reactivex.BackpressureStrategy;
+import io.reactivex.Flowable;
+import io.reactivex.FlowableEmitter;
+import io.reactivex.FlowableOnSubscribe;
+import io.reactivex.FlowableSubscriber;
+import io.reactivex.Notification;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
+import io.reactivex.functions.BiFunction;
+import io.reactivex.functions.Consumer;
+import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
/**
@@ -118,12 +136,14 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
private String finalVideoPath, geoWkt, detail; // 摄像后最终保存的文件名
private ViewGroup layerChange; // 切换地图和相机的父控件
private CheckBox capturePicture; //拍照
- private File paperFile, logFile;
+ private File paperFile, logFile, checkFile/*辅助检查文件*/;
private ImageView ivZoomAdd, ivZoomDel, ivLocation, ivPicRoadImage, ivPicVideoImage, imageView;
private View layerMapController;
private MyLocation oldCurrentLocation = null;
- private Timer timer;
- private TimerTask timerTask;
+// private Timer timer;
+// private TimerTask timerTask;
+ private Disposable disposable; // RxJava循环拍照的控制对象
+ private FlowableEmitter pictureEmitter; // RxJava控制照片生成
private SystemTTS systemTTS;
private StringBuilder picturesBuilder;
private LatLng startLatLine, endLatLine;
@@ -145,10 +165,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
- if (msg.what == 0x101) {
- System.out.println("收到拍照按钮请求");
- camera.takePictureSnapshot();
- } else if (msg.what == 0x102) {
+ if (msg.what == 0x102) {
if (imageView != null) {
imageView.setEnabled(true);
}
@@ -157,7 +174,7 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
capturePicture.setText("开始采集");
}
capturePicture.setChecked(false);
- stopTimer();
+ stopTakePhoto();
} else if (msg.what == 0x104) {
tvConvert.setText("转换成功:"+(++msg.arg1));
}
@@ -207,12 +224,8 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
if (finalVideoPath != null) {
File file = new File(finalVideoPath);
paperFile = new File(Objects.requireNonNull(file.getParentFile()).getAbsoluteFile() + "/" + "paper.txt");
+ checkFile = new File(Objects.requireNonNull(file.getParentFile()).getAbsoluteFile() + "/" + "check.json");
videoIndex = Integer.parseInt(file.getName().replace(".webp", ""));
- if (videoIndex == 0) {
- videoIndex = -1;
- } else {
- videoIndex = videoIndex - 1;
- }
convertIndex = videoIndex;
}
}
@@ -250,31 +263,25 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
radioGroupPicture.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
+ stopTakePhoto();
+ capturePicture.setChecked(false);
switch (checkedId) {
case R.id.radio_btn_hand://手动
radioPicture = 1;
isOration = false;
capturePicture.setText("拍摄");
- capturePicture.setChecked(false);
- stopTimer();
break;
case R.id.radio_btn_auto://自动1秒:
radioPicture = 2;
capturePicture.setText("开始采集");
- capturePicture.setChecked(false);
- stopTimer();
break;
case R.id.radio_btn_auto_sec://自动2 秒
radioPicture = 3;
capturePicture.setText("开始采集");
- capturePicture.setChecked(false);
- stopTimer();
break;
case R.id.radio_btn_half_sec://自动0.5 秒
radioPicture = 4;
capturePicture.setText("开始采集");
- capturePicture.setChecked(false);
- stopTimer();
break;
}
}
@@ -314,13 +321,14 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
} else {
picturesBuilder.append(TimestampUtil.time()).append(",").append("capturePicture 点击了拍摄 ,");
}
- startTimer();
+ startTakePhoto(radioPicture);
+ startTakePhoto(radioPicture);
} else {
if (radioPicture != 1) {
capturePicture.setText("开始采集");
picturesBuilder.append(TimestampUtil.time()).append(",").append("capturePicture 点击了暂停采集 ,");
}
- stopTimer();
+ stopTakePhoto();
}
}
});
@@ -382,6 +390,96 @@ public class PicturesActivity extends BaseActivity implements View.OnClickListen
}
});
+ Flowable pictureResultFlowable = Flowable.create(new FlowableOnSubscribe() {
+ @Override
+ public void subscribe(FlowableEmitter emitter) throws Exception {
+ pictureEmitter = emitter;
+ }
+ }, BackpressureStrategy.BUFFER).subscribeOn(Schedulers.io());
+
+ Flowable integerFlowable = Flowable.create(new FlowableOnSubscribe() {
+ @Override
+ public void subscribe(FlowableEmitter emitter) {
+ for (int i = videoIndex; ; i++) { // 标记当前是第几个图片,记录Index
+ emitter.onNext(i);
+ }
+ }
+ }, BackpressureStrategy.BUFFER).subscribeOn(Schedulers.io());
+
+ Flowable.zip(pictureResultFlowable, integerFlowable, new BiFunction(){
+
+ @Override
+ public Map apply(PictureResult pictureResult, Integer fileIndex) throws Exception { // 将图片转为File文件
+ // 图片和paper.txt处理
+ File currentFile = new File(paperFile.getParentFile().getAbsolutePath() + "/" + fileIndex + ".webp");
+ CameraUtils.writeToFile(pictureResult.getData(), currentFile); // 生成照片文件
+ // 记录当前点位信息
+ LocationRecorder recorder = new LocationRecorder();
+ recorder.setTime(System.currentTimeMillis());
+ // 记录主定位方式
+ recorder.setTencentLocationX(LocationLifeCycle.getInstance().getMainLocation().getLongitude());
+ recorder.setTencentLocationY(LocationLifeCycle.getInstance().getMainLocation().getLatitude());
+ // 记录辅助定位方式
+ MyLocation gpsLocation = LocationLifeCycle.getInstance().getReferenceLocation();
+ if (gpsLocation!=null) {
+ recorder.setGpsLocationX(gpsLocation.getLongitude());
+ recorder.setGpsLocationY(gpsLocation.getLatitude());
+ }
+ recorder.setBearing(LocationLifeCycle.getInstance().getMainLocation().getBearing());
+ recorder.setRssi(GPSUtils.getInstance(PicturesActivity.this).getSateliteCount());
+ recorder.setSatelliteCount(GPSUtils.getInstance(PicturesActivity.this).getSateliteCount());
+ FileUtils.writeFile(paperFile.getAbsolutePath(), recorder.toString(formatter, fileIndex), true);
+ Map map = new HashMap<>();
+ map.put("index", fileIndex);
+ map.put("picture", pictureResult);
+ return map;
+ }
+ })
+ .subscribeOn(Schedulers.io()) // 指定上游为IO线程
+ .observeOn(AndroidSchedulers.mainThread())
+ .doOnNext(new Consumer