diff --git a/aar/base/base-release.aar b/aar/base/base-release.aar new file mode 100644 index 0000000..9983d9a Binary files /dev/null and b/aar/base/base-release.aar differ diff --git a/aar/base/build.gradle b/aar/base/build.gradle new file mode 100644 index 0000000..587b7c2 --- /dev/null +++ b/aar/base/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('base-release.aar')) \ No newline at end of file diff --git a/app/README.md b/app/README.md new file mode 100644 index 0000000..8b72265 --- /dev/null +++ b/app/README.md @@ -0,0 +1,5 @@ +打包注意事项: +1.检查 Test.java 中的DEBUG是否为false; +2.检查 打包版本号; +3.检查数据库版本号; +4.检查changelog.xml内容 diff --git a/app/build.gradle b/app/build.gradle index 38c2fc4..8007d43 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,23 +1,22 @@ -//import com.bingce.AndroidSdk -//import com.bingce.SurveyorVersionUtils +import com.bingce.* apply plugin: 'com.android.application' apply plugin: 'org.jetbrains.kotlin.android' apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-parcelize' - apply from: "../control_common/config.gradle" + android { - namespace 'com.bingce.controlnetwork' - useLibrary "org.apache.http.legacy" - compileSdk 34 + useLibrary Libs.httpLegacy + compileSdk AndroidSdk.compileSdkVersion + namespace App.ControlNetwork.applicationId + defaultConfig { - applicationId "com.bingce.controlnetwork" - minSdkVersion 26 - targetSdkVersion 34 + minSdkVersion AndroidSdk.minSdkVersion + targetSdkVersion AndroidSdk.targetSdkVersion ndk {} - flavorDimensions "custom_made" + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true javaCompileOptions { @@ -28,11 +27,11 @@ android { ] } } - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildFeatures { viewBinding true + buildConfig true } signingConfigs { @@ -41,47 +40,82 @@ android { } } - def gitCommit = 'git rev-parse --short HEAD'.execute().text.trim() - System.out.println("base-java -- version:${gitCommit}") buildTypes { debug { signingConfig signingConfigs.debug - buildConfigField "String", "codeVersion", "\"${gitCommit}\"" + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - buildConfigField "String", "codeVersion", "\"${gitCommit}\"" } } - //渠道key - // tj61365--天津定制 - def flavor = "tj61365" + //渠道key + //bingce--通用版本 + //pro--高级版,驱动马达的版本 + //tj61365--天津定制 + //intl--国际版 + //intl_pro--国际专业版 + def flavor = "bingce" //多渠道打包 - flavorDimensions 'custom_made' + flavorDimensions = Arrays.asList("custom_made") productFlavors { - //天津版本 + if (flavor == "bingce") { + bingce { + dimension 'custom_made' + buildConfigField "int", "CHANNEL_TYPE", "com.bingce.AppChannel.CUSTOM_CONTROL_PUBLIC" + versionCode _versionCode + versionName _versionName + } + } + //其他定制app + if (flavor == "pro") { + pro {//驱动马达的版本 + dimension 'custom_made' + buildConfigField "int", "CHANNEL_TYPE", "com.bingce.AppChannel.CUSTOM_CONTROL_PRO" + versionCode(_versionCode * 100) + versionName _versionName + } + } if (flavor == "tj61365") { -// tj61365 { -// dimension 'custom_made' -// buildConfigField "int", "CHANNEL_TYPE", "com.bingce.AppChannel.CUSTOM_CONTROL_TJ_61365" -// versionCode(_versionCode * 100) -// versionName _versionName//"1.3.1" -// } + tj61365 {//天津定制 + dimension 'custom_made' + buildConfigField "int", "CHANNEL_TYPE", "com.bingce.AppChannel.CUSTOM_CONTROL_TJ_61365" + versionCode(_versionCode * 100) + versionName _versionName + } + } + if (flavor == "intl") { + intl {//国际版 + dimension 'custom_made' + buildConfigField "int", "CHANNEL_TYPE", "com.bingce.AppChannel.CUSTOM_CONTROL_INTERNATIONAL" + versionCode(_versionCode * 100) + versionName _versionName + } + } + if (flavor == "intl_pro") { + intl_pro {//国际专业版 + dimension 'custom_made' + buildConfigField "int", "CHANNEL_TYPE", "com.bingce.AppChannel.CUSTOM_CONTROL_INTERNATIONAL_PRO" + versionCode(_versionCode * 100) + versionName _versionName + } } - } splits { + // Split apks on build target ABI, view all options for the splits here: + // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits abi { enable true reset() - include 'arm64-v8a', 'armeabi-v7a'//,'armeabi-v7a', 'x86'//, 'x86_64', 'mips','armeabi', + include 'arm64-v8a'//,'armeabi-v7a', 'x86'//, 'x86_64', 'mips','armeabi', } } @@ -94,50 +128,74 @@ android { exclude 'META-INF/NOTICE' exclude 'META-INF/*.kotlin_module' + exclude '/META-INF/{AL2.0,LGPL2.1}'//适配compose +// exclude 'schemaorg_apache_xmlbeans/**' +// exclude 'assets/org/apache/**' +// exclude 'org/apache/**' +// exclude 'font_metrics.properties' } + lintOptions { abortOnError false disable 'GoogleAppIndexingWarning' } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - } dependencies { - implementation fileTree(include: ['*.jar', '*.aar'], dir: '../control_common/libs') - project.ext.dependencies.each { k, v -> - implementation v - } - project.ext.kapt.each { k, v -> kapt v } - implementation 'com.google.android.gms:play-services-auth:20.7.0' + implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') implementation project(':control_common') + + def moduleName = new ModuleName(project) + implementation project(moduleName.bingceModule("appBase")) + implementation project(moduleName.bingceModule("repository")) + implementation project(moduleName.bingceModule("base")) + implementation project(moduleName.bingceModule("leancloud")) + implementation project(moduleName.bingceModule("base-java")) + implementation project(moduleName.bingceModule("utils")) + implementation project(moduleName.bingceModule("coordlib")) + implementation project(moduleName.bingceModule("device")) + implementation project(moduleName.bingceModule("device-ui")) + implementation project(moduleName.bingceModule("rtk")) + implementation project(moduleName.bingceModule("totalstation")) + implementation project(moduleName.bingceModule("level")) + implementation project(moduleName.bingceModule("bcdialog-style")) + implementation project(moduleName.openSourceModule("utilcode")) + implementation project(moduleName.openSourceModule("colorful"))//选择主题颜色 + implementation project(moduleName.openSourceModule("dragExpandGrid"))//管理里的布局 + implementation project(moduleName.openSourceModule("lsettingitemlibrary"))//用户信息里 + implementation project(moduleName.openSourceModule("spinkit"))//loading控件 导出使用 + implementation project(moduleName.openSourceModule("splashview"))//广告view + implementation project(moduleName.openSourceModule("poishadowjar"))//导入excel + implementation project(moduleName.openSourceModule("safFilePicker"))//选择文件 + implementation project(moduleName.openSourceModule("fastjson")) + implementation project(moduleName.openSourceModule("agentweb")) + implementation project(":opensource:exFilePicker") + implementation project(":sdk:tensorFlowTTS")//语音播报 + implementation Libs.RxImagePicker.core +// implementation Libs.RxImagePicker.support +// implementation Libs.RxImagePicker.supportWechat + constraints { - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10") { because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib") } - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10") { because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib") } } - def leanCloudVersion = "8.2.16" - implementation "cn.leancloud:storage-android:$leanCloudVersion" - implementation "cn.leancloud:realtime-android:$leanCloudVersion" - - implementation 'com.getbase:floatingactionbutton:1.10.1' - - implementation 'com.github.razir.progressbutton:progressbutton:2.1.0' - implementation "com.mikepenz:materialdrawer:6.1.2" +// implementation "cn.leancloud:storage-android:8.2.5" +// implementation "cn.leancloud:realtime-android:8.2.5" + implementation Libs.LeanCloud.storage + implementation Libs.LeanCloud.realtime testImplementation "junit:junit:4.13.2" androidTestImplementation "androidx.test:runner:1.1.0" + androidTestImplementation "androidx.test:rules:1.1.0" + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' + + implementation 'com.google.android.gms:play-services-auth:20.7.0' - def imagepicker = "2.5.6" - implementation "com.github.qingmei2:rximagepicker:$imagepicker" -// implementation "com.github.qingmei2:rximagepicker_support:$imagepicker" -// implementation "com.github.qingmei2:rximagepicker_support_wechat:$imagepicker" + project.ext.dependencies.each { k, v -> implementation v } + project.ext.kapt.each { k, v -> kapt v } } \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 28992b9..c8f43e2 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -31,12 +31,7 @@ public static final int *; -keep class androidx.appcompat.widget.SearchView { *; } -keep class cn.aigestudio.datepicker.**{*;} --keep class io.realm.annotations.RealmModule --keep @io.realm.annotations.RealmModule class * --keep class io.realm.internal.Keep --keep @io.realm.internal.Keep class * { *; } -dontwarn javax.** --dontwarn io.realm.** -keep class com.tencent.mm.sdk.** { *; diff --git a/app/src/androidTest/kotlin/HelloKotlin.kt b/app/src/androidTest/kotlin/HelloKotlin.kt index 02e7131..f967c63 100644 --- a/app/src/androidTest/kotlin/HelloKotlin.kt +++ b/app/src/androidTest/kotlin/HelloKotlin.kt @@ -10,39 +10,39 @@ class HelloKotlin { @Test fun test() { - runBlocking { - - launch { - Log.d("hwhw", "请求1") - - delay(1000) - Log.d("hwhw", "请求1 delay") - - val apiCall = RetrofitClient.apiCall { - RetrofitClient.createService().getPassageData() - } - - apiCall?.let { - Log.d("hwhw", "请求成功1,$it") - } - } - - launch { - Log.d("hwhw", "请求2") - - delay(1000) - Log.d("hwhw", "请求2 delay") - - val apiCall1 = RetrofitClient.apiCall { - RetrofitClient.createService().getPassageData() - } - apiCall1?.let { - Log.d("hwhw", "请求成功2,$it") - } - } - - - } +// runBlocking { +// +// launch { +// Log.d("hwhw", "请求1") +// +// delay(1000) +// Log.d("hwhw", "请求1 delay") +// +// val apiCall = RetrofitClient.apiCall { +// RetrofitClient.createService().getPassageData() +// } +// +// apiCall?.let { +// Log.d("hwhw", "请求成功1,$it") +// } +// } +// +// launch { +// Log.d("hwhw", "请求2") +// +// delay(1000) +// Log.d("hwhw", "请求2 delay") +// +// val apiCall1 = RetrofitClient.apiCall { +// RetrofitClient.createService().getPassageData() +// } +// apiCall1?.let { +// Log.d("hwhw", "请求成功2,$it") +// } +// } +// +// +// } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3a83811..09491e2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -179,6 +179,35 @@ android:name=".activity.user.InputEmailActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:exported="true" /> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/App.java b/app/src/main/java/com/bingce/controlnetwork/App.java index e398f30..b0aea8d 100644 --- a/app/src/main/java/com/bingce/controlnetwork/App.java +++ b/app/src/main/java/com/bingce/controlnetwork/App.java @@ -5,6 +5,7 @@ import static com.bingce.AppChannel.customChannel; import android.content.SharedPreferences; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.text.TextUtils; import android.util.Log; import android.widget.ImageView; @@ -13,11 +14,11 @@ import androidx.preference.PreferenceManager; import com.bingce.AppChannel; import com.bingce.RepositoryBaseApp; import com.bingce.controlapphelper.datasource.database.SurveyorDataBase; -import com.bingce.controlapphelper.datasource.database.ToleranceTemplate; -import com.bingce.controlapphelper.util.DatabaseProvider; +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil; import com.bingce.controlapphelper.util.SettingValueUtil; import com.bingce.controlnetwork.activity.NotificationActivity; import com.bingce.utils.DES; +import com.bingce.utils.ThreadPoolUtil; import com.bumptech.glide.Glide; import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader; import com.mikepenz.materialdrawer.util.DrawerImageLoader; @@ -33,6 +34,7 @@ import cn.leancloud.LCInstallation; import cn.leancloud.LCLogger; import cn.leancloud.LeanCloud; import cn.leancloud.push.PushService; +import cn.liuyanbing.surveyor.AppConfig; import io.reactivex.functions.Consumer; import io.reactivex.plugins.RxJavaPlugins; @@ -74,11 +76,16 @@ public class App extends RepositoryBaseApp { public String wifiChatClientIp = ""; public String lastPhoneLocation = ""; + /** + * 自动测量是否开启atr + */ + public String levelSurveyorTime; + private static App app; @Override public void onCreate() { - customChannel = AppChannel.CUSTOM_PUBLIC;//; + customChannel = BuildConfig.CHANNEL_TYPE;//AppChannel.CUSTOM_PUBLIC; super.onCreate(); app = this; @@ -148,6 +155,10 @@ public class App extends RepositoryBaseApp { isCloseInstrumentAfterExit = prefs.getBoolean("isCloseInstrumentAfterExit", false); magneticDeclination = prefs.getFloat("magneticDeclination", 0); lastPhoneLocation = prefs.getString("lastPhoneLocation", ""); + levelSurveyorTime = prefs.getString("levelSurveyorTime", "1"); + if (TextUtils.isEmpty(levelSurveyorTime)) { + levelSurveyorTime = "1"; + } } @Override @@ -164,6 +175,16 @@ public class App extends RepositoryBaseApp { return BuildConfig.APPLICATION_ID; } + @Override + public boolean isThemeDark() { + return false; + } + + @Override + public int angleNotNumber() { + return AppConfig.instance.angleDotNum(); + } + public static App getApp() { return app; } @@ -175,9 +196,8 @@ public class App extends RepositoryBaseApp { private void initControlApp() { Utils.init(this); - //加载限差配置 - ToleranceTemplate.setup(); + ThreadPoolUtil.execute(ToleranceLoadUtil::init); //数据库 - DatabaseProvider.init(SurveyorDataBase.getInstance()); + SurveyorDataBase.getInstance(); } } diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/AboutActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/AboutActivity.java index 5474ffe..b36b276 100644 --- a/app/src/main/java/com/bingce/controlnetwork/activity/AboutActivity.java +++ b/app/src/main/java/com/bingce/controlnetwork/activity/AboutActivity.java @@ -14,6 +14,8 @@ import androidx.appcompat.widget.Toolbar; import com.bingce.activity.PrivacyPolicyActivity; import com.bingce.activity.UserAgreementActivity; +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.util.CheckControlUpdateUtil; import com.bingce.surveyor.agentweb.AgentWebActivity; import com.vansuita.materialabout.builder.AboutBuilder; @@ -24,9 +26,6 @@ import org.polaric.colorful.ColorfulActivity; import blankj.utilcode.util.ToastUtils; import blankj.utilcode.util.Utils; -import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.util.CheckControlUpdateUtil; - public class AboutActivity extends ColorfulActivity { private Toolbar mToolbar; @@ -120,14 +119,24 @@ public class AboutActivity extends ColorfulActivity { finish(); break; case R.id.menu_debug_switch: - Utils.isTest = !Utils.isTest; - if (Utils.isTest){ - ToastUtils.showShort(R.string.debug_on); - }else{ - ToastUtils.showShort(R.string.debug_off); - } + startOpenCloseMeasureDebug(); break; } return super.onOptionsItemSelected(item); } + + /** + * 开始打开或关闭调试 + */ + private void startOpenCloseMeasureDebug() { + CheckStorageUtil.check(this, () -> { + Utils.isTest = !Utils.isTest; + if (Utils.isTest) { + ToastUtils.showShort(R.string.debug_on); + } else { + ToastUtils.showShort(R.string.debug_off); + } + }); + } + } diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java index 0658939..4b51e4f 100644 --- a/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java +++ b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java @@ -1,7 +1,6 @@ package com.bingce.controlnetwork.activity; import android.annotation.SuppressLint; -import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; @@ -9,7 +8,6 @@ import android.graphics.Color; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.os.Handler; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; @@ -27,6 +25,7 @@ import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; +import androidx.lifecycle.ViewModelProvider; import androidx.preference.PreferenceManager; import androidx.viewpager.widget.ViewPager; @@ -35,27 +34,30 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.bingce.AppChannel; import com.bingce.BaseApp; import com.bingce.activity.BaseMainActivity; +import com.bingce.controlapphelper.datasource.database.config.ConfigOperate; import com.bingce.controlapphelper.event.DatabaseReadyEvent; -import com.bingce.controlapphelper.event.ProjectChangedEvent; import com.bingce.controlapphelper.event.SwitchPageEvent; import com.bingce.controlapphelper.util.InterfaceUtil; import com.bingce.controlapphelper.util.SettingValueUtil; import com.bingce.controlnetwork.App; import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.activity.backup.BackupExportActivity; import com.bingce.controlnetwork.activity.backup.launch.BackupImportHelper; import com.bingce.controlnetwork.activity.user.LoginActivity; import com.bingce.controlnetwork.activity.user.RegisterActivity; import com.bingce.controlnetwork.activity.user.UserInfoActivity; -import com.bingce.controlnetwork.fragment.ConfigFragment; +import com.bingce.controlnetwork.bean.MainUserBean; import com.bingce.controlnetwork.fragment.MainSurveyFragment; import com.bingce.controlnetwork.fragment.ProjectListFragment; import com.bingce.controlnetwork.fragment.ServiceFragment; +import com.bingce.controlnetwork.newui.configfragment.ConfigFragment; +import com.bingce.controlnetwork.newui.mefragment.MeFragment; import com.bingce.controlnetwork.util.CheckControlUpdateUtil; +import com.bingce.controlnetwork.viewmodel.MainActivityViewModel; import com.bingce.data.sync.GlobalFlowCenter; import com.bingce.data.sync.utils.LeanCloudConfigLoader; import com.bingce.data.sync.utils.LeanCloudUserLoginStateUtils; import com.bingce.device.Device; +import com.bingce.device.ui.dialog.DialogUtil; import com.bingce.device.ui.manager.DeviceConnectManager; import com.bingce.device.ui.manager.DeviceRemindManager; import com.bingce.device.ui.manager.DeviceRequestManager; @@ -64,7 +66,7 @@ import com.bingce.event.OpenShortUrlEvent; import com.bingce.surveyor.agentweb.AgentWebActivity; import com.bingce.totalstation.TotalStation; import com.bingce.ui.TabEntity; -import com.bingce.utils.ActivateUtil; +import com.bingce.utils.AppUtil; import com.bingce.utils.ColorUtil; import com.bingce.utils.CrashCollector; import com.bingce.utils.DateUtils; @@ -83,16 +85,6 @@ import com.flyco.tablayout.listener.OnTabSelectListener; import com.jkyeo.splashview.SplashView; import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.material_design_iconic_typeface_library.MaterialDesignIconic; -import com.mikepenz.materialdrawer.AccountHeader; -import com.mikepenz.materialdrawer.AccountHeaderBuilder; -import com.mikepenz.materialdrawer.Drawer; -import com.mikepenz.materialdrawer.DrawerBuilder; -import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; -import com.mikepenz.materialdrawer.model.ProfileDrawerItem; -import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem; -import com.mikepenz.materialdrawer.model.SecondaryDrawerItem; -import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; -import com.mikepenz.materialdrawer.model.interfaces.IProfile; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory; import com.umeng.commonsdk.UMConfigure; @@ -108,6 +100,7 @@ import org.polaric.colorful.Colorful; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; import alibaba.fastjson.JSON; import alibaba.fastjson.JSONObject; @@ -131,26 +124,27 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn public final DeviceRemindManager deviceRemindManager = new DeviceRemindManager(this, this); public final static String MAIN_IN_ACTION_NAME = "cn.liuyanbing.surveyor.main_activity_local_receiver"; private Toolbar mToolbar; - private AccountHeader accountHeader = null; - private Drawer drawerLeft = null; + // private AccountHeader accountHeader = null; +// private Drawer drawerLeft = null; private NumberProgressBar cutDownProgressBar; private CheckBox powerOffCheckbox; private final List mFragments = new ArrayList<>(); private String[] mTitles; - private final int[] mIconUnSelectIds = new int[]{R.drawable.ic_tab_project_unselect, R.drawable.ic_ruler_unselected, R.mipmap.tab_home_unselect, R.mipmap.tab_service_unselect}; - private final int[] mIconSelectIds = new int[]{R.drawable.ic_tab_project_selected, R.drawable.ic_ruler_selected, R.mipmap.tab_home_select, R.mipmap.tab_service_select}; + private final int[] mIconUnSelectIds = new int[]{R.drawable.ic_tab_project_unselect, R.drawable.ic_ruler_unselected, R.mipmap.tab_home_unselect, R.mipmap.tab_service_unselect, R.mipmap.tab_me_unselect}; + private final int[] mIconSelectIds = new int[]{R.drawable.ic_tab_project_selected, R.drawable.ic_ruler_selected, R.mipmap.tab_home_select, R.mipmap.tab_service_select, R.mipmap.tab_me_select}; private final ArrayList mTabEntities = new ArrayList<>(); private ViewPager mViewPager; private CommonTabLayout mTabLayout; private BackupImportHelper backupImportUtil = new BackupImportHelper(this); + private MaterialDialog langDialog, unbindDeviceDialog; + + private MainActivityViewModel mainActivityViewModel; @SuppressLint("SourceLockedOrientationActivity") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (ActivateUtil.encrypt(this, "control", AppChannel.customChannel) == null) - finish(); - + mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class); EventBus.getDefault().register(this); if (isThemeDark()) { @@ -170,20 +164,27 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn VipManager.getInstance().controlSdkRefresh(this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { @Override public void onRefreshSuccess() { + if (!AppUtil.isZh() && SdkUtils.isRegCodeValidate() && !SdkUtils.isIntlCodeValidate()) {//非中文环境需要国际许可码 + DialogUtil.mDismissAlertDialog(MainActivity.this, R.string.hint, R.string.you_need_apply_for_an_international_license_code, R.string.i_know, null, null); + } else if ((AppUtil.isZh() && !VipManager.getInstance().isCnLevelExpireTimeValid() && VipManager.getInstance().isIntlLevelExpireTimeValid()) + || (!AppUtil.isZh() && VipManager.getInstance().isCnLevelExpireTimeValid() && !VipManager.getInstance().isIntlLevelExpireTimeValid())) { + if (langDialog == null || !langDialog.isShowing()) { + langDialog = new MaterialDialog.Builder(MainActivity.this).content(R.string.your_membership_is_not_available_in_the_current_language).positiveText(R.string.i_know).show(); + } + } if (!VipManager.getInstance().checkReg() - && ((VipManager.getInstance().level > 0 && VipManager.getInstance().isInExpireDate) - || (VipManager.getInstance().eduLevel > 0 && VipManager.getInstance().isEduInExpireDate) - || (VipManager.getInstance().intlLevel > 0 && VipManager.getInstance().isIntlInExpireDate) - || (VipManager.getInstance().controlLevel > 0 && VipManager.getInstance().isControlInExpireDate)) + && (VipManager.getInstance().isCnLevelExpireTimeValid() || VipManager.getInstance().isIntlLevelExpireTimeValid()) && !VipManager.getInstance().isControlBoundDevice) { - new MaterialDialog.Builder(MainActivity.this) - .title(R.string.hint) - .content(R.string.unbind_old_device_first) - .positiveText(R.string.unbind_device) - .onPositive((dialog, which) -> - startActivity(new Intent(MainActivity.this, UserInfoActivity.class))) - .negativeText(R.string.not_now) - .show(); + if (unbindDeviceDialog == null || !unbindDeviceDialog.isShowing()) { + unbindDeviceDialog = new MaterialDialog.Builder(MainActivity.this) + .title(R.string.hint) + .content(R.string.unbind_old_device_first) + .positiveText(R.string.unbind_device) + .onPositive((dialog, which) -> + startActivity(new Intent(MainActivity.this, UserInfoActivity.class))) + .negativeText(R.string.not_now) + .show(); + } } if (!StringUtils.isEmpty(SdkUtils.attach())) { JSONObject attach = JSON.parseObject(SdkUtils.attach()); @@ -242,11 +243,12 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn mTabLayout.setUnderlineColor(Color.BLACK); } } - mTitles = new String[]{getString(R.string.project), getString(R.string.survey), getString(R.string.label_manager), getString(R.string.service)}; + mTitles = new String[]{getString(R.string.project), getString(R.string.survey), getString(R.string.label_manager), getString(R.string.service), getString(R.string.me)}; mFragments.add(new ProjectListFragment()); mFragments.add(new MainSurveyFragment()); mFragments.add(new ConfigFragment()); mFragments.add(new ServiceFragment()); + mFragments.add(new MeFragment()); for (int i = 0; i < mTitles.length; i++) { mTabEntities.add(new TabEntity(mTitles[i], mIconSelectIds[i], mIconUnSelectIds[i])); } @@ -270,6 +272,7 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager())); mViewPager.setCurrentItem(0); mViewPager.setOffscreenPageLimit(4); + mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { @@ -287,140 +290,143 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn } }); - accountHeader = new AccountHeaderBuilder() - .withActivity(this) - .withCompactStyle(true) -// .withHeaderBackground(R.drawable.drawer_header) - .withProfileImagesClickable(true) - .withCurrentProfileHiddenInList(true) - .addProfiles( - new ProfileDrawerItem() - .withEmail(getString(R.string.not_log_in)) - .withIcon(R.drawable.app_logo) - .withIdentifier(1003), - new ProfileSettingDrawerItem() - .withName(getString(R.string.log_in)) - .withIcon(new IconicsDrawable(this).icon(MaterialDesignIconic.Icon.gmi_sign_in).paddingDp(5)) - .withIdentifier(1000).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { - @Override - public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { - Intent intent = new Intent(Utils.getApp(), LoginActivity.class); - intent.putExtra("finishTo", UserInfoActivity.class.getName()); - startActivity(intent); - return false; - } - })) - .withOnAccountHeaderProfileImageListener(new AccountHeader.OnAccountHeaderProfileImageListener() { - @Override - public boolean onProfileImageClick(View view, IProfile profile, boolean current) { - if (LCUser.getCurrentUser() == null) { - Intent intent = new Intent(Utils.getApp(), LoginActivity.class); - intent.putExtra("finishTo", UserInfoActivity.class.getName()); - startActivity(intent); - } else { - startActivity(new Intent(MainActivity.this, UserInfoActivity.class)); - } - return false; - } - - @Override - public boolean onProfileImageLongClick(View view, IProfile profile, boolean current) { - return false; - } - }) - .withOnlyMainProfileImageVisible(true) - .withSavedInstance(savedInstanceState) - .build(); - - IDrawerItem[] items = new IDrawerItem[]{ -// new PrimaryDrawerItem().withName(R.string.update_database).withDescription(R.string.update_database_description).withIcon(MaterialDesignIconic.Icon.gmi_upload).withIdentifier(14).withSelectable(false), -// new PrimaryDrawerItem().withName(R.string.video_tutorial).withDescription(R.string.video_tutorial_description).withIcon(MaterialDesignIconic.Icon.gmi_collection_video).withIdentifier(15).withSelectable(false), - new PrimaryDrawerItem().withName(R.string.docs).withIcon(MaterialDesignIconic.Icon.gmi_help_outline).withIdentifier(16).withSelectable(false), - new PrimaryDrawerItem().withName(R.string.tech_customer_service).withIcon(R.mipmap.icon_program_customer_service).withIdentifier(17).withSelectable(false), - new PrimaryDrawerItem().withName(R.string.app_data_backup).withIcon(MaterialDesignIconic.Icon.gmi_info_outline).withIcon(R.drawable.ic_backup).withIdentifier(24).withSelectable(false), - new PrimaryDrawerItem().withName(R.string.app_backup_import).withIcon(MaterialDesignIconic.Icon.gmi_info_outline).withIcon(R.drawable.ic_import).withIdentifier(25).withSelectable(false), - new PrimaryDrawerItem().withName(R.string.about).withIcon(MaterialDesignIconic.Icon.gmi_info_outline).withIdentifier(19).withSelectable(false) - }; - //Create the drawer - drawerLeft = new DrawerBuilder() - .withActivity(this) - .withToolbar(mToolbar) - .withAccountHeader(accountHeader) //set the AccountHeader we created earlier for the header - .addDrawerItems(items) - .addStickyDrawerItems(new SecondaryDrawerItem().withName(R.string.settings).withIcon(MaterialDesignIconic.Icon.gmi_settings).withIdentifier(20).withSelectable(false)) - .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { - @Override - public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { - if (drawerItem != null) { - switch ((int) drawerItem.getIdentifier()) { - case 14: - new AlertDialog.Builder(MainActivity.this) - .setTitle(R.string.confirm_update_database) - .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - EventBus.getDefault().post(new ProjectChangedEvent()); - } - }).setNegativeButton(R.string.cancel, null).show(); - break; - case 15: - showTutorialListDialog(); - break; - case 16: -// Intent intent16 = new Intent(); -// intent16.setClass(Utils.getApp(), AgentWebActivity.class); -// intent16.putExtra("short_url", "android_url_control_network_docs"); -// startActivity(intent16); - AgentWebActivity.navigation2( - MainActivity.this, - "android_url_control_network_docs"); - break; - case 17: -// Intent intent = new Intent(); -// intent.setClass(Utils.getApp(), AgentWebActivity.class); -// intent.putExtra("short_url", "android_url_tech_support"); -// startActivity(intent); - AgentWebActivity.navigation2( - MainActivity.this, - "android_url_tech_support" - ); - break; - case 19: - Intent intent17 = new Intent(Utils.getApp(), AboutActivity.class); - startActivity(intent17); - break; - case 20: - Intent intent18 = new Intent(Utils.getApp(), SettingsActivity.class); - startActivityForResult(intent18, 331); - break; - case 24: - BackupExportActivity.start(MainActivity.this, BackupExportActivity.class); - break; - case 25: - backupImportUtil.doImport(MainActivity.this, success -> { - if (success) { - restartApplication(); -// initProject(); - } - }); - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - drawerLeft.closeDrawer(); - } - }, 60); - - break; - - } - } - - return false; - } - }) - .withSavedInstance(savedInstanceState) - .withSelectedItem(-1) - .build(); +// accountHeader = new AccountHeaderBuilder() +// .withActivity(this) +// .withCompactStyle(true) +//// .withHeaderBackground(R.drawable.drawer_header) +// .withProfileImagesClickable(true) +// .withCurrentProfileHiddenInList(true) +// .addProfiles( +// new ProfileDrawerItem() +// .withEmail(getString(R.string.not_log_in)) +// .withIcon(R.drawable.app_logo) +// .withIdentifier(1003), +// new ProfileSettingDrawerItem() +// .withName(getString(R.string.log_in)) +// .withIcon(new IconicsDrawable(this).icon(MaterialDesignIconic.Icon.gmi_sign_in).paddingDp(5)) +// .withIdentifier(1000).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { +// @Override +// public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { +// Intent intent = new Intent(Utils.getApp(), LoginActivity.class); +// intent.putExtra("finishTo", UserInfoActivity.class.getName()); +// startActivity(intent); +// return false; +// } +// })) +// .withOnAccountHeaderProfileImageListener(new AccountHeader.OnAccountHeaderProfileImageListener() { +// @Override +// public boolean onProfileImageClick(View view, IProfile profile, boolean current) { +// if (LCUser.getCurrentUser() == null) { +// Intent intent = new Intent(Utils.getApp(), LoginActivity.class); +// intent.putExtra("finishTo", UserInfoActivity.class.getName()); +// startActivity(intent); +// } else { +// startActivity(new Intent(MainActivity.this, UserInfoActivity.class)); +// } +// return false; +// } +// +// @Override +// public boolean onProfileImageLongClick(View view, IProfile profile, boolean current) { +// return false; +// } +// }) +// .withOnlyMainProfileImageVisible(true) +// .withSavedInstance(savedInstanceState) +// .build(); +// +// IDrawerItem[] items = new IDrawerItem[]{ +//// new PrimaryDrawerItem().withName(R.string.update_database).withDescription(R.string.update_database_description).withIcon(MaterialDesignIconic.Icon.gmi_upload).withIdentifier(14).withSelectable(false), +//// new PrimaryDrawerItem().withName(R.string.video_tutorial).withDescription(R.string.video_tutorial_description).withIcon(MaterialDesignIconic.Icon.gmi_collection_video).withIdentifier(15).withSelectable(false), +// new PrimaryDrawerItem().withName(R.string.docs).withIcon(MaterialDesignIconic.Icon.gmi_help_outline).withIdentifier(16).withSelectable(false), +// new PrimaryDrawerItem().withName(R.string.tech_customer_service).withIcon(R.mipmap.icon_program_customer_service).withIdentifier(17).withSelectable(false), +// new PrimaryDrawerItem().withName(R.string.app_data_backup).withIcon(MaterialDesignIconic.Icon.gmi_info_outline).withIcon(R.drawable.ic_backup).withIdentifier(24).withSelectable(false), +// new PrimaryDrawerItem().withName(R.string.app_backup_import).withIcon(MaterialDesignIconic.Icon.gmi_info_outline).withIcon(R.drawable.ic_import).withIdentifier(25).withSelectable(false), +// new PrimaryDrawerItem().withName(R.string.about).withIcon(MaterialDesignIconic.Icon.gmi_info_outline).withIdentifier(19).withSelectable(false) +// }; +// //Create the drawer +// drawerLeft = new DrawerBuilder() +// .withActivity(this) +// .withToolbar(mToolbar) +// .withAccountHeader(accountHeader) //set the AccountHeader we created earlier for the header +// .addDrawerItems(items) +// .addStickyDrawerItems(new SecondaryDrawerItem().withName(R.string.settings).withIcon(MaterialDesignIconic.Icon.gmi_settings).withIdentifier(20).withSelectable(false)) +// .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { +// @Override +// public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { +// if (drawerItem != null) { +// switch ((int) drawerItem.getIdentifier()) { +// case 14: +// new AlertDialog.Builder(MainActivity.this) +// .setTitle(R.string.confirm_update_database) +// .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() { +// @Override +// public void onClick(DialogInterface dialog, int which) { +// EventBus.getDefault().post(new ProjectChangedEvent()); +// } +// }).setNegativeButton(R.string.cancel, null).show(); +// break; +// case 15: +// showTutorialListDialog(); +// break; +// case 16: + //帮助文档 +//// Intent intent16 = new Intent(); +//// intent16.setClass(Utils.getApp(), AgentWebActivity.class); +//// intent16.putExtra("short_url", "android_url_control_network_docs"); +//// startActivity(intent16); +// AgentWebActivity.navigation2( +// MainActivity.this, +// "android_url_control_network_docs"); +// break; +// case 17: + //技术支持 +//// Intent intent = new Intent(); +//// intent.setClass(Utils.getApp(), AgentWebActivity.class); +//// intent.putExtra("short_url", "android_url_tech_support"); +//// startActivity(intent); +// AgentWebActivity.navigation2( +// MainActivity.this, +// "android_url_tech_support" +// ); +// break; +// case 19: +// Intent intent17 = new Intent(Utils.getApp(), AboutActivity.class); +// startActivity(intent17); +// break; +// case 20: +// Intent intent18 = new Intent(Utils.getApp(), SettingsActivity.class); +// startActivityForResult(intent18, 331); +// break; +// case 24: +// BackupExportActivity.start(MainActivity.this, BackupExportActivity.class); +// break; +// case 25: + //导入 +// backupImportUtil.doImport(MainActivity.this, success -> { +// if (success) { +// restartApplication(); +//// initProject(); +// } +// }); +// new Handler().postDelayed(new Runnable() { +// @Override +// public void run() { +// drawerLeft.closeDrawer(); +// } +// }, 60); +// +// break; +// +// } +// } +// +// return false; +// } +// }) +// .withSavedInstance(savedInstanceState) +// .withSelectedItem(-1) +// .build(); } public void setCurrentTab(int position) { @@ -619,10 +625,10 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { - if (drawerLeft != null && drawerLeft.isDrawerOpen()) { - drawerLeft.closeDrawer(); - return true; - } +// if (drawerLeft != null && drawerLeft.isDrawerOpen()) { +// drawerLeft.closeDrawer(); +// return true; +// } if (mViewPager != null) { Fragment viewPagerFragment = getViewPagerFragment(this, mViewPager.getId(), mViewPager.getCurrentItem()); @@ -646,12 +652,12 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn @Override protected void onSaveInstanceState(Bundle outState) { - //add the values which need to be saved from the drawer to the bundle - if (drawerLeft != null) - outState = drawerLeft.saveInstanceState(outState); - //add the values which need to be saved from the accountHeader to the bundle - if (accountHeader != null) - outState = accountHeader.saveInstanceState(outState); +// //add the values which need to be saved from the drawer to the bundle +// if (drawerLeft != null) +// outState = drawerLeft.saveInstanceState(outState); +// //add the values which need to be saved from the accountHeader to the bundle +// if (accountHeader != null) +// outState = accountHeader.saveInstanceState(outState); super.onSaveInstanceState(outState); } @@ -684,7 +690,7 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn startActivityForResult(intent4, 331); break; case R.id.menu_activity_main_more: - openLeftDrawer(); +// openLeftDrawer(); break; } return super.onOptionsItemSelected(item); @@ -719,10 +725,10 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn } if (((App) Utils.getApp()).isUserStatusChanged) { ((App) Utils.getApp()).isUserStatusChanged = false; - if (drawerLeft != null) - drawerLeft.openDrawer(); - if (accountHeader != null) - accountHeader.toggleSelectionList(MainActivity.this); +// if (drawerLeft != null) +// drawerLeft.openDrawer(); +// if (accountHeader != null) +// accountHeader.toggleSelectionList(MainActivity.this); updateHeaderResult(); } //按照设置选项,保持屏幕常亮,放在onResume而不放在onCreate里是因为,用户更改设置后返回主页就要开始常亮了 @@ -995,34 +1001,34 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn */ public void updateHeaderResult() { Log.d("updateHeaderResult", "updateHeaderResult"); - if (drawerLeft == null || accountHeader == null) - return; - for (int i = accountHeader.getProfiles().size() - 1; i >= 0; i--) { - accountHeader.removeProfile(accountHeader.getProfiles().get(i)); - } - - if (LCUser.getCurrentUser() == null || !LCUser.getCurrentUser().isAuthenticated()) { - accountHeader.addProfiles( - new ProfileSettingDrawerItem().withName(getString(R.string.log_in)) - .withIcon(new IconicsDrawable(this).icon(MaterialDesignIconic.Icon.gmi_sign_in).paddingDp(5)) - .withIdentifier(1000).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { - @Override - public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { - Intent intent = new Intent(Utils.getApp(), LoginActivity.class); - intent.putExtra("finishTo", UserInfoActivity.class.getName()); - startActivity(intent); - return false; - } - })); - } else { - accountHeader.addProfiles(new ProfileSettingDrawerItem().withName(getString(R.string.user_info)).withIcon(new IconicsDrawable(this).icon(MaterialDesignIconic.Icon.gmi_account).paddingDp(5)).withIdentifier(1000).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { - @Override - public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { - startActivity(new Intent(MainActivity.this, UserInfoActivity.class)); - return false; - } - })); - } +// if (drawerLeft == null || accountHeader == null) +// return; +// for (int i = accountHeader.getProfiles().size() - 1; i >= 0; i--) { +// accountHeader.removeProfile(accountHeader.getProfiles().get(i)); +// } + +// if (LCUser.getCurrentUser() == null || !LCUser.getCurrentUser().isAuthenticated()) { +// accountHeader.addProfiles( +// new ProfileSettingDrawerItem().withName(getString(R.string.log_in)) +// .withIcon(new IconicsDrawable(this).icon(MaterialDesignIconic.Icon.gmi_sign_in).paddingDp(5)) +// .withIdentifier(1000).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { +// @Override +// public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { +// Intent intent = new Intent(Utils.getApp(), LoginActivity.class); +// intent.putExtra("finishTo", UserInfoActivity.class.getName()); +// startActivity(intent); +// return false; +// } +// })); +// } else { +// accountHeader.addProfiles(new ProfileSettingDrawerItem().withName(getString(R.string.user_info)).withIcon(new IconicsDrawable(this).icon(MaterialDesignIconic.Icon.gmi_account).paddingDp(5)).withIdentifier(1000).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { +// @Override +// public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { +// startActivity(new Intent(MainActivity.this, UserInfoActivity.class)); +// return false; +// } +// })); +// } updateProfileItem(); @@ -1033,13 +1039,22 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn String nickname = LCUser.getCurrentUser().getString("nickname"); LCFile avatarFile = LCUser.getCurrentUser().getLCFile("avatar"); if (!StringUtils.isEmpty(nickname)) { - ProfileDrawerItem item = new ProfileDrawerItem().withName(nickname).withEmail(LCUser.getCurrentUser().getUsername()).withIdentifier(1003); - if (avatarFile == null) { - item.withIcon(R.drawable.app_logo); - } else { - item.withIcon(avatarFile.getUrl()); +// ProfileDrawerItem item = new ProfileDrawerItem().withName(nickname).withEmail(LCUser.getCurrentUser().getUsername()).withIdentifier(1003); +// if (avatarFile == null) { +// item.withIcon(R.drawable.app_logo); +// } else { +// item.withIcon(avatarFile.getUrl()); +// } +// accountHeader.addProfiles(item); + + String avatarUrl = null; + if (avatarFile != null) { + avatarUrl = avatarFile.getUrl(); } - accountHeader.addProfiles(item); + + mainActivityViewModel.getRefreshLoginUserLiveData().setValue( + new MainUserBean(LCUser.getCurrentUser().getUsername(), + nickname, avatarUrl)); } else { LCObject userProfile = LCUser.getCurrentUser().getLCObject("profile"); if (userProfile != null) { @@ -1055,19 +1070,28 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn String nickname = avObject.getString("nickname"); LCFile avatarFile = avObject.getLCFile("avatar"); if (!StringUtils.isEmpty(nickname)) { - ProfileDrawerItem item = new ProfileDrawerItem().withName(nickname).withEmail(LCUser.getCurrentUser().getUsername()).withIdentifier(1003); - if (avatarFile == null) { - item.withIcon(R.drawable.app_logo); - } else { - item.withIcon(avatarFile.getUrl()); - } - accountHeader.addProfiles(item); +// ProfileDrawerItem item = new ProfileDrawerItem().withName(nickname).withEmail(LCUser.getCurrentUser().getUsername()).withIdentifier(1003); +// if (avatarFile == null) { +// item.withIcon(R.drawable.app_logo); +// } else { +// item.withIcon(avatarFile.getUrl()); +// } +// accountHeader.addProfiles(item); //保存到_User,下次不再查Profile LCUser.getCurrentUser().put("nickname", nickname); - if (avatarFile != null) + + String avatarUrl = null; + if (avatarFile != null) { LCUser.getCurrentUser().put("avatar", avatarFile); + avatarUrl = avatarFile.getUrl(); + } LCUser.getCurrentUser().saveInBackground().subscribe(); + + + mainActivityViewModel.getRefreshLoginUserLiveData().setValue( + new MainUserBean(LCUser.getCurrentUser().getUsername(), + nickname, avatarUrl)); } } @@ -1097,19 +1121,28 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn String nickname = list.get(0).getString("nickname"); LCFile avatarFile = list.get(0).getLCFile("avatar"); if (!StringUtils.isEmpty(nickname)) { - ProfileDrawerItem item = new ProfileDrawerItem().withName(nickname).withEmail(LCUser.getCurrentUser().getUsername()).withIdentifier(1003); - if (avatarFile == null) { - item.withIcon(R.drawable.app_logo); - } else { - item.withIcon(avatarFile.getUrl()); - } - accountHeader.addProfiles(item); +// ProfileDrawerItem item = new ProfileDrawerItem().withName(nickname).withEmail(LCUser.getCurrentUser().getUsername()).withIdentifier(1003); +// if (avatarFile == null) { +// item.withIcon(R.drawable.app_logo); +// } else { +// item.withIcon(avatarFile.getUrl()); +// } +// accountHeader.addProfiles(item); + + String avatarUrl = null; //保存到_User,下次不再查Profile LCUser.getCurrentUser().put("nickname", nickname); - if (avatarFile != null) + + if (avatarFile != null) { LCUser.getCurrentUser().put("avatar", avatarFile); + avatarUrl = avatarFile.getUrl(); + } LCUser.getCurrentUser().saveInBackground().subscribe(); + + mainActivityViewModel.getRefreshLoginUserLiveData().setValue( + new MainUserBean(LCUser.getCurrentUser().getUsername(), + nickname, avatarUrl)); } } } @@ -1127,7 +1160,10 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn } } } else { - accountHeader.addProfiles(new ProfileDrawerItem().withEmail(getString(R.string.click_avatar_to_log_in)).withIcon(R.drawable.app_logo).withIdentifier(1003)); +// accountHeader.addProfiles(new ProfileDrawerItem().withEmail(getString(R.string.click_avatar_to_log_in)).withIcon(R.drawable.app_logo).withIdentifier(1003)); + mainActivityViewModel.getRefreshLoginUserLiveData().setValue( + new MainUserBean(null, + null, null)); } } @@ -1135,8 +1171,8 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn * 开启左侧菜单 */ public void openLeftDrawer() { - if (drawerLeft != null) - drawerLeft.openDrawer(); +// if (drawerLeft != null) +// drawerLeft.openDrawer(); } @Override @@ -1151,7 +1187,7 @@ public class MainActivity extends BaseMainActivity implements Device.IDeviceConn @Override public void onDeviceConnectSucceed() { - mainActivityUtils.onDeviceConnectSuccess(); + mainActivityUtils.onDeviceConnectSucceed(); } @Override diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java index 31288db..01e45ef 100644 --- a/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java +++ b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java @@ -9,6 +9,7 @@ import android.location.Location; import android.location.LocationManager; import android.os.Build; import android.provider.Settings; +import android.view.View; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; @@ -30,12 +31,14 @@ import com.bingce.device.service.comm.emulator.EmulatorService; import com.bingce.device.service.comm.localgps.LocationService; import com.bingce.device.service.comm.localgps.NativePositioningService; import com.bingce.device.service.comm.otg.OTGCommService; -import com.bingce.device.service.comm.socket.SocketCommService; +import com.bingce.device.service.comm.socket.TsSocketService; import com.bingce.device.service.comm.spp.BTService; +import com.bingce.device.ui.ConnectLevelActivity; import com.bingce.device.ui.ConnectRtkActivity; import com.bingce.device.ui.ConnectTSActivity; import com.bingce.device.ui.utils.DeviceUtil; import com.bingce.device.ui.widget.BCProgressDialog; +import com.bingce.level.Level; import com.bingce.rtk.event.RtkSpeechEvent; import com.bingce.totalstation.TotalStation; import com.bingce.totalstation.TsConfig; @@ -95,16 +98,17 @@ public class MainActivityUtils extends AppCompatActivityProviderUtils { /** * 连接设备成功后,启动相关服务,因为Ntrip与SN无关,可以在此执行,与SN相关的服务在RtkReceivedSerialNumberEvent事件后执行 */ - public void onDeviceConnectSuccess() { + public void onDeviceConnectSucceed() { if (deviceConnectingProgressDialog != null && deviceConnectingProgressDialog.isShowing()) { deviceConnectingProgressDialog.dismiss(); } - if (!TotalStation.getInstance().isInitDone()) { + if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_TS) { TotalStation.getInstance().runnableStart(); TotalStation.getInstance().init(); + } else if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_LEVEL) { + Level.getInstance().init(); } - //记录用户联机时手机定位的大概位置 if (ActivityCompat.checkSelfPermission(/*this*/context(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { LocationManager mLocationManager = ((LocationManager) context().getSystemService(Context.LOCATION_SERVICE)); @@ -312,16 +316,16 @@ public class MainActivityUtils extends AppCompatActivityProviderUtils { } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_QXBT) { //千寻RTK需要GnssServer连接蓝牙 } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_HOTSPOT) { - if (!ServiceUtils.isServiceRunning(SocketCommService.class.getName())) { - ServiceUtils.startService(SocketCommService.class); + if (!ServiceUtils.isServiceRunning(TsSocketService.class.getName())) { + ServiceUtils.startService(TsSocketService.class); } } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_OTG) { if (!ServiceUtils.isServiceRunning(OTGCommService.class.getName())) { ServiceUtils.startService(OTGCommService.class); } } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_TPCOM) { - if (!ServiceUtils.isServiceRunning(SocketCommService.class.getName())) { - ServiceUtils.startService(SocketCommService.class); + if (!ServiceUtils.isServiceRunning(TsSocketService.class.getName())) { + ServiceUtils.startService(TsSocketService.class); } } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_PHONE_LOCATION) { if (!ServiceUtils.isServiceRunning(NativePositioningService.class.getName())) { @@ -338,7 +342,7 @@ public class MainActivityUtils extends AppCompatActivityProviderUtils { new MaterialDialog.Builder(ActivityUtils.getTopActivity()) .title(R.string.quick_connect) .content(instrumentInfo) - .positiveText(Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_TS ? R.string.connect_and_setup_station : R.string.connect) + .positiveText(R.string.connect) .negativeText(R.string.config) .neutralText(R.string.switch_instrument) .onPositive(new MaterialDialog.SingleButtonCallback() { @@ -357,6 +361,8 @@ public class MainActivityUtils extends AppCompatActivityProviderUtils { Intent intent; if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_TS) { intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); + } else if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_LEVEL) { + intent = new Intent(ActivityUtils.getTopActivity(), ConnectLevelActivity.class); } else { intent = new Intent(ActivityUtils.getTopActivity(), ConnectRtkActivity.class); } @@ -379,6 +385,8 @@ public class MainActivityUtils extends AppCompatActivityProviderUtils { Intent intent; if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_TS) { intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); + } else if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_LEVEL) { + intent = new Intent(ActivityUtils.getTopActivity(), ConnectLevelActivity.class); } else { intent = new Intent(ActivityUtils.getTopActivity(), ConnectRtkActivity.class); } @@ -389,9 +397,26 @@ public class MainActivityUtils extends AppCompatActivityProviderUtils { } private void chooseInstrumentType() { - Intent intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); - intent.putExtra("customChannel", AppChannel.customChannel); - ActivityUtils.getTopActivity().startActivity(intent); + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.choose_instrument_type) + .items(new String[]{ActivityUtils.getTopActivity().getString(R.string.total_station), ActivityUtils.getTopActivity().getString(R.string.device_type_level)}) + .itemsCallback(new MaterialDialog.ListCallback() { + @Override + public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) { + switch (which) { + case 0: + Intent intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); + intent.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent); + break; + case 1: + Intent intent2 = new Intent(ActivityUtils.getTopActivity(), ConnectLevelActivity.class); + intent2.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent2); + break; + } + } + }).show(); } @@ -413,7 +438,7 @@ public class MainActivityUtils extends AppCompatActivityProviderUtils { ServiceUtils.stopService(NativePositioningService.class); ServiceUtils.stopService(BTService.class); ServiceUtils.stopService(BleService.class); - ServiceUtils.startService(SocketCommService.class); + ServiceUtils.startService(TsSocketService.class); ThreadPoolUtil.execute(new Runnable() { @Override public void run() { diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/BackupImportHelper.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/BackupImportHelper.java index dd008db..84ca3a7 100644 --- a/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/BackupImportHelper.java +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/BackupImportHelper.java @@ -7,6 +7,7 @@ import android.content.Intent; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; public class BackupImportHelper { private ICallback callback; @@ -22,6 +23,16 @@ public class BackupImportHelper { }); } + public BackupImportHelper(Fragment fragment) { + importLauncher = fragment.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (callback == null) { + return; + } + boolean success = result != null && Activity.RESULT_OK == result.getResultCode(); + callback.onImported(success); + }); + } + public void doImport(Context context, ICallback callback) { this.callback = callback; Intent intent = MigrationFolder2PrivateRoomActivity.intent(context, true); diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/ZipMigrationUtils.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/ZipMigrationUtils.java index 312ad15..2dbf664 100644 --- a/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/ZipMigrationUtils.java +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/ZipMigrationUtils.java @@ -89,7 +89,7 @@ public class ZipMigrationUtils { private static File[] unzipBackupFile(File duplicate, File unzipFolder, String errorString) { if (!unzipFolder.exists()) { - if (!unzipFolder.mkdir()) { + if (!unzipFolder.mkdirs()) { ToastUtils.showShort("解压备份文件失败"); return null; } @@ -102,7 +102,7 @@ public class ZipMigrationUtils { ToastUtils.showShort("解压备份文件失败"); return null; } - if (!unzipFolder.mkdir()) { + if (!unzipFolder.mkdirs()) { ToastUtils.showShort("解压备份文件失败"); return null; } diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainer.java b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainer.java index 7a6a33c..c118304 100644 --- a/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainer.java +++ b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainer.java @@ -15,30 +15,6 @@ import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment; import com.bingce.controlnetwork.fragment.ToleranceDetailFragment; import com.bingce.controlnetwork.fragment.ToleranceManageFragment; import com.bingce.controlnetwork.fragment.ToleranceSelectFragment; -import com.bingce.controlnetwork.fragment.station.line.attached.LineStationAttachedSetupFragment; -import com.bingce.controlnetwork.fragment.station.line.close.LineStationCloseSetupFragment; -import com.bingce.controlnetwork.fragment.station.line.random.LineStationRandomSetupFragment; -import com.bingce.controlnetwork.fragment.station.line.single.LineStationSingleSetupFragment; -import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubleGroundSetupFragment; -import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubleUnderGroundSetupFragment; -import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellSetupFragment; - -import java.util.HashMap; -import java.util.Map; - -import com.bingce.controlnetwork.fragment.PickPointFragment; -import com.bingce.controlnetwork.fragment.PointListFragment; -import com.bingce.controlnetwork.fragment.PrismManageFragment; -import com.bingce.controlnetwork.fragment.ProjectToleranceSettingFragment; -import com.bingce.controlnetwork.fragment.SelectExportHeightTraverseFragment; -import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordFragment; -import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordWireFileFragment; -import com.bingce.controlnetwork.fragment.stationsetting.StationSettingHeightTraverseFragment; -import com.bingce.controlnetwork.fragment.stationsetting.StationSettingsFragment; -import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment; -import com.bingce.controlnetwork.fragment.ToleranceDetailFragment; -import com.bingce.controlnetwork.fragment.ToleranceManageFragment; -import com.bingce.controlnetwork.fragment.ToleranceSelectFragment; import com.bingce.controlnetwork.fragment.projectdetail.ProjectDetailHeightTraverseFragment; import com.bingce.controlnetwork.fragment.projectdetail.ProjectDetailTriangleFragment; import com.bingce.controlnetwork.fragment.station.defaultstation.DefaultStationSetupFragment; @@ -51,9 +27,18 @@ import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubl import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubleUnderGroundSetupFragment; import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellSetupFragment; import com.bingce.controlnetwork.fragment.stationdetail.SingleStationDetailAndEditFragment; +import com.bingce.controlnetwork.fragment.stationsetting.StationSettingHeightTraverseFragment; +import com.bingce.controlnetwork.fragment.stationsetting.StationSettingsFragment; import com.bingce.controlnetwork.fragment.stationsurvey.StationSurveyorFragment; import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; import com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse.MeasureHeightTraverseFragment; +import com.bingce.controlnetwork.func.level.fragment.LevelRouteCreateEditFragment; +import com.bingce.controlnetwork.func.level.fragment.LevelSelectExportFragment; +import com.bingce.controlnetwork.func.level.fragment.LevelSurveyFragment; +import com.bingce.controlnetwork.func.level.fragment.ProjectDetailLevelFragment; + +import java.util.HashMap; +import java.util.Map; public class FragmentContainer { private interface IBuilder { @@ -91,6 +76,10 @@ public class FragmentContainer { factory.put(MeasureHeightTraverseFragment.TAG, MeasureHeightTraverseFragment::newInstance); factory.put(SelectExportHeightTraverseFragment.TAG, SelectExportHeightTraverseFragment::newInstance); factory.put(StationSettingHeightTraverseFragment.TAG, StationSettingHeightTraverseFragment::newInstance); + factory.put(ProjectDetailLevelFragment.TAG, ProjectDetailLevelFragment::newInstance); + factory.put(LevelSurveyFragment.TAG, LevelSurveyFragment::newInstance); + factory.put(LevelSelectExportFragment.TAG, LevelSelectExportFragment::newInstance); + factory.put(LevelRouteCreateEditFragment.TAG, LevelRouteCreateEditFragment::newInstance); } public static Fragment getFragment(String tag, Bundle bundle) { diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/OpeningRenewalVipActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/OpeningRenewalVipActivity.java index bb5b8fc..b172ff9 100644 --- a/app/src/main/java/com/bingce/controlnetwork/activity/user/OpeningRenewalVipActivity.java +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/OpeningRenewalVipActivity.java @@ -96,7 +96,7 @@ public class OpeningRenewalVipActivity extends ColorfulActivity { if (total_fee <= 0) { binding.activityOpeningRenewalTvTotalFee.setText("联网获取价格"); } else { - binding.activityOpeningRenewalTvTotalFee.setText(Util.formatDouble2String(total_fee / 100.0) + "元"); + binding.activityOpeningRenewalTvTotalFee.setText(Util.formatDouble2StringDotAuto(total_fee / 100.0) + "元"); } } }); @@ -145,7 +145,7 @@ public class OpeningRenewalVipActivity extends ColorfulActivity { if (total_fee <= 0) { binding.activityOpeningRenewalTvTotalFee.setText("联网获取价格"); } else { - binding.activityOpeningRenewalTvTotalFee.setText(Util.formatDouble2String(total_fee / 100.0) + "元"); + binding.activityOpeningRenewalTvTotalFee.setText(Util.formatDouble2StringDotAuto(total_fee / 100.0) + "元"); } } catch (Exception ex) { ex.printStackTrace(); diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/RegisterActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/RegisterActivity.java index e420b66..abb5dba 100644 --- a/app/src/main/java/com/bingce/controlnetwork/activity/user/RegisterActivity.java +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/RegisterActivity.java @@ -25,8 +25,8 @@ import androidx.core.content.ContextCompat; import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; -import com.bingce.AppChannel; import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.App; import com.bingce.controlnetwork.R; import com.bingce.data.sync.utils.LeanCloudConfigLoader; import com.bingce.device.enums.SpecialDeviceEnum; @@ -36,6 +36,7 @@ import com.bingce.utils.AppUtil; import com.bingce.utils.ClipboardUtils; import com.bingce.utils.PropertiesGet; import com.bingce.utils.RegisterUtil; +import com.bingce.utils.SdkUtils; import com.bingce.utils.StringUtil; import com.bingce.utils.Util; import com.bingce.utils.VipManager; @@ -60,9 +61,6 @@ import cn.leancloud.LCException; import cn.leancloud.LCObject; import cn.leancloud.LCQuery; import cn.leancloud.LCUser; - -import com.bingce.controlnetwork.App; - import io.reactivex.Observer; import io.reactivex.disposables.Disposable; @@ -90,13 +88,8 @@ public class RegisterActivity extends ColorfulActivity { mTextViewVersion.setText("V" + AppUtils.getAppVersionName()); - if (AppChannel.customChannel != AppChannel.CUSTOM_INTERNATIONAL - && AppChannel.customChannel != AppChannel.CUSTOM_TERSUS_INTERNATIONAL - && AppChannel.customChannel != AppChannel.CUSTOM_PENTAX_INTERNATIONAL - && AppChannel.customChannel != AppChannel.CUSTOM_TUNNEL_AUTO_SCAN) { - if (!AppUtil.isZh()) {//国内发行版本在非简体中文语言下不可用 - DialogUtil.mDismissAlertDialog(this, R.string.hint, R.string.activation_can_only_use_in_simple_chinese, R.string.i_know, null, dialogInterface -> finish()); - } + if (!AppUtil.isZh() && SdkUtils.isRegCodeValidate() && !SdkUtils.isIntlCodeValidate()) {//非中文环境需要国际许可码 + DialogUtil.mDismissAlertDialog(this, R.string.hint, R.string.you_need_apply_for_an_international_license_code, R.string.i_know, null, null); } boolean isSpecial = false; @@ -152,7 +145,7 @@ public class RegisterActivity extends ColorfulActivity { if (checkStoragePermission != PackageManager.PERMISSION_GRANTED) { requestPhoneStatePermission(this); } else { - if ("SERIALNUMBERunknown".equals(RegisterUtil.getOriginalMachineCode()) || "SERIALNUMBERnull".equals(RegisterUtil.getOriginalMachineCode())) { + if ("".equals(RegisterUtil.getOriginalMachineCode()) || "SERIALNUMBERunknown".equals(RegisterUtil.getOriginalMachineCode()) || "SERIALNUMBERnull".equals(RegisterUtil.getOriginalMachineCode())) { new MaterialDialog.Builder(this) .title(R.string.hint) .content("此手机机器码未知,请关闭相关限制软件请重启软件") @@ -174,7 +167,7 @@ public class RegisterActivity extends ColorfulActivity { mBtnActivate.setText(R.string.activated); } - mMachineCode = RegisterUtil.getEncryptMachineCode(); + mMachineCode = RegisterUtil.getEncryptMachineCodeInfo(); mOriginalMachineCode = RegisterUtil.getOriginalMachineCode(); if (mMachineCode != null) { met_machine_code.setText(mMachineCode); @@ -226,14 +219,6 @@ public class RegisterActivity extends ColorfulActivity { mBtnActivate.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { - if (AppChannel.customChannel != AppChannel.CUSTOM_INTERNATIONAL - && AppChannel.customChannel != AppChannel.CUSTOM_TERSUS_INTERNATIONAL - && AppChannel.customChannel != AppChannel.CUSTOM_PENTAX_INTERNATIONAL - && AppChannel.customChannel != AppChannel.CUSTOM_TUNNEL_AUTO_SCAN) { - if (!AppUtil.isZh()) {//国内发行版本在非简体中文语言下不可用 - DialogUtil.mDismissAlertDialog(RegisterActivity.this, R.string.hint, R.string.activation_can_only_use_in_simple_chinese, R.string.i_know, null, null); - } - } final String registerCode = met_activate_code.getText().toString().trim().toUpperCase(Locale.CHINA).replaceAll(" |\n|\r", ""); if (mMachineCode == null) { ToastUtils.showShort(R.string.machine_code_illegal); @@ -267,58 +252,61 @@ public class RegisterActivity extends ColorfulActivity { if (avObjects == null || avObjects.isEmpty()) { new LCQuery<>("Device") .whereEqualTo("machineCode", mOriginalMachineCode) + .whereEqualTo("controlRegCode", registerCode) .limit(1) - .findInBackground() - .subscribe(new Observer>() { + .findInBackground().subscribe(new Observer>() { @Override - public void onSubscribe(Disposable d) { + public void onSubscribe(Disposable disposable) { } @Override - public void onNext(final List devices) { + public void onNext(List lcObjects) { if (isFinishing()) return; - if (devices != null && !devices.isEmpty() - && devices.get(0).getBoolean("activated") - && !devices.get(0).getBoolean("converted")) { - ((App) Utils.getApp()).registerCodeV2 = registerCode; - Util.putPreference("registerCodeV2", registerCode); - - VipManager.getInstance().controlSdkRefresh(RegisterActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { - @Override - public void onRefreshSuccess() { - progressDialog.dismiss(); - getSupportActionBar().setTitle(R.string.activated); - mBtnActivate.setEnabled(false); - met_activate_code.setEnabled(false); - ToastUtils.showShort(R.string.activate_success); - } - - @Override - public void onRefreshFailed(int errorCode) { - progressDialog.dismiss(); - ToastUtils.showShort(getString(R.string.error_code) + ":" + errorCode); - } - }); - //激活次数+1 - devices.get(0).increment("activationTimes"); - devices.get(0).saveInBackground().subscribe(); - } else if (devices.get(0).getBoolean("converted")) { - progressDialog.dismiss(); - ToastUtils.showShort("此设备已经兑换过年会员,无法再绑定手机"); - } else if (!devices.get(0).getBoolean("activated")) { - progressDialog.dismiss(); - ToastUtils.showShort("无法激活,请联系开发人员"); + if (!lcObjects.isEmpty()) { + if (lcObjects.get(0).getBoolean("activated") && !lcObjects.get(0).getBoolean("converted")) { + ((App) Utils.getApp()).registerCodeV2 = registerCode; + Util.putPreference("registerCodeV2", registerCode); + + VipManager.getInstance().controlSdkRefresh(RegisterActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + progressDialog.dismiss(); + getSupportActionBar().setTitle(R.string.activated); + mBtnActivate.setEnabled(false); + met_activate_code.setEnabled(false); + ToastUtils.showShort(R.string.activate_success); + } + + @Override + public void onRefreshFailed(int errorCode) { + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + ":" + errorCode); + } + }); + //激活次数+1 + lcObjects.get(0).increment("activationTimes"); + lcObjects.get(0).saveInBackground().subscribe(); + } else if (lcObjects.get(0).getBoolean("converted")) { + progressDialog.dismiss(); + ToastUtils.showShort("此设备已经兑换过年会员,无法再绑定手机"); + } else if (!lcObjects.get(0).getBoolean("activated")) { + progressDialog.dismiss(); + ToastUtils.showShort("无法激活,请联系开发人员"); + } else { + progressDialog.dismiss(); + ToastUtils.showShort(R.string.cloud_has_not_register_code); + } } else { progressDialog.dismiss(); - ToastUtils.showShort(R.string.cloud_has_not_register_code); + ToastUtils.showShort("激活码无效"); } } @Override - public void onError(Throwable e) { + public void onError(Throwable throwable) { progressDialog.dismiss(); - ToastUtils.showShort(getString(R.string.error_code) + ":" + new LCException(e).getCode()); + ToastUtils.showShort(getString(R.string.error_code) + ":" + new LCException(throwable).getCode()); } @Override diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/UserInfoActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/UserInfoActivity.java index 44c42fa..e5b3798 100644 --- a/app/src/main/java/com/bingce/controlnetwork/activity/user/UserInfoActivity.java +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/UserInfoActivity.java @@ -33,9 +33,10 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.internal.MDButton; import com.bingce.AppChannel; import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.DialogEditNicknameBinding; import com.bingce.controlnetwork.ui.WechatImagePicker; -import com.bingce.device.ui.dialog.DialogUtil; -import com.bingce.utils.AppUtil; import com.bingce.utils.DateUtils; import com.bingce.utils.FileUtil; import com.bingce.utils.LCDeviceUtil; @@ -67,11 +68,6 @@ import cn.leancloud.LCFile; import cn.leancloud.LCObject; import cn.leancloud.LCQuery; import cn.leancloud.LCUser; - -import com.bingce.controlnetwork.App; -import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.databinding.DialogEditNicknameBinding; - import de.hdodenhof.circleimageview.CircleImageView; import id.zelory.compressor.Compressor; import io.reactivex.Observer; @@ -119,13 +115,6 @@ public class UserInfoActivity extends ColorfulActivity { btn_opening_renewal = findViewById(R.id.activity_user_info_btn_opening_renewal); btn_log_out = findViewById(R.id.activity_user_info_btn_log_out); - if (AppChannel.customChannel != AppChannel.CUSTOM_CONTROL_INTERNATIONAL - && AppChannel.customChannel != AppChannel.CUSTOM_CONTROL_INTERNATIONAL_PRO) { - if (!AppUtil.isZh()) {//国内发行版本在非简体中文语言下不可用 - DialogUtil.mDismissAlertDialog(this, R.string.hint, R.string.activation_can_only_use_in_simple_chinese, R.string.i_know, null, null); - } - } - updateUserInfo(); avatarImageView.setOnClickListener(new View.OnClickListener() { @@ -294,7 +283,7 @@ public class UserInfoActivity extends ColorfulActivity { LCDeviceUtil.updateDeviceInfo("controlnetwork", ((App) Utils.getApp()).registerCodeV2, new LCDeviceUtil.OnDeviceUpdateListener() { @Override public void onUpdateSuccess() { - VipManager.getInstance().surveyorSdkRefresh(UserInfoActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + VipManager.getInstance().controlSdkRefresh(UserInfoActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { @Override public void onRefreshSuccess() { progressDialog.dismiss(); @@ -434,10 +423,7 @@ public class UserInfoActivity extends ColorfulActivity { } if (!VipManager.getInstance().checkReg() - && ((VipManager.getInstance().level > 0 && VipManager.getInstance().isInExpireDate) - || (VipManager.getInstance().eduLevel > 0 && VipManager.getInstance().isEduInExpireDate) - || (VipManager.getInstance().intlLevel > 0 && VipManager.getInstance().isIntlInExpireDate) - || (VipManager.getInstance().controlLevel > 0 && VipManager.getInstance().isControlInExpireDate)) + && (VipManager.getInstance().isCnLevelExpireTimeValid() || VipManager.getInstance().isIntlLevelExpireTimeValid()) && !VipManager.getInstance().isControlBoundDevice) { new MaterialDialog.Builder(UserInfoActivity.this) .title(R.string.hint) diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java index 7980d1f..9eec0f0 100644 --- a/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java @@ -25,7 +25,8 @@ public class PointSelectAdapter extends AbstractPointSelectAdapter { @Override public int getGroupCount() { - return data.groupCount() + 1; +// return data.groupCount() + 1; + return data.groupCount() ; } @Override diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java index b25cac5..0cadcab 100644 --- a/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java @@ -6,6 +6,7 @@ import android.widget.BaseExpandableListAdapter; import androidx.recyclerview.widget.RecyclerView; +import com.bingce.controlapphelper.interfacee.IProjectTolerance; import com.bingce.controlapphelper.model.ProjectTolerance; import com.bingce.controlapphelper.model.UniversalListItem; import com.bingce.controlapphelper.model.ViewItemType; @@ -22,17 +23,17 @@ import java.util.List; * 限差详情adapter * */ public class ToleranceDetailAdapter extends BaseExpandableListAdapter { - private ProjectTolerance data; + private IProjectTolerance data; private static final List childTypes = Arrays.asList( ViewItemType.nameWithBool, ViewItemType.nameWithText); - public ToleranceDetailAdapter(ProjectTolerance limit) { + public ToleranceDetailAdapter(IProjectTolerance limit) { data = limit; } - public void updateData(ProjectTolerance limit) { + public void updateData(IProjectTolerance limit) { this.data = limit; notifyDataSetChanged(); } diff --git a/app/src/main/java/com/bingce/controlnetwork/bean/MainUserBean.java b/app/src/main/java/com/bingce/controlnetwork/bean/MainUserBean.java new file mode 100644 index 0000000..1311f4b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/bean/MainUserBean.java @@ -0,0 +1,13 @@ +package com.bingce.controlnetwork.bean; + +public class MainUserBean { + public String userName; + public String nickName; + public String avator; + + public MainUserBean(String userName, String nickName, String avator) { + this.userName = userName; + this.nickName = nickName; + this.avator = avator; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/event/RefreshEvent.java b/app/src/main/java/com/bingce/controlnetwork/event/RefreshEvent.java new file mode 100644 index 0000000..b8204fc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/event/RefreshEvent.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.event; + +public class RefreshEvent { + public static final int REFRESH_BY_LEVEL_I_DETECTION_SETTING_UPDATE = 3; + + private int type; + private T data; + + public RefreshEvent(int type, T data) { + this.type = type; + this.data = data; + } + + public int getType() { + return type; + } + + public T getData() { + return data; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/event/RefreshToleranceTotailEvent.java b/app/src/main/java/com/bingce/controlnetwork/event/RefreshToleranceTotailEvent.java new file mode 100644 index 0000000..b55964f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/event/RefreshToleranceTotailEvent.java @@ -0,0 +1,4 @@ +package com.bingce.controlnetwork.event; + +public class RefreshToleranceTotailEvent { +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java index 64e8bb2..fc8333b 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java @@ -14,12 +14,10 @@ import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import com.bingce.controlapphelper.model.IUniversalListItem; - -import org.jetbrains.annotations.NotNull; - import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; -import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; + +import org.jetbrains.annotations.NotNull; public abstract class AbstractHierarchicalListFragment extends Fragment { private View layout1; @@ -32,7 +30,7 @@ public abstract class AbstractHierarchicalListFragment extends Fragment { private RecyclerView recyclerView2; private boolean is1Layout = true;//通知当前显示的是layout1还是layout2 private int currentListIndex = 0;//当前显示的list在所有集合中的index - private final IndexWithTextAdapter.IOnItemClick callback = item -> onItemClicked(currentListIndex, item); + private final IndexWithTextAdapter.IOnItemClick> callback = item -> onItemClicked(currentListIndex, item); @Nullable @org.jetbrains.annotations.Nullable @@ -121,7 +119,7 @@ public abstract class AbstractHierarchicalListFragment extends Fragment { RecyclerView recyclerView1, RecyclerView recyclerView2, AbstractHierarchicalListFragment fragment, - final IndexWithTextAdapter.IOnItemClick callback, + final IndexWithTextAdapter.IOnItemClick> callback, boolean targetLayoutIsLayout1, int listIndex, boolean moveForward) { @@ -174,14 +172,14 @@ public abstract class AbstractHierarchicalListFragment extends Fragment { } //通知child,通知list的item被点击,下一步执行 forward或结束加载 - protected abstract void onItemClicked(int currentListIndex, Item item); + protected abstract void onItemClicked(int currentListIndex, IUniversalListItem item); //通知child,准备back,用于加载数据 protected abstract void onBackClicked(int currentListIndex); //通知child,加载相应list的数据 protected abstract void setupList(int listIndex, TextView title, RecyclerView recyclerView, - final IndexWithTextAdapter.IOnItemClick callback); + final IndexWithTextAdapter.IOnItemClick> callback); protected static class Item implements IUniversalListItem { private final String name; diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java index d5baa5d..e55b8ea 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java @@ -11,23 +11,21 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import androidx.fragment.app.Fragment; -import com.bingce.controlapphelper.datasource.database.ProjectType; -import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; -import com.bingce.controlapphelper.datasource.database.ToleranceTemplate; -import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetailDataSource; -import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; -import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupConstants; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil; import com.bingce.controlapphelper.model.BundleConstants; import com.bingce.controlapphelper.util.ToleranceUtil; -import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.fragment.base.BaseFragment; import com.bingce.controlnetwork.ui.ViewUtil; import com.bingce.controlnetwork.ui.widget.TextItemWithMore; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; +import com.bingce.utils.IOnSingleGetCallback; import com.bingce.utils.ThreadPoolUtil; -import java.util.List; +import com.bingce.controlnetwork.R; /* * 项目限差详情,包含'LimitDetailFragment'+选择模板 @@ -61,42 +59,26 @@ public abstract class AbstractProjectToleranceFragment extends BaseFragment { * * @param projectType */ - protected ToleranceDetailRecord getFirstDefaultTolerance(String projectType) { - return ProjectType.getTarget(projectType, (projectTypeBack) -> { - List list = null; - if (projectTypeBack == ProjectType.TRIANGLE) { - list = ToleranceTemplate.detailListOfGroup(ToleranceGroupConstants.VALUE_MUL_CYCLE_ANGLE); - } else if (projectTypeBack == ProjectType.CONNECTION) { - list = ToleranceTemplate.detailListOfGroup(ToleranceTemplate.CITY_GROUP_ID); - } else if (projectTypeBack == ProjectType.HEIGHT_TRAVERSE) { - list = ToleranceTemplate.detailListOfGroup(ToleranceGroupConstants.VALUE_HEIGHT_TRAVERSE); - } - if (list != null && !list.isEmpty()) { - return list.get(0); - } - return null; - }); + protected IToleranceDetail getNewDefaultTolerance(String projectType) { + return ToleranceLoadUtil.getToleranceLoad(projectType).getNewDefaultTolerance(projectType); } protected abstract void onCreateView(View view); - protected void setCurrentToleranceName(View view, ToleranceDetailRecord toleranceRecord) { + protected void setCurrentToleranceName(View view, IToleranceDetail toleranceRecord) { View tv = view.findViewById(R.id.setting_index); - ThreadPoolUtil.execute(new Runnable() { - @Override - public void run() { - if (toleranceRecord == null) { - return; + ThreadPoolUtil.execute(() -> { + if (toleranceRecord == null) return; + IToleranceOperate operate = ToleranceOperateUtil.getOperate(toleranceRecord.getId()); + if (operate == null) return; + ToleranceGroupRecord group = operate.getGroup(toleranceRecord); + ToleranceLevelRecord level = operate.getLevel(toleranceRecord); + String name = ToleranceUtil.completedToleranceName(group, level, toleranceRecord); + runOnUI(() -> { + if (tv instanceof TextItemWithMore) { + ((TextItemWithMore) tv).setDescribeText(name); } - ToleranceGroupRecord groupRecord = ToleranceTemplate.groupOf(toleranceRecord.groupId); - ToleranceLevelRecord levelRecord = ToleranceTemplate.levelOf(toleranceRecord.levelId); - String name = ToleranceUtil.completedToleranceName(groupRecord, levelRecord, toleranceRecord); - runOnUI(() -> { - if (tv instanceof TextItemWithMore) { - ((TextItemWithMore) tv).setDescribeText(name); - } - }); - } + }); }); } @@ -109,11 +91,10 @@ public abstract class AbstractProjectToleranceFragment extends BaseFragment { */ @WorkerThread protected void onSelectToleranceTemplateClick() { - IToleranceDetailDataSource toleranceDetailDataSource = - SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); - //缓存+数据库中获取 - ToleranceDetailRecord toleranceDetailRecord = toleranceDetailDataSource.getRecordSync(currentToleranceDetailRecordId); - if (toleranceDetailRecord == null) { + IToleranceOperate operate = ToleranceOperateUtil.getOperate(currentToleranceDetailRecordId); + if (operate == null) return; + IToleranceDetail toleranceDetailRecordTj = operate.getIToleranceDetail(currentToleranceDetailRecordId); + if (toleranceDetailRecordTj == null) { return; } @@ -122,21 +103,17 @@ public abstract class AbstractProjectToleranceFragment extends BaseFragment { getChildFragmentManager(), getViewLifecycleOwner(), projectType, - toleranceDetailRecord.getGroupId(), - toleranceDetailRecord.getLevelId(), - toleranceDetailRecord.getId(), + toleranceDetailRecordTj.getGroupId(), + toleranceDetailRecordTj.getLevelId(), + toleranceDetailRecordTj.getId(), toleranceId -> ThreadPoolUtil.execute(() -> { //根据toleranceId查找缓存数据 - ToleranceDetailRecord instance = - SurveyorDatabaseFactory.instance.getToleranceDetailDataSource().getRecordSync(toleranceId); + IToleranceDetail instance = operate.getIToleranceDetail(toleranceId); //更新页面数据 updateToleranceDetail(getView(), instance); -// //新增 - if (instance != null) { - //这里增加存入数据库 已备杀死app后能获取到限差数据 - SurveyorDatabaseFactory.instance.getToleranceDetailDataSource().record(instance); - } - + //新增 + //这里增加存入数据库 已备杀死app后能获取到限差数据 + operate.saveToleranceDetail(instance); }) )); } @@ -145,8 +122,14 @@ public abstract class AbstractProjectToleranceFragment extends BaseFragment { currentToleranceDetailRecordId = toleranceId; } + protected void newToleranceDetailFragment(Bundle args, IOnSingleGetCallback callback) { + if (callback != null) { + callback.onGet(ToleranceDetailFragment.newInstance(args, false)); + } + } + @WorkerThread - protected void updateToleranceDetail(View view, ToleranceDetailRecord tolerance) { + protected void updateToleranceDetail(View view, IToleranceDetail tolerance) { if (tolerance == null) { return; } @@ -162,13 +145,13 @@ public abstract class AbstractProjectToleranceFragment extends BaseFragment { if (getArguments() != null) { args.putString(BundleConstants.KEY_TOLERANCE_ID, tolerance.getId()); } - getParentFragmentManager() + newToleranceDetailFragment(args, detailFragmentInstance -> getParentFragmentManager() .beginTransaction() - .replace(R.id.fragment_container, ToleranceDetailFragment.newInstance(args), AbstractProjectToleranceFragment.class.getName()) - .commit(); + .replace(R.id.fragment_container, detailFragmentInstance, AbstractProjectToleranceFragment.class.getName()) + .commit()); } else { if (detailFragment instanceof ToleranceDetailFragment) { - ((ToleranceDetailFragment) detailFragment).changeTolerance(tolerance.getId()); + ((ToleranceDetailFragment) detailFragment).switchTolerance(tolerance.getId()); } } }); diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java index dcfb5d0..50cd386 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java @@ -2,6 +2,7 @@ package com.bingce.controlnetwork.fragment; import android.content.Context; import android.os.Bundle; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -27,16 +28,15 @@ import com.bingce.controlapphelper.surveyor.state.ISurveyState; import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; import com.bingce.controlapphelper.util.DigitalUtil; import com.bingce.controlapphelper.util.IUIRunner; -import com.bingce.controlnetwork.adapter.SurveyorStationRecordsAdapter; -import com.bingce.controlnetwork.surveyor.state.angledistance.StateManager; -import com.bingce.totalstation.TotalStation; -import com.bingce.utils.ThreadPoolUtil; - import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.adapter.SurveyorStationRecordsAdapter; import com.bingce.controlnetwork.fragment.base.BaseFragment; import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; import com.bingce.controlnetwork.surveyor.state.angledistance.StateManager; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import blankj.utilcode.util.ToastUtils; /** * 测站某个测期的测量数据列表 @@ -305,6 +305,32 @@ public class ComponentStationSurveyorDataListFragment extends BaseFragment stateManager.stationAdjust(StationDataAdjustDialogFragment.TYPE_ANGLE_DISTANCE); } + /** + * 测站检测平差 + */ + public void stationCheckAdjust() { + ThreadPoolUtil.execute(() -> { + SurveyorScheduleRecord scheduleRecord = SurveyorDatabaseFactory.instance.getScheduleDataSource() + .findScheduleSync(SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null)); + if (scheduleRecord == null || SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED.equals(scheduleRecord.getStatue())) { + ToastUtils.showShort("请完成测站测量"); + return; + } + if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(scheduleRecord.getStatue())) { + //经过检测 + stateManager.stationAdjustOnly(StationDataAdjustDialogFragment.TYPE_ANGLE_DISTANCE); + } else if (SurveyorScheduleConstants.STATUE_VALUE_COMPLETED.equals(scheduleRecord.getStatue())) { + //完成测量 + String error = stateManager.stationCheckOnly(); + if (!TextUtils.isEmpty(error)) { + TipsFragment.tipsOnly(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), error); + return; + } + stateManager.stationAdjustOnly(StationDataAdjustDialogFragment.TYPE_ANGLE_DISTANCE); + } + }); + } + public void goBack() { if (stateManager == null) { return; diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java index 44be965..86ff06e 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java @@ -10,6 +10,7 @@ import androidx.annotation.Nullable; import androidx.lifecycle.LiveData; import androidx.recyclerview.widget.RecyclerView; +import com.bingce.controlapphelper.datasource.database.ProjectType; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; import com.bingce.controlapphelper.model.BundleConstants; @@ -18,6 +19,7 @@ import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.adapter.SurveyorStationListAdapter; import com.bingce.controlnetwork.fragment.base.BaseFragment; import com.bingce.controlnetwork.fragment.stationdetail.SingleStationDetailAndEditFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.StationSurveyorFragment; import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; import com.bingce.utils.ThreadPoolUtil; @@ -56,7 +58,11 @@ public class ComponentSurveyorStationListFragment extends BaseFragment { SingleStationDetailAndEditFragment.start(getContext(), stationId, stationName, item.getProjectId()); } else { //StationSurveyorFragment原始测量页 - MeasureFragment.start(getContext(), stationId, stationName); + if (ProjectType.isConnection(item.projectType)) { + MeasureFragment.start(getContext(), stationId, stationName); + } else { + StationSurveyorFragment.start(getContext(), stationId, stationName); + } } }); } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java index ab5652e..258a09b 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java @@ -8,7 +8,9 @@ import androidx.recyclerview.widget.RecyclerView; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.model.IUniversalListItem; import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; import com.bingce.utils.ThreadPoolUtil; @@ -20,10 +22,6 @@ import java.util.List; import blankj.utilcode.util.ToastUtils; -import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; -import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; - /** * 选择项目和测期的组件 */ @@ -32,11 +30,11 @@ public class ComponentSwitchStationListFragment extends AbstractHierarchicalList private static final int INDEX_CYCLE_LIST = 1; private String projectId = ""; private String projectName = ""; - private SelectableIndexWithTextAdapter projectAdapter; - private SelectableIndexWithTextAdapter periodAdapter; + private SelectableIndexWithTextAdapter> projectAdapter; + private SelectableIndexWithTextAdapter> periodAdapter; @Override - protected void onItemClicked(int currentListIndex, Item item) { + protected void onItemClicked(int currentListIndex, IUniversalListItem item) { if (INDEX_PROJECT_LIST == currentListIndex) { projectId = item.getId(); projectName = item.getName(); @@ -60,7 +58,7 @@ public class ComponentSwitchStationListFragment extends AbstractHierarchicalList @Override protected void setupList(int listIndex, TextView title, RecyclerView recyclerView, - final IndexWithTextAdapter.IOnItemClick callback) { + IndexWithTextAdapter.IOnItemClick> callback) { if (INDEX_PROJECT_LIST == listIndex) { //加载 if (title != null) { @@ -75,7 +73,7 @@ public class ComponentSwitchStationListFragment extends AbstractHierarchicalList if (getArguments() != null) { selectedProject = getArguments().getString(KEY_PROJECT_ID); } - List items = new ArrayList<>(); + List> items = new ArrayList<>(); int targetIndex = 0; for (int index = 0; index < projectRecords.size(); index++) { ProjectRecord projectRecord = projectRecords.get(index); @@ -105,7 +103,7 @@ public class ComponentSwitchStationListFragment extends AbstractHierarchicalList ThreadPoolUtil.execute(() -> { List periodRecords = SurveyorDatabaseFactory.instance .getSurveyorPeriod().getDataListSyncByProjectId(projectId); - List items = new ArrayList<>(); + List> items = new ArrayList<>(); String selectedPeriodId = ""; if (getArguments() != null) { selectedPeriodId = getArguments().getString(KEY_CYCLE_ID); @@ -136,9 +134,6 @@ public class ComponentSwitchStationListFragment extends AbstractHierarchicalList } } - private ComponentSwitchStationListFragment() { - } - private static final String KEY_PROJECT_ID = "___project_id"; private static final String KEY_CYCLE_ID = "__cycle_id"; diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java index 9deb14e..e833c46 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java @@ -8,12 +8,14 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; -import com.bingce.controlapphelper.datasource.database.ToleranceTemplate; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetailDataSource; -import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupConstants; import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil; +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; import com.bingce.utils.ThreadPoolUtil; @@ -25,10 +27,6 @@ import java.util.List; import blankj.utilcode.util.ToastUtils; -import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; -import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; - /** * 选择限差模板的内容 @@ -41,16 +39,16 @@ public class ComponentSwitchToleranceFragment extends AbstractHierarchicalListFr private String groupId = ""; private String levelId = ""; private String toleranceId = ""; - private SelectableIndexWithTextAdapter adapterGroup = null; - private SelectableIndexWithTextAdapter adapterLevel = null; - private SelectableIndexWithTextAdapter adapterDetail = null; + private SelectableIndexWithTextAdapter> adapterGroup = null; + private SelectableIndexWithTextAdapter> adapterLevel = null; + private SelectableIndexWithTextAdapter> adapterDetail = null; @Override - protected void onItemClicked(int currentListIndex, Item item) { + protected void onItemClicked(int currentListIndex, IUniversalListItem item) { if (INDEX_GROUP == currentListIndex) { groupId = item.getId(); //检测目标group是否有level,如果没有直接进入detail - List levelRecordList = ToleranceTemplate.levelListOf(projectType, groupId); + List levelRecordList = ToleranceLoadUtil.getToleranceLoad(projectType).levelListOf(projectType, groupId); if (levelRecordList.isEmpty()) { levelId = ""; forward2(INDEX_TOLERANCE); @@ -61,11 +59,15 @@ public class ComponentSwitchToleranceFragment extends AbstractHierarchicalListFr levelId = item.getId(); forward2(INDEX_TOLERANCE); } else { - SelectedToleranceEvent result = new SelectedToleranceEvent(item.getId()); - EventBus.getDefault().post(result); + callBackData(item.getId()); } } + private void callBackData(String id) { + SelectedToleranceEvent result = new SelectedToleranceEvent(id); + EventBus.getDefault().post(result); + } + @Override protected int preIndexOf(int index) { if (INDEX_TOLERANCE == index) { @@ -95,29 +97,27 @@ public class ComponentSwitchToleranceFragment extends AbstractHierarchicalListFr @Override protected void setupList(int listIndex, TextView title, RecyclerView recyclerView, - final IndexWithTextAdapter.IOnItemClick callback) { + final IndexWithTextAdapter.IOnItemClick> callback) { if (INDEX_GROUP == listIndex) { if (title != null) { title.setText(R.string.tips_please_select_tolerance_group); } -// List toleranceGroupRecords = ToleranceTemplate.allGroups(); - List toleranceGroupRecords = ToleranceTemplate.getGroupFromType(projectType); - List items = new ArrayList<>(); + List toleranceGroupRecords = ToleranceLoadUtil.getToleranceLoad(projectType).getGroupFromType(projectType); + List> items = new ArrayList<>(); int targetIndex = 0; - Item customGroup = null; + IUniversalListItem customGroup = null; int index = -1; for (ToleranceGroupRecord toleranceGroupRecord : toleranceGroupRecords) { - Item item = new Item(toleranceGroupRecord.getName(), toleranceGroupRecord.getId()); if (toleranceGroupRecord.isDeleted()) { continue; } if (ToleranceGroupConstants.VALUE_CUSTOM_GROUP.equals(toleranceGroupRecord.getId())) { - customGroup = item; + customGroup = toleranceGroupRecord; continue; } index++; - items.add(item); - if (groupId.equals(item.getId())) { + items.add(toleranceGroupRecord); + if (groupId.equals(toleranceGroupRecord.getId())) { targetIndex = index; } } @@ -139,14 +139,13 @@ public class ComponentSwitchToleranceFragment extends AbstractHierarchicalListFr if (title != null) { title.setText(R.string.tips_please_select_tolerance_level); } - List toleranceLevelRecords = ToleranceTemplate.levelListOf(projectType, groupId); - List items = new ArrayList<>(); + List toleranceLevelRecords = ToleranceLoadUtil.getToleranceLoad(projectType).levelListOf(projectType, groupId); + List> items = new ArrayList<>(); int targetIndex = 0; for (int index = 0; index < toleranceLevelRecords.size(); index++) { ToleranceLevelRecord toleranceLevelRecord = toleranceLevelRecords.get(index); - Item item = new Item(toleranceLevelRecord.getName(), toleranceLevelRecord.getId()); - items.add(item); - if (levelId != null && levelId.equals(item.getId())) { + items.add(toleranceLevelRecord); + if (levelId != null && levelId.equals(toleranceLevelRecord.getId())) { targetIndex = index; } } @@ -161,28 +160,35 @@ public class ComponentSwitchToleranceFragment extends AbstractHierarchicalListFr ThreadPoolUtil.execute(() -> { IToleranceDetailDataSource toleranceDetailDataSource = SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); - List toleranceDetailRecords; + List toleranceDetailList; int titleRes = R.string.tips_please_select_instrument_precision; if (levelId == null || levelId.isEmpty()) {//自定义模板 - toleranceDetailRecords = toleranceDetailDataSource.getDataListByGroup(groupId); + toleranceDetailList = ToleranceLoadUtil.getToleranceLoad(projectType).getDetailListByGroup(groupId); //选择模板 titleRes = R.string.tips_please_select_custom_tolerance; } else { - toleranceDetailRecords = ToleranceTemplate.detailListOfLevel(projectType, levelId); + toleranceDetailList = ToleranceLoadUtil.getToleranceLoad(projectType).detailListOfLevel(projectType, levelId); } + + if (!ToleranceGroupConstants.VALUE_CUSTOM_GROUP.equals(groupId) && + toleranceDetailList != null && toleranceDetailList.size() == 1) { + callBackData(toleranceDetailList.get(0).getId()); + return; + } + + int finalTitleRes = titleRes; runOnUI(() -> { if (title != null) { title.setText(finalTitleRes); } }); - List items = new ArrayList<>(); + List> items = new ArrayList<>(); int targetIndex = 0; - for (int index = 0; index < toleranceDetailRecords.size(); index++) { - ToleranceDetailRecord toleranceDetailRecord = toleranceDetailRecords.get(index); - Item item = new Item(toleranceDetailRecord.getName(), toleranceDetailRecord.getId()); - items.add(item); - if (toleranceId.equals(item.getId())) { + for (int index = 0; index < toleranceDetailList.size(); index++) { + IToleranceDetail toleranceDetailRecordTj = toleranceDetailList.get(index); + items.add((IUniversalListItem) toleranceDetailRecordTj); + if (toleranceId.equals(toleranceDetailRecordTj.getId())) { targetIndex = index; } } @@ -218,9 +224,6 @@ public class ComponentSwitchToleranceFragment extends AbstractHierarchicalListFr } } - private ComponentSwitchToleranceFragment() { - } - private static final String KEY_PROJECT_TYPE = "___PROJECT_TYPE___"; private static final String KEY_GROUP = "___GROUP___"; private static final String KEY_LEVEL = "___LEVEL___"; diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt index ddbd980..93bd353 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt @@ -9,6 +9,8 @@ import androidx.fragment.app.Fragment import com.bingce.controlapphelper.datasource.database.ProjectType import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord import com.bingce.controlapphelper.datasource.database.project.ProjectRecord import com.bingce.controlapphelper.datasource.database.route.RouteRecord import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord @@ -19,6 +21,7 @@ import com.bingce.controlnetwork.fragment.base.BaseFragment import com.bingce.controlnetwork.fragment.bottompage.BottomBean import com.bingce.controlnetwork.fragment.bottompage.BottomPageFragment import com.bingce.controlnetwork.fragment.bottompage.IData +import com.bingce.controlnetwork.func.level.fragment.LevelSurveyorHomeFragment import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope import kotlinx.coroutines.cancel @@ -37,7 +40,7 @@ class MainSurveyFragment : BaseFragment() { private val scope = MainScope() //筛选项目的项目类型 - private var selectProjectTypeTag: String? = null + private var selectProjectType: String? = null override fun onCreateView( inflater: LayoutInflater, @@ -80,7 +83,7 @@ class MainSurveyFragment : BaseFragment() { selectData[0].name, selectData[1].name ) - if (isHeightTraverse()) { + if (ProjectType.isHeightTraverse(selectProjectType)) { switchContent( title, SurveyorRouteStationFragment.newInstance( @@ -88,6 +91,15 @@ class MainSurveyFragment : BaseFragment() { selectData[1].id ) ) + } else if (ProjectType.isLevel(selectProjectType)) { + switchContent( + title, + LevelSurveyorHomeFragment.newInstance( + selectData[0].id, + selectData[1].id, + false + ) + ) } else { switchContent( title, @@ -126,15 +138,26 @@ class MainSurveyFragment : BaseFragment() { //二级数据 val projectRecord = SurveyorDatabaseFactory.instance.projectDataSource.getRecord(bottomBean.id) - selectProjectTypeTag = projectRecord.getProjectType() - if (isHeightTraverse()) { + selectProjectType = projectRecord.getProjectType() + if (ProjectType.isHeightTraverse(selectProjectType)) { val routeList = SurveyorDatabaseFactory.instance.getRouteDataSource() .getByProjectId(bottomBean.id) for (routeRecord in routeList) { dataList.add( BottomBean( routeRecord.getId(), routeRecord.name, - 1, tag = selectProjectTypeTag + 1, tag = selectProjectType + ) + ) + } + } else if (ProjectType.isLevel(selectProjectType)) { + val routeList = LevelingDbFactory.instance.levelDataSource + .getByProjectId(bottomBean.id) + for (routeRecord in routeList) { + dataList.add( + BottomBean( + routeRecord.getId(), routeRecord.name, + 1, tag = selectProjectType ) ) } @@ -145,7 +168,7 @@ class MainSurveyFragment : BaseFragment() { dataList.add( BottomBean( periodItem.getId(), periodItem.getName(), - 1, tag = selectProjectTypeTag + 1, tag = selectProjectType ) ) } @@ -159,8 +182,10 @@ class MainSurveyFragment : BaseFragment() { override fun getTitle(pageIndex: Int): String { return if (pageIndex == 0) { Tools.getString(R.string.please_select_an_project) - } else if (selectProjectTypeTag != null && pageIndex == 1) { - if (isHeightTraverse()) { + } else if (selectProjectType != null && pageIndex == 1) { + if (ProjectType.isHeightTraverse(selectProjectType) + || ProjectType.isLevel(selectProjectType) + ) { Tools.getString(R.string.please_select_an_route) } else { Tools.getString(R.string.please_select_an_period) @@ -181,9 +206,11 @@ class MainSurveyFragment : BaseFragment() { switchContent(null, null) return@launch } - - if (projectRecord.getProjectType() == ProjectType.HEIGHT_TRAVERSE.flag) { + val projectType = projectRecord.getProjectType() + if (ProjectType.isHeightTraverse(projectType)) { loadHeightTraverseData(projectRecord) + } else if (ProjectType.isLevel(projectType)) { + loadLevelData(projectRecord) } else { loadNotHeightTraverseData(projectRecord) } @@ -231,6 +258,23 @@ class MainSurveyFragment : BaseFragment() { ) } + private suspend fun loadLevelData(projectRecord: ProjectRecord) { + val routeRecord = getLevelRouteRecord(projectRecord.getId()) + val fragment = + if (routeRecord == null) + EmptyFragment() + else LevelSurveyorHomeFragment.newInstance( + projectRecord.getId(), + routeRecord.getId(), + false + ) + + switchContent( + getFilterTitle(projectRecord.getProjectName(), routeRecord?.routeName), + fragment + ) + } + private fun getFilterTitle(projectName: String, secondName: String?): String { val suffix = if (secondName == null) "" else " > $secondName" return projectName + suffix @@ -302,9 +346,21 @@ class MainSurveyFragment : BaseFragment() { } } - private fun isHeightTraverse(): Boolean { - return selectProjectTypeTag == ProjectType.HEIGHT_TRAVERSE.flag + private suspend fun getLevelRouteRecord( + projectId: String, + ): LevelRouteRecord? { + return withContext(Dispatchers.IO) { + val defaultRouteId = SurveyorDatabaseFactory.instance + .configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_ROUTE_ID)?.configValue + val routeRecord = + LevelingDbFactory.instance.levelDataSource + .getByIdSync(defaultRouteId) + if (routeRecord != null) { + return@withContext routeRecord + } + LevelingDbFactory.instance.levelDataSource + .getDefault(projectId) + } } - } \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PickPointFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PickPointFragment.java index 494c36e..6fb2bd0 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/PickPointFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PickPointFragment.java @@ -17,6 +17,8 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; @@ -36,6 +38,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; + public class PickPointFragment extends BaseFragment { public static final String TAG = PickPointFragment.class.getName(); AbstractPointSelectAdapter adapter; @@ -59,8 +62,9 @@ public class PickPointFragment extends BaseFragment { ThreadPoolUtil.execute(() -> { IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); - List globalControlPoints = pointDataSource - .getListByProjectId(PointRecord.GLOBAL_CONTROL_POINT_PROJECT_ID, PointRecord.TYPE_GLOBAL_POINT); + //去掉全局控制点 +// List globalControlPoints = pointDataSource +// .getListByProjectId(PointRecordTj.GLOBAL_CONTROL_POINT_PROJECT_ID, PointRecordTj.TYPE_GLOBAL_POINT); KnownAndUnknownPoints knownAndUnknownPoints = KnownAndUnknownPoints.loadData(false, filterId, projectId); @@ -78,14 +82,15 @@ public class PickPointFragment extends BaseFragment { //过滤全局控制点 List others = new ArrayList<>(); - for (PointRecord pointRecord : globalControlPoints) { - if ((filterId != null && filterId.contains(pointRecord.getId())) || - filterName.contains(pointRecord.getName()) || - knownAndUnknownPoints.containsKnownPoint(pointRecord)) { - continue; - } - others.add(pointRecord); - } + //去掉全局控制点 +// for (PointRecordTj pointRecord : globalControlPoints) { +// if ((filterId != null && filterId.contains(pointRecord.getId())) || +// filterName.contains(pointRecord.getName()) || +// knownAndUnknownPoints.containsKnownPoint(pointRecord)) { +// continue; +// } +// others.add(pointRecord); +// } adapter = new PointSelectAdapter(knownAndUnknownPoints, others, pickPointResult, finalMaxCount1, getContext()); @@ -97,6 +102,28 @@ public class PickPointFragment extends BaseFragment { } }); }); +// String pointType = getArguments().getString(KEY_POINT_TYPE); +// if (PointRecord.TYPE_KNOWN_POINT.equals(pointType)) { +// KnownAndUnknownPoints.loadKnownData(filterId, projectId, instance -> runOnUI(() -> { +// adapter = new KnownAndUnknownPointSelectAdapter(instance, pickPointResult, +// finalMaxCount1, getContext()); +// expandableListView.setAdapter(adapter); +// int groupCount = adapter.getGroupCount(); +// for (int index = 0; index < groupCount; index++) { +// expandableListView.expandGroup(index); +// } +// })); +// } else { +// KnownAndUnknownPoints.loadKnownAndUnknownData(filterId, projectId, instance -> runOnUI(() -> { +// adapter = new KnownAndUnknownPointSelectAdapter(instance, pickPointResult, +// finalMaxCount1, getContext()); +// expandableListView.setAdapter(adapter); +// int groupCount = adapter.getGroupCount(); +// for (int index = 0; index < groupCount; index++) { +// expandableListView.expandGroup(index); +// } +// })); +// } } setHasOptionsMenu(true); return view; @@ -152,23 +179,58 @@ public class PickPointFragment extends BaseFragment { }); } + public static void pickKnownPoint( Context context, + String type, + int maxCount, + String title, + ArrayList filterPointId, String projectId, + PickPointResult result, ActivityResultLauncher launcher) { + pickPoint( context, + type, maxCount, title, filterPointId, projectId, result, launcher); + } + + public static void pickKnownAndUnknownPoint(Context context, + String type, + int maxCount, + String title, + List filterPointId, String projectId, + PickPointResult result, ActivityResultLauncher launcher) { + pickPoint(context, + type, maxCount, title, filterPointId, projectId, result, launcher); + } + public static void pickPoint(Context context, - String type, - int maxCount, - String title, - List filterPointId, String projectId, - PickPointResult result, ActivityResultLauncher launcher) { + String type, + int maxCount, + String title, + List filterPointId, String projectId, + PickPointResult result, ActivityResultLauncher launcher) { +// ArrayList list = new ArrayList<>(); +// list.add(context.getString(R.string.global_control_point)); +// if (knownOnly) { +// list.add(context.getString(R.string.project_known_point)); +// } else { +// list.add(context.getString(R.string.project_known_unknown_point)); +// } +// ListDialogFragment.showList(fragmentManager, list, lifecycleOwner, (index, value) -> { if (launcher == null) { return; } Bundle args = new Bundle(); - +// if (index == 0) { +// args.putString(BundleConstants.KEY_PROJECT_ID, PointRecord.GLOBAL_CONTROL_POINT_PROJECT_ID); +// } else { args.putString(BundleConstants.KEY_PROJECT_ID, projectId); +// } +// if (knownOnly) { +// args.putString(KEY_POINT_TYPE, PointRecord.TYPE_KNOWN_POINT); +// } args.putString(KEY_TYPE, type); args.putInt(KEY_MAX_COUNT, maxCount); args.putStringArrayList(KEY_FILTER, (ArrayList) filterPointId); args.putParcelable(BundleConstants.KEY_RESULT, result); launcher.launch(FragmentContainerActivity.startIntent(context, TAG, title, args)); +// }); } public interface IOnSelectCallback { diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java index 3eef7cb..2667fa0 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java @@ -10,205 +10,174 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; +import androidx.annotation.WorkerThread; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.bingce.controlapphelper.datasource.database.ProjectType; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; -import com.bingce.controlapphelper.event.DatabaseReadyEvent; -import com.bingce.controlnetwork.adapter.ProjectListAdapter; -import com.bingce.controlnetwork.guide.GuideSequence; -import com.bingce.controlnetwork.guide.ITapTargetProvider; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.ISurveyorPeriodDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; +import com.bingce.controlapphelper.util.SurveyorRecordUtil; +import com.bingce.controlapphelper.util.ToleranceUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.projectdetail.ProjectDetailFragment; +import com.bingce.controlnetwork.fragment.projectedit.AbstractProjectEditFragment; +import com.bingce.controlnetwork.func.level.fragment.ProjectDetailLevelFragment; +import com.bingce.controlnetwork.newui.adapter.ProjectListAdapter; +import com.bingce.controlnetwork.newui.projectedit.ProjectCreateEditActivity; +import com.bingce.controlnetwork.newui.widget.selectitem.BaseSelectItemFragment; +import com.bingce.controlnetwork.newui.widget.selectitem.SelectProjectTypeFragment; +import com.bingce.controlnetwork.util.DialogUtil; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; import com.bingce.surveyor.agentweb.AgentWebActivity; import com.bingce.utils.ThreadPoolUtil; -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; import org.jetbrains.annotations.NotNull; -import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.adapter.ProjectListAdapter; -import com.bingce.controlnetwork.fragment.projectdetail.ProjectDetailFragment; -import com.bingce.controlnetwork.fragment.projectedit.AbstractProjectEditFragment; -import com.bingce.controlnetwork.guide.GuideSequence; -import com.bingce.controlnetwork.guide.ITapTargetProvider; +import java.util.List; import jp.wasabeef.recyclerview.animators.FadeInLeftAnimator; /** * 主页面-项目 */ -public class ProjectListFragment extends Fragment { +public class ProjectListFragment extends BaseFragment { private ProjectListAdapter projectListAdapter; - private final GuideSequence createProjectGuide; - private final GuideSequence modifyProjectGuide; - private final IConfigDataSource configDataSource = - SurveyorDatabaseFactory.instance.getConfigDataSource(); + private RecyclerView recyclerView; + private View createNewProject; - private static final int GUIDE_INDEX_PROJECT_NEW = 0; - private static final int GUIDE_INDEX_PROJECT_MODIFY = 0; + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_project_list, container, false); + recyclerView = view.findViewById(R.id.recycler_view_project_list); + createNewProject = view.findViewById(R.id.create_new); + return view; + } - public ProjectListFragment() { - createProjectGuide = new GuideSequence(GUIDE_INDEX_PROJECT_NEW + 1, new GuideSequence.IDelegate() { - @Override - public void show(int index, ITapTargetProvider provider) { - if (index == GUIDE_INDEX_PROJECT_NEW) { - if (getView() != null && getActivity() != null) { - provider.show4View( - getActivity(), - getView().findViewById(R.id.create_new), - getString(R.string.guide_create_new_project), null); - } - } - } + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initView(); + initListener(); + initObserver(); + } + private void initAdapter() { + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.setItemAnimator(new FadeInLeftAnimator()); + projectListAdapter = new ProjectListAdapter(requireContext()); + projectListAdapter.setAdapterContextMenu(new ContextMenuDeleteEdit() { @Override - public void dismiss(int index) { - ConfigConstants.markGuideCompleted(ConfigConstants.KEY_GUIDE_NEW_PROJECT, configDataSource); - } - }); - modifyProjectGuide = new GuideSequence(GUIDE_INDEX_PROJECT_MODIFY + 1, new GuideSequence.IDelegate() { - @Override - public void show(int index, ITapTargetProvider provider) { - if (index == GUIDE_INDEX_PROJECT_MODIFY) { - if (getView() != null && getActivity() != null) { - provider.show4View( - getActivity(), - getView().findViewById(R.id.tap_placeholder), - getString(R.string.guide_edit_project), - getString(R.string.tips_project_list_edit_describe)); - } - } + protected void delete(ProjectRecord item) { + startDeleteProject(item); } @Override - public void dismiss(int index) { - ConfigConstants.markGuideCompleted(ConfigConstants.KEY_GUIDE_MODIFY_PROJECT, configDataSource); + protected void edit(ProjectRecord item) { + startEditProject(item); } }); + projectListAdapter.setOnItemClickListener(this::goProjectDetail); + recyclerView.setAdapter(projectListAdapter); } - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_project_list, container, false); - initCreateNewProject(view); - return view; + private void initListener() { + //新建项目 + createNewProject.setOnClickListener(v -> { + //选择项目类型 + BaseSelectItemFragment.select(new SelectProjectTypeFragment(), + getChildFragmentManager(), + getViewLifecycleOwner(), + value -> goCreateOrEditProject(value, null)); + }); } /** - * 新建项目 - * - * @param view onCreateView的view + * 去新建项目或编辑项目 */ - private void initCreateNewProject(View view) { - View createNew = view.findViewById(R.id.create_new); - if (createNew != null) { - createNew.setOnClickListener(v -> { - //选择项目类型 - SelectProjectTypeFragment - .start( - getChildFragmentManager(), - getViewLifecycleOwner(), - projectType -> { - //新建项目的弹框 - AbstractProjectEditFragment.createProject(getChildFragmentManager(), requireContext(), projectType); - }); - }); + private void goCreateOrEditProject(String projctType, ProjectRecord projectRecord) { + if (ProjectType.isLevel(projctType)) { + String projectId = null; + if (projectRecord != null) { + projectId = projectRecord.getId(); + } + ProjectCreateEditActivity.launch(requireContext(), projctType, projectId); + } else { + if (projectRecord == null) { + AbstractProjectEditFragment.createProject(getChildFragmentManager(), requireContext(), projctType); + } else { + AbstractProjectEditFragment.editProject(getChildFragmentManager(), requireContext(), + projectRecord.getId(), projctType, projectRecord.getToleranceId(), projectRecord.getProjectName()); + } } } - @Override - public void onStart() { - super.onStart(); - refreshData(); - } - - @Override - public void onStop() { - super.onStop(); - if (EventBus.getDefault().isRegistered(this)) { - EventBus.getDefault().unregister(this); - } + private void initObserver() { + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getLiveDataList() + .observe(getViewLifecycleOwner(), this::addToleranceNameToProject); } - @Subscribe(threadMode = ThreadMode.MAIN) - public void onMessageEvent(DatabaseReadyEvent event) { - refreshData(); - } - private void refreshData() { - View view = getView(); - if (view == null) { - return; - } - //显示引导 + private void addToleranceNameToProject(List projectRecords) { ThreadPoolUtil.execute(() -> { - int index = -1; - if (!ConfigConstants.isGuideCompleted(ConfigConstants.KEY_GUIDE_NEW_PROJECT, configDataSource)) { - index = 0; + for (ProjectRecord record : projectRecords) { + String toleName = null; + IToleranceOperate operate = ToleranceOperateUtil.getOperate(record.getToleranceId()); + if (operate != null) { + IToleranceDetail iToleranceDetail = operate.getIToleranceDetail(record.getToleranceId()); + if (iToleranceDetail != null) { + ToleranceGroupRecord group = operate.getGroup(iToleranceDetail); + ToleranceLevelRecord level1 = operate.getLevel(iToleranceDetail); + toleName = ToleranceUtil.completedToleranceName(group, level1, iToleranceDetail); + } + } + record.toleranceName = toleName; } - int finalIndex = index; - ThreadPoolUtil.executeInMain(() -> createProjectGuide.start(finalIndex)); + refreshAdapter(projectRecords); }); + } - RecyclerView recyclerView = view.findViewById(R.id.recycler_view_project_list); - if (recyclerView.getAdapter() != null) { - return; - } - if (projectListAdapter == null) { - recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - recyclerView.setItemAnimator(new FadeInLeftAnimator()); - if (getContext() != null) { - projectListAdapter = new ProjectListAdapter( - this::goProjectDetail, - getContext(), - runnable -> { - if (getActivity() != null) { - getActivity().runOnUiThread(runnable); - } - }, - getViewLifecycleOwner(), - getChildFragmentManager()); - recyclerView.setAdapter(projectListAdapter); + private void refreshAdapter(List projectRecords) { + ThreadPoolUtil.executeInMain(() -> { + if (projectListAdapter != null) { + projectListAdapter.refreshData(projectRecords); } - } - SurveyorDatabaseFactory - .instance - .getProjectDataSource() - .getLiveDataList() - .observe(getViewLifecycleOwner(), projectRecords -> { - - projectListAdapter.updateData(projectRecords); - - //显示引导 - if (projectRecords == null || projectRecords.isEmpty()) { - return; - } - ThreadPoolUtil.execute(() -> { - int index = -1; - if (!ConfigConstants.isGuideCompleted(ConfigConstants.KEY_GUIDE_MODIFY_PROJECT, configDataSource)) { - index = 0; - } - int finalIndex = index; - ThreadPoolUtil.executeInMain(() -> modifyProjectGuide.start(finalIndex)); - }); - }); + }); } + private void initView() { + initAdapter(); + } /** * 进入项目详情 */ private void goProjectDetail(ProjectRecord item) { - ProjectDetailFragment.start(requireContext(), - item.projectType, - item.getId(), - item.getName()); + if (ProjectType.isLevel(item.projectType)) { + ProjectDetailLevelFragment.start(requireContext(), item.projectType, item.getId(), item.getName()); + } else { + ProjectDetailFragment.start(requireContext(), + item.projectType, + item.getId(), + item.getName()); + } } @Override @@ -220,11 +189,83 @@ public class ProjectListFragment extends Fragment { @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.menu_activity_project_list_help) { -// Intent intent = new Intent(Utils.getApp(), AgentWebActivity.class); -// intent.putExtra("short_url", "android_url_activity_project_list_help"); -// startActivity(intent); AgentWebActivity.navigation2(getContext(), "android_url_activity_project_list_help"); } return super.onOptionsItemSelected(item); } + + private void startEditProject(ProjectRecord item) { + goCreateOrEditProject(item.projectType, item); + } + + private void startDeleteProject(ProjectRecord item) { + //删除的时候判断是否需要更新默认项目 + ThreadPoolUtil.execute(() -> { + //检测是否有测量数据 + if (SurveyorRecordUtil.isProjectSurveyor(item.getId())) { + //弹框提示 + runOnUI(() -> TipsFragment.cancelAbleTips( + getChildFragmentManager(), + getViewLifecycleOwner(), + requireContext(), + "要删除的项目存在测量数据,是否确认删除?", + 4, + () -> ThreadPoolUtil.execute(() -> doDelete(item)))); + } else { + ThreadPoolUtil.executeInMain(() -> { + DialogUtil.showConfirmDialog(getChildFragmentManager(), getViewLifecycleOwner(), "您确定要删除该项目吗?", + Tools.getString(R.string.confirm), () -> { + ThreadPoolUtil.execute(() -> { + doDelete(item); + }); + }); + }); + } + }); + } + + @WorkerThread + private void doDelete(ProjectRecord item) { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + IConfigDataSource configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource(); + + ConfigRecord defaultProject = configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_PROJECT_ID); + + boolean needChangeDefaultProjectId = false; + if (defaultProject == null || defaultProject.getConfigValue().equals(item.getId())) { + needChangeDefaultProjectId = true; + } + + //先删除项目及关联 + projectDataSource.delete(item); + + if (needChangeDefaultProjectId) { + String projectId = ""; + String periodId = ""; + List projectRecords = projectDataSource.getDataList(); + if (projectRecords != null) { + ISurveyorPeriodDataSource surveyorPeriodDataSource = SurveyorDatabaseFactory.instance.getSurveyorPeriod(); + for (ProjectRecord projectRecord : projectRecords) { + if (projectRecord == null) { + continue; + } + List surveyorPeriodRecordList = surveyorPeriodDataSource.getDataListSyncByProjectId(projectRecord.getId()); + for (SurveyorPeriodRecord surveyorPeriodRecord : surveyorPeriodRecordList) { + if (surveyorPeriodRecord == null) { + continue; + } + periodId = surveyorPeriodRecord.getId(); + break; + } + if (!periodId.isEmpty()) { + projectId = projectRecord.getId(); + break; + } + } + } + configDataSource.set(ConfigConstants.KEY_DEFAULT_PROJECT_ID, projectId); + configDataSource.set(ConfigConstants.KEY_DEFAULT_PERIOD_ID, periodId); + } + } + } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorStationListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorStationListFragment.java deleted file mode 100644 index 62db4af..0000000 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorStationListFragment.java +++ /dev/null @@ -1,352 +0,0 @@ -package com.bingce.controlnetwork.fragment; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; -import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; -import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; -import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; -import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; -import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; -import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; -import com.bingce.controlnetwork.guide.GuideSequence; -import com.bingce.controlnetwork.guide.ITapTargetProvider; -import com.bingce.utils.IOnSingleGetCallback; -import com.bingce.utils.ThreadPoolUtil; - -import java.util.List; - -import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.fragment.base.BaseFragment; -import com.bingce.controlnetwork.guide.GuideSequence; -import com.bingce.controlnetwork.guide.ITapTargetProvider; - -/** - * 主页面-测量 - */ -public class SurveyorStationListFragment extends BaseFragment { - private final ComponentSurveyorStationListFragment fragment = ComponentSurveyorStationListFragment.newInstance("", "", false); - - private String projectId; - private String periodId; - private final GuideSequence guideSequence; - private final IConfigDataSource configDataSource = - SurveyorDatabaseFactory.instance.getConfigDataSource(); - private static final int GUIDE_INDEX_SWITCH_STATION = 0;//切换测站列表 - - public SurveyorStationListFragment() { - super(); - guideSequence = new GuideSequence(GUIDE_INDEX_SWITCH_STATION + 1, new GuideSequence.IDelegate() { - @Override - public void show(int index, ITapTargetProvider provider) { - if (GUIDE_INDEX_SWITCH_STATION == index) { - provider.show4View( - getActivity(), - findViewById(R.id.select), - getString(R.string.guide_switch_station_list), - getString(R.string.guide_switch_station_list_describe) - ); - } - } - - @Override - public void dismiss(int index) { - if (GUIDE_INDEX_SWITCH_STATION == index) { - ConfigConstants.markGuideCompleted(ConfigConstants.KEY_GUIDE_SWITCH_STATION_LIST, configDataSource); - } - } - }); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_project_surveyor_station_list_layout, container, false); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - - SurveyorDatabaseFactory - .instance - .getConfigDataSource() - .getLiveDataByKey(ConfigConstants.KEY_DEFAULT_PROJECT_ID) - .observe(getViewLifecycleOwner(), onProjectIdCallback::onGet); - } - - @Override - public void onResume() { - super.onResume(); - refreshUI(); - } - - private final IOnSingleGetCallback onSurveyorCycleRecordCallback = new IOnSingleGetCallback() { - @Override - public void onGet(SurveyorPeriodRecord instance) { - if (instance == null) { - update(projectId, ""); - return; - } - periodId = instance.getId(); - - update(projectId, periodId); - } - }; - - private final IOnSingleGetCallback onProjectRecordCallback = new IOnSingleGetCallback() { - @Override - public void onGet(ProjectRecord instance) { - if (instance == null) { - update("", ""); - return; - } - projectId = instance.id; - SurveyorDatabaseFactory - .instance - .getSurveyorPeriod() - .getDefault(projectId, onSurveyorCycleRecordCallback); - } - }; - - /** - * 第一次获取到的测其id - */ - private final IOnSingleGetCallback onSurveyorCycleCallback = new IOnSingleGetCallback() { - @Override - public void onGet(ConfigRecord instance) { - if (instance == null) { - SurveyorDatabaseFactory - .instance - .getProjectDataSource() - .getDefaultRecord(onProjectRecordCallback); - return; - } - periodId = instance.getConfigValue(); - - update(projectId, periodId); - } - }; - - /** - * 第一次获取到的默认项目id - */ - private final IOnSingleGetCallback onProjectIdCallback = new IOnSingleGetCallback() { - @Override - public void onGet(ConfigRecord instance) { - if (instance == null) { - SurveyorDatabaseFactory - .instance - .getProjectDataSource() - .getDefaultRecord(onProjectRecordCallback); - return; - } - projectId = instance.getConfigValue(); - //project是否被删除 - if (projectId == null || projectId.isEmpty()) { - update("", ""); - return; - } - - SurveyorDatabaseFactory - .instance - .getConfigDataSource() - .getByKey(ConfigConstants.KEY_DEFAULT_PERIOD_ID, onSurveyorCycleCallback); - } - }; - - private void refreshUI() { - ThreadPoolUtil.execute(() -> { - //检测当前项目列表是否为空 - IProjectDataSource projectDataSource = - SurveyorDatabaseFactory.instance.getProjectDataSource(); - if (projectDataSource.recordCount() > 0 && !ConfigConstants.isGuideCompleted(ConfigConstants.KEY_GUIDE_SWITCH_STATION_LIST, configDataSource)) { - //当项目记录数大于0并且没有提示过的时候 进行引导提示 - runOnUI(() -> guideSequence.start(GUIDE_INDEX_SWITCH_STATION)); - } - }); - } - - private void updateText(String projectName, String cycleName) { - View view = getView(); - if (view == null) { - return; - } - runOnUI(() -> { - View titleLayout = view.findViewById(R.id.title); - if (titleLayout != null && - projectName != null && !projectName.isEmpty() && - cycleName != null && !cycleName.isEmpty()) { - //当项目和测期都不为空的时候设置 - titleLayout.setVisibility(View.VISIBLE); - - TextView title = view.findViewById(R.id.titleView); - if (title != null && getContext() != null) { - String string = projectName + " > " + cycleName; - title.setText(string); - } - - titleLayout.setOnClickListener(onSwitchClickListener); - } else if (titleLayout != null) { - titleLayout.setVisibility(View.INVISIBLE); - } - }); - } - - private final View.OnClickListener onSwitchClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - //去选择项目和测期 -// SelectProjectAndSurveyorCycleFragment.select( -// getChildFragmentManager(), -// getViewLifecycleOwner(), -// projectId, -// cycleIndex, -// (pId, pName, cycleId, cycleName) -> { -// //刷新数据 -// projectId = pId; -// cycleIndex = cycleId; -// //保存默认值 -// IConfigDataSource configDataSource = -// SurveyorDatabaseFactory -// .instance -// .getConfigDataSource(); -// //数据存储 -// configDataSource.set(ConfigConstants.KEY_DEFAULT_PROJECT_ID, projectId); -// configDataSource.set(ConfigConstants.KEY_DEFAULT_CYCLE_ID, cycleIndex); -// -// updateText(pName, cycleName); -// fragment.update(pId, cycleId); -// }); - -// BottomPageFragment.showBottom(getChildFragmentManager(), getViewLifecycleOwner(), -// selectData, -// selectData -> { -// -// }); - } - }; - -// private IData selectData = new IData() { -// -// @Nullable -// @Override -// public Object getData(@Nullable BottomBean bottomBean, @NonNull Continuation> $completion) { -// return null; -// } -// -// @Override -// public String getTitle(int pageIndex) { -// if (pageIndex == 0) { -// return "请选择项目"; -// } else if (pageIndex == 1) { -// return "请选择测期"; -// } -// return ""; -// } - -// @Nullable -// @Override -// public List getData(@Nullable BottomBean bottomBean) { -// List dataList = new ArrayList<>(); -// if (bottomBean == null) { -// List projectRecords = SurveyorDatabaseFactory -// .instance -// .getProjectDataSource() -// .getDataList(); -// -// for (ProjectRecord projectRecord : projectRecords) { -// dataList.add(new BottomBean(projectRecord.getId(), projectRecord.getProjectName(), -// 0, false, null)); -// } -// -// } else { -// if (bottomBean.getPageIndex() == 0) { -// -// List periodRecords = SurveyorDatabaseFactory.instance -// .getSurveyorPeriod().getDataListSyncByProjectId(bottomBean.getId()); -// -// for (SurveyorPeriodRecord projectRecord : periodRecords) { -// dataList.add(new BottomBean(projectRecord.getId(), projectRecord.getName(), -// 1, false, null)); -// } -// -// } -// } -// -// return dataList; -// } - -// }; - - /** - * @param projectId - * @param periodId - */ - private void update(final String projectId, final String periodId) { - if (fragment == null) { - return; - } - View view = getView(); - if (view == null) { - return; - } - ThreadPoolUtil.execute(() -> { - String projectName = ""; - String cycleName = ""; - ProjectRecord projectRecord = - SurveyorDatabaseFactory - .instance - .getProjectDataSource() - .getRecord(projectId); - if (projectRecord != null) { - projectName = projectRecord.getProjectName(); - } - SurveyorPeriodRecord periodRecord = - SurveyorDatabaseFactory - .instance - .getSurveyorPeriod() - .getRecord(periodId); - if (periodRecord == null) { - //获取第一个测期 - List records = SurveyorDatabaseFactory - .instance - .getSurveyorPeriod() - .getDataListSyncByProjectId(projectId); - if (!records.isEmpty()) { - periodRecord = records.get(0); - } - } - if (periodRecord != null) { - cycleName = periodRecord.getName(); - this.periodId = periodRecord.getId(); - } - updateText(projectName, cycleName); - - this.projectId = projectId; - - fragment.update(this.projectId, this.periodId); - }); - } - - public static SurveyorStationListFragment newInstance() { - return new SurveyorStationListFragment(); - } - - private void switchContentFragment() { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.fragment_container, fragment, "___station_list") - .commit(); - } - - -} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java index d8600d2..67f10db 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java @@ -17,9 +17,12 @@ import com.bingce.controlapphelper.model.BundleConstants; import com.bingce.controlapphelper.model.ProjectTolerance; import com.bingce.controlapphelper.model.ToleranceAttributesType; import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.event.RefreshToleranceTotailEvent; import com.bingce.utils.ThreadPoolUtil; import com.rengwuxian.materialedittext.MaterialEditText; +import org.greenrobot.eventbus.EventBus; + public class ToleranceAttributeEditFragment extends AbstractFullScreenDialogFragment { @Override @@ -36,98 +39,88 @@ public class ToleranceAttributeEditFragment extends AbstractFullScreenDialogFrag return; } ProjectTolerance projectTolerance = new ProjectTolerance(record); - - setData(contentView, projectTolerance); - - }); - } - return contentView; - } - - private void setData(View contentView, ProjectTolerance projectTolerance) { - ThreadPoolUtil.executeInMain(() -> { - int attributeIndex = getArguments().getInt(KEY_ATTRIBUTE_INDEX, -1); - if (attributeIndex < 0) { - return; - } - ToleranceAttributesType type = ToleranceAttributesType.values()[attributeIndex]; - MaterialEditText editor = contentView.findViewById(R.id.editor); - SwitchCompat switchCompat = contentView.findViewById(R.id.switch_control); - View integerView = contentView.findViewById(R.id.integerValue); - - if (projectTolerance.isBoolValue(type)) { - if (editor != null) { - editor.setVisibility(View.GONE); - } - if (integerView != null) { - integerView.setVisibility(View.GONE); - } - if (switchCompat != null) { - switchCompat.setVisibility(View.VISIBLE); - switchCompat.setChecked(projectTolerance.getBoolAttribute(type)); - } - } else if (projectTolerance.isDoubleValue(type)) { - if (editor != null) { - editor.setVisibility(View.VISIBLE); - String value = String.valueOf(projectTolerance.getDoubleAttribute(type)); - editor.setText(value); - editor.setHint(value); - } - if (switchCompat != null) { - switchCompat.setVisibility(View.GONE); - } - if (integerView != null) { - integerView.setVisibility(View.GONE); - } - } else if (projectTolerance.isIntegerValue(type)) { - if (editor != null) { - editor.setVisibility(View.GONE); - } - if (switchCompat != null) { - switchCompat.setVisibility(View.GONE); + int attributeIndex = getArguments().getInt(KEY_ATTRIBUTE_INDEX, -1); + if (attributeIndex < 0) { + return; } - if (integerView != null) { - integerView.setVisibility(View.VISIBLE); - String value = String.valueOf(projectTolerance.getIntegerAttribute(type)); - TextView countView = integerView.findViewById(R.id.count); - countView.setText(value); - View left = integerView.findViewById(R.id.left); - View right = integerView.findViewById(R.id.right); - if (left != null) { - if (Integer.parseInt(value) <= 1) { - left.setEnabled(false); - } - left.setOnClickListener(v -> { - int count = Integer.parseInt(countView.getText().toString()); - countView.setText(String.valueOf(count - 1)); - if (count - 1 <= 1) {//禁止减小 - left.setEnabled(false); - } - //减小后增大变为可用 - if (right != null) { - right.setEnabled(true); - } - }); + ToleranceAttributesType type = ToleranceAttributesType.values()[attributeIndex]; + MaterialEditText editor = contentView.findViewById(R.id.editor); + SwitchCompat switchCompat = contentView.findViewById(R.id.switch_control); + View integerView = contentView.findViewById(R.id.integerValue); + if (projectTolerance.isBoolValue(type)) { + if (editor != null) { + integerView.setVisibility(View.GONE); } - if (right != null) { - right.setOnClickListener(v -> { - int count = Integer.parseInt(countView.getText().toString()); - countView.setText(String.valueOf(count + 1)); - //增大后减小变为可用 - if (left != null) { - left.setEnabled(true); - } - if (type == ToleranceAttributesType.singleSurveyor && count + 1 >= 2) { - right.setEnabled(false); + if (integerView != null) { + integerView.setVisibility(View.GONE); + } + if (switchCompat != null) { + switchCompat.setVisibility(View.VISIBLE); + switchCompat.setChecked(projectTolerance.getBoolAttribute(type)); + } + } else if (projectTolerance.isDoubleValue(type)) { + if (editor != null) { + editor.setVisibility(View.VISIBLE); + String value = String.valueOf(projectTolerance.getDoubleAttribute(type)); + editor.setText(value); + editor.setHint(value); + } + if (switchCompat != null) { + switchCompat.setVisibility(View.GONE); + } + if (integerView != null) { + integerView.setVisibility(View.GONE); + } + } else if (projectTolerance.isIntegerValue(type)) { + if (editor != null) { + editor.setVisibility(View.GONE); + } + if (switchCompat != null) { + switchCompat.setVisibility(View.GONE); + } + if (integerView != null) { + integerView.setVisibility(View.VISIBLE); + String value = String.valueOf(projectTolerance.getIntegerAttribute(type)); + TextView countView = integerView.findViewById(R.id.count); + countView.setText(value); + View left = integerView.findViewById(R.id.left); + View right = integerView.findViewById(R.id.right); + if (left != null) { + if (Integer.parseInt(value) <= 1) { + left.setEnabled(false); } - }); + left.setOnClickListener(v -> { + int count = Integer.parseInt(countView.getText().toString()); + countView.setText(String.valueOf(count - 1)); + if (count - 1 <= 1) {//禁止减小 + left.setEnabled(false); + } + //减小后增大变为可用 + if (right != null) { + right.setEnabled(true); + } + }); + } + if (right != null) { + right.setOnClickListener(v -> { + int count = Integer.parseInt(countView.getText().toString()); + countView.setText(String.valueOf(count + 1)); + //增大后减小变为可用 + if (left != null) { + left.setEnabled(true); + } + if (type == ToleranceAttributesType.singleSurveyor && count + 1 >= 2) { + right.setEnabled(false); + } + }); + } } } - } - }); + }); + } + return contentView; } - @Override protected void onConfirm() { ThreadPoolUtil.execute(() -> { @@ -169,12 +162,12 @@ public class ToleranceAttributeEditFragment extends AbstractFullScreenDialogFrag projectTolerance.setIntegerAttribute(type, Integer.parseInt(string)); } //存储数据 - projectTolerance.updateToleranceRecord(this::dismiss); - }); - } + projectTolerance.save2DataSource(() -> { + EventBus.getDefault().post(new RefreshToleranceTotailEvent()); + dismissAllowingStateLoss(); + }); - private ToleranceAttributeEditFragment() { - super(); + }); } private static final String KEY_ATTRIBUTE_INDEX = "__attribute_index___"; diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java index ee54fc5..d8989e9 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java @@ -9,61 +9,89 @@ import android.widget.ExpandableListView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.leveling.tolerance.LevelingToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; +import com.bingce.controlapphelper.interfacee.IProjectTolerance; import com.bingce.controlapphelper.model.BundleConstants; import com.bingce.controlapphelper.model.ProjectTolerance; -import com.bingce.controlapphelper.util.SurveyorRecordUtil; -import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlapphelper.model.tolerance.ProjectToleranceLeveling; import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; import com.bingce.controlnetwork.adapter.ToleranceDetailAdapter; +import com.bingce.controlnetwork.event.RefreshToleranceTotailEvent; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; import com.bingce.utils.ThreadPoolUtil; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + + /** * 限差详情页 */ public class ToleranceDetailFragment extends Fragment { public static final String TAG = ToleranceDetailFragment.class.getName(); - private String toleranceId; + private String currentToleranceId; private ToleranceDetailAdapter adapter; - private ToleranceDetailFragment() { + private ExpandableListView expandableListView; + + @Subscribe(threadMode = ThreadMode.MAIN) + public void refresh(RefreshToleranceTotailEvent event) { + refreshUi(); } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); if (getArguments() != null) { - toleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); + currentToleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + EventBus.getDefault().register(this); View view = inflater.inflate(R.layout.fragment_limit_detail_list, container, false); - if (view instanceof ExpandableListView) { - changeTolerance(toleranceId, view); - } + expandableListView = view.findViewById(R.id.list); + refreshUi(); return view; } - public void changeTolerance(String id) { - changeTolerance(id, getView()); + @Override + public void onDestroyView() { + super.onDestroyView(); + EventBus.getDefault().unregister(this); } - private void changeTolerance(String id, View view) { - toleranceId = id; - ExpandableListView expandableListView = (ExpandableListView) view; - SurveyorDatabaseFactory - .instance - .getToleranceDetailDataSource() - .getLiveDataRecord(id) - .observe(getViewLifecycleOwner(), - toleranceRecord -> - updateTolerance(expandableListView, new ProjectTolerance(toleranceRecord))); + public void switchTolerance(String id) { + currentToleranceId = id; + refreshUi(); + } + + private void refreshUi() { + IToleranceOperate operate = ToleranceOperateUtil.getOperate(currentToleranceId); + if (operate == null) { + return; + } + ThreadPoolUtil.execute(() -> { + IToleranceDetail iToleranceDetail = operate.getIToleranceDetail(currentToleranceId); + ThreadPoolUtil.executeInMain(() -> { + if (iToleranceDetail != null) { + if (iToleranceDetail instanceof LevelingToleranceDetail) { + updateTolerance(expandableListView, new ProjectToleranceLeveling((LevelingToleranceDetail) iToleranceDetail)); + } else if (iToleranceDetail instanceof ToleranceDetailRecord) { + updateTolerance(expandableListView, new ProjectTolerance((ToleranceDetailRecord) iToleranceDetail)); + } + } + }); + }); + } /** @@ -72,70 +100,68 @@ public class ToleranceDetailFragment extends Fragment { * @param expandableListView * @param projectTolerance */ - private void updateTolerance(ExpandableListView expandableListView, ProjectTolerance projectTolerance) { - if (!toleranceId.equals(projectTolerance.id())) { + private void updateTolerance(ExpandableListView expandableListView, IProjectTolerance projectTolerance) { + if (!currentToleranceId.equals(projectTolerance.id())) { return; } - boolean editableForWholeTolerance = projectTolerance.isWritable(); + boolean editable = projectTolerance.isWritable(); //填充adapter if (adapter == null) { adapter = new ToleranceDetailAdapter(projectTolerance); expandableListView.setAdapter(adapter); - //全部展开 - int groupCount = expandableListView.getCount(); - for (int index = 0; index < groupCount; index++) { - expandableListView.expandGroup(index); - } + expandAllItemView(expandableListView, projectTolerance); } else { adapter.updateData(projectTolerance); + expandAllItemView(expandableListView, projectTolerance); } //设置点击事件 expandableListView.setOnChildClickListener((parent, v, groupPosition, childPosition, viewId) -> { - checkToleranceClick(projectTolerance, groupPosition, childPosition, success -> { - if (success) { - ToleranceAttributeEditFragment - .editAndSave(toleranceId, - projectTolerance.attributesType(groupPosition, childPosition), - projectTolerance.attributesName(groupPosition, childPosition), - projectTolerance.groupName(groupPosition), - getChildFragmentManager()); - } - }); + boolean forbidModify = false; + if (getArguments() != null) { + forbidModify = getArguments().getBoolean(KEY_FORBID_MODIFY, false); + } + if (editable && !forbidModify) {//执行编辑 + ToleranceAttributeEditFragment + .editAndSave(currentToleranceId, + projectTolerance.attributesType(groupPosition, childPosition), + projectTolerance.attributesName(groupPosition, childPosition), + projectTolerance.groupName(groupPosition), + getChildFragmentManager()); + } else if (forbidModify) { + TipsFragment.tipsOnly(getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + getString(R.string.tips_tolerance_cannt_modify_because_has_surveyed)); + } else { + TipsFragment.tipsOnly(getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + getString(R.string.tips_tolerance_template_cannt_delete)); + } return true; }); } - private void checkToleranceClick(ProjectTolerance projectTolerance, int groupPosition, int childPosition, ICheckEditTolerance checkEditTolerance) { - ThreadPoolUtil.execute(() -> { - //该限差是否有项目测量数据 - boolean hasSurveyedWithToleraeId = SurveyorRecordUtil.isToleranceSurveyor(toleranceId); - - //单个点击限差是否可以编辑 - boolean editToleranceSingle = projectTolerance.isEditTolerance(groupPosition, childPosition); - - boolean isCanEditTolerance = false;//是否可以编辑限差 - if (projectTolerance.isWritable() && editToleranceSingle && !hasSurveyedWithToleraeId) { - isCanEditTolerance = true; - } else { - if (!editToleranceSingle) { - tipsError(getString(R.string.tips_tolerance_template_cannt_delete_short)); - } else if (!projectTolerance.isWritable()) { - tipsError(getString(R.string.tips_tolerance_template_cannt_delete)); - } else { - //这里统一提示有数据不能修改 - tipsError(getString(R.string.tips_tolerance_cannt_modify_because_has_surveyed)); - } - } - - checkEditTolerance.result(isCanEditTolerance); - }); + /** + * 全部展开 + * + * @param expandableListView + * @param projectTolerance + */ + private void expandAllItemView(ExpandableListView expandableListView, IProjectTolerance projectTolerance) { + int groupCount = projectTolerance.groupCount(); + for (int index = 0; index < groupCount; index++) { + expandableListView.expandGroup(index); + } } - private void tipsError(String errorMsg) { - runOnUi(() -> TipsFragment.tipsOnly(getChildFragmentManager(), - getViewLifecycleOwner(), - requireContext(), - errorMsg)); + private static final String KEY_FORBID_MODIFY = "__forbid_modify"; + + public static ToleranceDetailFragment newInstance(Bundle args, boolean forbidModify) { + ToleranceDetailFragment fragment = new ToleranceDetailFragment(); + args.putBoolean(KEY_FORBID_MODIFY, forbidModify); + fragment.setArguments(args); + return fragment; } public static ToleranceDetailFragment newInstance(Bundle args) { @@ -144,20 +170,10 @@ public class ToleranceDetailFragment extends Fragment { return fragment; } - public static void start(Context context, String toleranceId) { + public static void start(Context context, String toleranceId, boolean forbidModify) { Bundle args = new Bundle(); + args.putBoolean(KEY_FORBID_MODIFY, forbidModify); args.putString(BundleConstants.KEY_TOLERANCE_ID, toleranceId); - FragmentContainerActivity.start(context, TAG, Tools.getString(R.string.menu_item_project_tolerance_setting), args); - } - - private interface ICheckEditTolerance { - void result(boolean success); - } - - private void runOnUi(Runnable runnable) { - FragmentActivity activity = getActivity(); - if (activity != null) { - activity.runOnUiThread(runnable); - } + FragmentContainerActivity.start(context, TAG, "限差设置", args); } } \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceManageFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceManageFragment.java index 44425ed..336c84f 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceManageFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceManageFragment.java @@ -14,13 +14,16 @@ import androidx.lifecycle.LifecycleOwner; import androidx.recyclerview.widget.RecyclerView; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; -import com.bingce.controlapphelper.datasource.database.ToleranceTemplate; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetailDataSource; import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil; import com.bingce.controlapphelper.model.BundleConstants; import com.bingce.controlapphelper.surveyor.method.ToleranceMethodKt; +import com.bingce.controlapphelper.util.SurveyorRecordUtil; import com.bingce.controlapphelper.util.ToleranceUtil; import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; @@ -73,7 +76,7 @@ public class ToleranceManageFragment extends BaseFragment { getViewLifecycleOwner(), getContext(), toleranceDetailRecords, - item -> ToleranceDetailFragment.start(getContext(), item.getId())); + this::clickToleranceItem); recyclerView.setAdapter(adapter); } else { adapter.updateData(toleranceDetailRecords); @@ -87,6 +90,29 @@ public class ToleranceManageFragment extends BaseFragment { return rootView; } + /** + * 点击限差进行编辑 + * + * @param item + */ + private void clickToleranceItem(ToleranceDetailRecord item) { + ThreadPoolUtil.execute(() -> { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory + .instance.getProjectDataSource(); + List projectRecordList = projectDataSource + .getDataListByToleranceId(item.getId()); + boolean hasSurveyed = false; + for (ProjectRecord projectRecord : projectRecordList) { + if (SurveyorRecordUtil.isProjectSurveyor(projectRecord.getId())) { + hasSurveyed = true; + break; + } + } + boolean finalHasSurveyed = hasSurveyed; + runOnUI(() -> ToleranceDetailFragment.start(getContext(), item.getId(), finalHasSurveyed)); + }); + } + private void showSelectedToleranceDlg(View view) { SelectToleranceTemplateBottomSheetFragment.select( @@ -109,16 +135,17 @@ public class ToleranceManageFragment extends BaseFragment { SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); ThreadPoolUtil.execute(() -> { //先检测预置模板 - ToleranceDetailRecord toleranceDetailRecord = ToleranceTemplate.detailOf(toleranceId); + ToleranceDetailRecord toleranceDetailRecord = (ToleranceDetailRecord) ToleranceLoadUtil.getTriangleToleranceLoad().detailOf(toleranceId); if (toleranceDetailRecord == null) { toleranceDetailRecord = toleranceDetailDataSource.getRecordSync(toleranceId); } if (toleranceDetailRecord == null) { return; } + //查询限差完整名称 - ToleranceGroupRecord toleranceGroupRecord = ToleranceTemplate.groupOf(toleranceDetailRecord.groupId); - ToleranceLevelRecord toleranceLevelRecord = ToleranceTemplate.levelOf(toleranceDetailRecord.levelId); + ToleranceGroupRecord toleranceGroupRecord = ToleranceLoadUtil.getTriangleToleranceLoad().groupOf(toleranceDetailRecord.getGroupId()); + ToleranceLevelRecord toleranceLevelRecord = ToleranceLoadUtil.getTriangleToleranceLoad().levelOf(toleranceDetailRecord.getLevelId()); if (toleranceGroupRecord == null) { ToastUtils.showShort(R.string.error_tips_tolerance_template_read_failure); return; @@ -142,13 +169,13 @@ public class ToleranceManageFragment extends BaseFragment { } private static void gotoEditNewTolerance(Context context, ToleranceDetailRecord template, String name) { - ToleranceDetailRecord newInstance = new ToleranceDetailRecord(template); + ToleranceDetailRecord newInstance = template.convertCustomRecord(template); newInstance.singleSurveyor = template.singleSurveyor; newInstance.setName(name); SurveyorDatabaseFactory .instance .getToleranceDetailDataSource() - .saveWithCallback(newInstance, () -> ToleranceDetailFragment.start(context, newInstance.getId())); + .saveWithCallback(newInstance, () -> ToleranceDetailFragment.start(context, newInstance.getId(), false)); } private static class _Adapter extends BaseIndexTextWithContextMenuAdapter @@ -200,4 +227,5 @@ public class ToleranceManageFragment extends BaseFragment { fragment.setArguments(bundle); return fragment; } + } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceSelectFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceSelectFragment.java index 92505d5..cc78629 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceSelectFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceSelectFragment.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.text.TextUtils; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -14,46 +15,42 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; -import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; import com.bingce.controlapphelper.model.BundleConstants; import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; import com.bingce.utils.ThreadPoolUtil; public class ToleranceSelectFragment extends AbstractProjectToleranceFragment { public static final String TAG = ToleranceSelectFragment.class.getName(); - private ToleranceSelectFragment() { - super(); - } - @Override protected void onCreateView(View view) { String toleranceId = null; if (getArguments() != null) { toleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); - if (toleranceId != null && !toleranceId.isEmpty()) { - String finalToleranceId = toleranceId; - ThreadPoolUtil.execute(() -> { - ToleranceDetailRecord instance = - SurveyorDatabaseFactory.instance - .getToleranceDetailDataSource().getRecordSync(finalToleranceId); - updateToleranceDetail(view, instance); - }); - } - } - //当前没有限差的时候 - if (toleranceId == null || toleranceId.isEmpty()) { - if (getArguments() != null) { - ToleranceDetailRecord firstDefaultTolerance = getFirstDefaultTolerance(projectType); - updateToleranceDetail(view, firstDefaultTolerance); - } } - + initData(view, toleranceId); setHasOptionsMenu(true); } + private void initData(View view, String toleranceId) { + if (TextUtils.isEmpty(toleranceId)) { + IToleranceDetail firstDefaultTolerance = getNewDefaultTolerance(projectType); + updateToleranceDetail(view, firstDefaultTolerance); + } else { + ThreadPoolUtil.execute(() -> { + IToleranceOperate operate = ToleranceOperateUtil.getOperate(toleranceId); + if (operate != null) { + IToleranceDetail iToleranceDetail = operate.getIToleranceDetail(toleranceId); + updateToleranceDetail(view, iToleranceDetail); + } + }); + } + } + @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.tolerance_select_menu, menu); @@ -95,7 +92,7 @@ public class ToleranceSelectFragment extends AbstractProjectToleranceFragment { return; } } - selectCallback.onSelectTolerance(null); +// selectCallback.onSelectTolerance(null); }); } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseFragment.java index 56f75a9..5c94c4f 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseFragment.java @@ -6,8 +6,10 @@ import androidx.annotation.IdRes; import androidx.fragment.app.Fragment; import androidx.lifecycle.Lifecycle; -public class BaseFragment extends Fragment { - final protected void runOnUI(Runnable runnable) { +import com.bingce.controlapphelper.util.IUIRunner; + +public class BaseFragment extends Fragment implements IUIRunner { + public void runOnUI(Runnable runnable) { if (getActivity() == null) { return; } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailFragment.kt index a91e84d..31c4221 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailFragment.kt +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailFragment.kt @@ -10,13 +10,11 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.annotation.WorkerThread -import androidx.appcompat.widget.Toolbar import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import blankj.utilcode.util.ToastUtils import com.bingce.controlapphelper.datasource.database.ProjectType import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory -import com.bingce.controlapphelper.datasource.database.config.ConfigConstants import com.bingce.controlapphelper.event.SwitchPageEvent import com.bingce.controlapphelper.model.BundleConstants import com.bingce.controlnetwork.R @@ -25,20 +23,12 @@ import com.bingce.controlnetwork.databinding.FragmentProjectDetailListLayoutBind import com.bingce.controlnetwork.fragment.PointListFragment import com.bingce.controlnetwork.fragment.ProjectToleranceSettingFragment import com.bingce.controlnetwork.fragment.base.BaseFragment -import com.bingce.controlnetwork.guide.GuideSequence -import com.bingce.controlnetwork.guide.ITapTargetProvider -import com.bingce.utils.ThreadPoolUtil import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.greenrobot.eventbus.EventBus abstract class ProjectDetailFragment : BaseFragment() { - val KEY_GUIDE_INDEX_SURVEYOR_TOLERANCE = 0 - val KEY_GUIDE_INDEX_KNOWN_POINTS = 1 - val KEY_GUIDE_INDEX_UN_KNOWN_POINTS = 2 - val KEY_GUIDE_INDEX_SURVEYOR_CYCLE = 3 - val KEY_GUIDE_INDEX_CREATE_STATION = 4 companion object { @JvmStatic @@ -63,95 +53,15 @@ abstract class ProjectDetailFragment : BaseFragment() { protected val projectId: String by lazy { requireArguments().getString(BundleConstants.KEY_PROJECT_ID)!! } + protected val projectType: String? by lazy { requireArguments().getString(BundleConstants.KEY_PROJECT_TYPE) } - private val editGuides: GuideSequence by lazy { - GuideSequence(KEY_GUIDE_INDEX_CREATE_STATION + 1, object : GuideSequence.IDelegate { - override fun show(index: Int, provider: ITapTargetProvider) { - val fragmentActivity = activity - if (fragmentActivity == null || fragmentActivity.isDestroyed || fragmentActivity.isFinishing) { - return - } - val guideMsgAndDesc = getGuideMsgAndDesc(index) - - if (KEY_GUIDE_INDEX_SURVEYOR_TOLERANCE == index) { - if (fragmentActivity is FragmentContainerActivity) { - provider.show4ToolbarMenu( - fragmentActivity, - fragmentActivity.findViewById(R.id.toolbar), - R.id.project_parameter_setting, - guideMsgAndDesc[0], - guideMsgAndDesc[1] - ) - } - } else if (KEY_GUIDE_INDEX_KNOWN_POINTS == index) { - provider.show4View( - fragmentActivity, - fragmentActivity.findViewById(R.id.known_point_list), - guideMsgAndDesc[0], - guideMsgAndDesc[1] - ) - } else if (KEY_GUIDE_INDEX_UN_KNOWN_POINTS == index) { - provider.show4View( - fragmentActivity, - fragmentActivity.findViewById(R.id.unknown_point_list), - guideMsgAndDesc[0], - guideMsgAndDesc[1] - ) - } else if (KEY_GUIDE_INDEX_SURVEYOR_CYCLE == index) { - provider.show4View( - fragmentActivity, - fragmentActivity.findViewById(R.id.cycle_layout), - guideMsgAndDesc[0], - guideMsgAndDesc[1] - ) - } else if (KEY_GUIDE_INDEX_CREATE_STATION == index) { - provider.show4View( - fragmentActivity, - fragmentActivity.findViewById(R.id.create_station_btn), - guideMsgAndDesc[0], - guideMsgAndDesc[1] - ) - } - } - - override fun dismiss(index: Int) { - if (KEY_GUIDE_INDEX_SURVEYOR_TOLERANCE == index) { - ConfigConstants.markGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_TOLERANCE, - configDataSource - ) - } else if (KEY_GUIDE_INDEX_KNOWN_POINTS == index) { - ConfigConstants.markGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_KNOWN_POINT, - configDataSource - ) - } else if (KEY_GUIDE_INDEX_UN_KNOWN_POINTS == index) { - ConfigConstants.markGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_UNKNOWN_POINT, - configDataSource - ) - } else if (KEY_GUIDE_INDEX_SURVEYOR_CYCLE == index) { - ConfigConstants.markGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_SURVEYOR_CYCLE, - configDataSource - ) - } else if (KEY_GUIDE_INDEX_CREATE_STATION == index) { - ConfigConstants.markGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_CRAETE_STATION, - configDataSource - ) - } - } - }) - } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? ): View { _binding = FragmentProjectDetailListLayoutBinding.inflate(inflater, container, false) initView() @@ -171,13 +81,14 @@ abstract class ProjectDetailFragment : BaseFragment() { protected abstract fun clickCreateStation() - protected abstract fun getGuideMsgAndDesc(position: Int): Array - private fun initView() { + //设置开始测量 + mBinding.ilBtn.btnTwo.text = getString(R.string.start_surveyor) + childFragmentManager - .beginTransaction() - .replace(R.id.fragment_container, getContentFragment(), "__station_list") - .commit() + .beginTransaction() + .replace(R.id.fragment_container, getContentFragment(), "__station_list") + .commit() //已知点 initKnownPoint() //未知点 @@ -189,10 +100,10 @@ abstract class ProjectDetailFragment : BaseFragment() { } private fun initCreateStation() = - mBinding.createStationBtn.setOnClickListener { v -> clickCreateStation() } + mBinding.ilBtn.btnOne.setOnClickListener { v -> clickCreateStation() } private fun initGoMeasurePage() { - mBinding.ivGoMeasurePage.setOnClickListener { view -> + mBinding.ilBtn.btnTwo.setOnClickListener { view -> lifecycleScope.launch(Dispatchers.IO) { val msg = saveDefaultProjectAndSoOn() if (!msg.isNullOrEmpty()) { @@ -200,10 +111,10 @@ abstract class ProjectDetailFragment : BaseFragment() { return@launch } EventBus.getDefault().post( - SwitchPageEvent( - SwitchPageEvent.TYPE_SWITCH_TO_MEASURE_PAGE_AND_DATA, - null - ) + SwitchPageEvent( + SwitchPageEvent.TYPE_SWITCH_TO_MEASURE_PAGE_AND_DATA, + null + ) ) val activity = activity activity?.finish() @@ -214,8 +125,8 @@ abstract class ProjectDetailFragment : BaseFragment() { private fun initUnKnownPoint() { mBinding.unknownPointList.setOnClickListener { view -> PointListFragment.go2UnknownPointList( - projectId, - context + projectId, + context ) } } @@ -223,8 +134,8 @@ abstract class ProjectDetailFragment : BaseFragment() { private fun initKnownPoint() { mBinding.knownPointList.setOnClickListener { view -> PointListFragment.go2KnownPointList( - projectId, - context + projectId, + context ) } } @@ -232,59 +143,6 @@ abstract class ProjectDetailFragment : BaseFragment() { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { inflater.inflate(R.menu.project_detail_fragment_menu, menu) super.onCreateOptionsMenu(menu, inflater) - ThreadPoolUtil.execute { - if (!ConfigConstants.isGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_TOLERANCE, - configDataSource - ) - ) { - ThreadPoolUtil.executeInMain { - editGuides.start( - KEY_GUIDE_INDEX_SURVEYOR_TOLERANCE - ) - } - } else if (!ConfigConstants.isGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_KNOWN_POINT, - configDataSource - ) - ) { - ThreadPoolUtil.executeInMain { - editGuides.start( - KEY_GUIDE_INDEX_KNOWN_POINTS - ) - } - } else if (!ConfigConstants.isGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_UNKNOWN_POINT, - configDataSource - ) - ) { - ThreadPoolUtil.executeInMain { - editGuides.start( - KEY_GUIDE_INDEX_UN_KNOWN_POINTS - ) - } - } else if (!ConfigConstants.isGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_SURVEYOR_CYCLE, - configDataSource - ) - ) { - ThreadPoolUtil.executeInMain { - editGuides.start( - KEY_GUIDE_INDEX_SURVEYOR_CYCLE - ) - } - } else if (!ConfigConstants.isGuideCompleted( - ConfigConstants.KEY_GUIDE_PROJECT_CRAETE_STATION, - configDataSource - ) - ) { - ThreadPoolUtil.executeInMain { - editGuides.start( - KEY_GUIDE_INDEX_CREATE_STATION - ) - } - } - } } override fun onOptionsItemSelected(item: MenuItem): Boolean { diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailHeightTraverseFragment.kt index 4e189b3..d427cc1 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailHeightTraverseFragment.kt +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailHeightTraverseFragment.kt @@ -4,13 +4,13 @@ import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels -import com.bingce.controlnetwork.fragment.heighttraverse.viewmodel.HeightCreateOrEditVm -import com.bingce.controlnetwork.fragment.projectdetail.content.RouteFragment import com.bingce.controlapphelper.datasource.database.SurveyorDataBase import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory import com.bingce.controlapphelper.datasource.database.config.ConfigConstants import com.bingce.controlapphelper.util.Tools import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.fragment.heighttraverse.viewmodel.HeightCreateOrEditVm +import com.bingce.controlnetwork.fragment.projectdetail.content.RouteFragment class ProjectDetailHeightTraverseFragment : ProjectDetailFragment() { @@ -61,43 +61,11 @@ class ProjectDetailHeightTraverseFragment : ProjectDetailFragment() { ) } - override fun getGuideMsgAndDesc(position: Int): Array { - val array = arrayOfNulls(2) - when (position) { - KEY_GUIDE_INDEX_SURVEYOR_TOLERANCE -> { - array[0] = getString(R.string.guide_modify_project_tolerance) - array[1] = getString(R.string.project_tolerance_apply_all_station) - } - - KEY_GUIDE_INDEX_KNOWN_POINTS -> { - array[0] = getString(R.string.guide_edit_known_point) - array[1] = null - } - - KEY_GUIDE_INDEX_UN_KNOWN_POINTS -> { - array[0] = getString(R.string.guide_edit_unknown_point) - array[1] = null - } - - KEY_GUIDE_INDEX_SURVEYOR_CYCLE -> { - array[0] = getString(R.string.route_list) - array[1] = null - } - - KEY_GUIDE_INDEX_CREATE_STATION -> { - array[0] = getString(R.string.create_new_route) - array[1] = null - } - } - return array - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) mBinding.tvCycleTitle.text = getString(R.string.route) - mBinding.createStationBtn.text = getString(R.string.create_new_route) + mBinding.ilBtn.btnOne.text = getString(R.string.create_new_route) mBinding.ivCycleArrow.visibility = View.GONE } - } \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailTriangleFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailTriangleFragment.kt index c5a42a5..2a3f221 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailTriangleFragment.kt +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailTriangleFragment.kt @@ -110,37 +110,6 @@ class ProjectDetailTriangleFragment : ProjectDetailFragment() { } } - override fun getGuideMsgAndDesc(position: Int): Array { - val array = arrayOfNulls(2) - when (position) { - KEY_GUIDE_INDEX_SURVEYOR_TOLERANCE -> { - array[0] = getString(R.string.guide_modify_project_tolerance) - array[1] = getString(R.string.guide_modify_project_tolerance_describe) - } - - KEY_GUIDE_INDEX_KNOWN_POINTS -> { - array[0] = getString(R.string.guide_edit_known_point) - array[1] = null - } - - KEY_GUIDE_INDEX_UN_KNOWN_POINTS -> { - array[0] = getString(R.string.guide_edit_unknown_point) - array[1] = null - } - - KEY_GUIDE_INDEX_SURVEYOR_CYCLE -> { - array[0] = getString(R.string.guide_switch_surveyor_cycle) - array[1] = null - } - - KEY_GUIDE_INDEX_CREATE_STATION -> { - array[0] = getString(R.string.guide_create_new_station) - array[1] = null - } - } - return array - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initListener() diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/AbstractProjectEditFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/AbstractProjectEditFragment.kt index 8a9b344..12685c4 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/AbstractProjectEditFragment.kt +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/AbstractProjectEditFragment.kt @@ -11,18 +11,18 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.room.withTransaction import blankj.utilcode.util.ToastUtils -import com.bingce.controlnetwork.fragment.AbstractFullScreenDialogFragment -import com.bingce.controlnetwork.fragment.ToleranceSelectFragment -import com.bingce.controlnetwork.ui.widget.dialog.LoadingUtilKt -import com.bingce.controlnetwork.util.DefaultNameUtil import com.bingce.controlapphelper.datasource.database.ProjectType import com.bingce.controlapphelper.datasource.database.SurveyorDataBase import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory -import com.bingce.controlapphelper.datasource.database.ToleranceTemplate import com.bingce.controlapphelper.datasource.database.config.ConfigConstants import com.bingce.controlapphelper.datasource.database.project.ProjectRecord import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.fragment.AbstractFullScreenDialogFragment +import com.bingce.controlnetwork.fragment.ToleranceSelectFragment +import com.bingce.controlnetwork.ui.widget.dialog.LoadingUtilKt +import com.bingce.controlnetwork.util.DefaultNameUtil import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope import kotlinx.coroutines.cancel @@ -37,9 +37,6 @@ abstract class AbstractProjectEditFragment : AbstractFullScreenDialogFragment() const val KEY_PROJECT_NAME = "___project___name___" const val KEY_TOLERANCE_ID = "___tolerance_id" - const val GUIDE_INDEX_PROJECT_NAME = 0 - const val GUIDE_INDEX_PROJECT_TOLERANCE = 1 - @JvmStatic fun editProject( fragmentManager: FragmentManager, @@ -146,8 +143,9 @@ abstract class AbstractProjectEditFragment : AbstractFullScreenDialogFragment() .getRecordSync(toleranceId) } toleranceDetailRecord?.let { - val groupRecord = ToleranceTemplate.groupOf(it.groupId) - val levelRecord = ToleranceTemplate.levelOf(it.levelId) + val tjToleranceLoad = ToleranceLoadUtil.getTriangleToleranceLoad() + val groupRecord = tjToleranceLoad.groupOf(it.groupId) + val levelRecord = tjToleranceLoad.levelOf(it.levelId) val lineName = if (levelRecord?.name == null) "" else "-${levelRecord.name}" @@ -160,12 +158,24 @@ abstract class AbstractProjectEditFragment : AbstractFullScreenDialogFragment() } protected open fun initData() { - updateToleranceData(getToleranceId()) + initToleranceData() //设置项目名称 - setProjectName(getProjectName() ?: DefaultNameUtil.getDefaultProjectName()) + setProjectName(getProjectName() ?: "")//DefaultNameUtil.getDefaultProjectName() updateShowSlopData(getProjectId()) } + /** + * 初始化限差数据 + */ + private fun initToleranceData() { + val projectType = getProjectType() + + val newDefaultTolerance = ToleranceLoadUtil.getTriangleToleranceLoad().getNewDefaultTolerance(projectType) + val toleranceId = + getToleranceId() ?: newDefaultTolerance?.id + updateToleranceData(toleranceId) + } + private fun updateShowSlopData(projectId: String?) { if (projectId == null) { val checked = when (getProjectType()) { diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditTriangleFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditTriangleFragment.kt index eb84192..378ad93 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditTriangleFragment.kt +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditTriangleFragment.kt @@ -4,16 +4,9 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import com.bingce.controlnetwork.guide.GuideSequence -import com.bingce.controlnetwork.guide.ITapTargetProvider import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory -import com.bingce.controlapphelper.datasource.database.config.ConfigConstants import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource -import com.bingce.controlnetwork.R import com.bingce.controlnetwork.databinding.FragmentProjectEditTriangleBinding -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext /** * 三角测量和联系测量共用 @@ -31,39 +24,11 @@ class ProjectEditTriangleFragment : AbstractProjectEditFragment() { val configDataSource: IConfigDataSource = SurveyorDatabaseFactory.instance.configDataSource - private val createProjectGuide = GuideSequence(GUIDE_INDEX_PROJECT_TOLERANCE + 1, - object : GuideSequence.IDelegate { - override fun show(index: Int, provider: ITapTargetProvider) { - if (index == GUIDE_INDEX_PROJECT_NAME) { - provider.show4View( - dialog, - view?.findViewById(R.id.editor), - getString(R.string.guide_input_project_name), getString(R.string.guide_project_name_can_same) - ) - } else if (index == GUIDE_INDEX_PROJECT_TOLERANCE) { - provider.show4View( - dialog, - view?.findViewById(R.id.select_tolerance), - getString(R.string.guide_select_tolerance_of_project), null - ) - } - } - - override fun dismiss(index: Int) { - if (GUIDE_INDEX_PROJECT_NAME == index) { - ConfigConstants.markGuideCompleted( - ConfigConstants.KEY_GUIDE_INPUT_PROJECT_NAME, configDataSource - ) - } else if (GUIDE_INDEX_PROJECT_TOLERANCE == index) { - ConfigConstants.markGuideCompleted( - ConfigConstants.KEY_GUIDE_SELECT_TOLERANCE, configDataSource - ) - } - } - }) - - - override fun createContentView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + override fun createContentView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { _binding = FragmentProjectEditTriangleBinding.inflate(inflater, container, false) return mBinding.root } @@ -72,24 +37,6 @@ class ProjectEditTriangleFragment : AbstractProjectEditFragment() { return true } - override fun onResume() { - super.onResume() - dealTyroGuide() - } - - private fun dealTyroGuide() { - scope.launch { - val index = withContext(Dispatchers.IO) { - if (!ConfigConstants.isGuideCompleted(ConfigConstants.KEY_GUIDE_INPUT_PROJECT_NAME, configDataSource)) { - 0 - } else if (!ConfigConstants.isGuideCompleted(ConfigConstants.KEY_GUIDE_SELECT_TOLERANCE, configDataSource)) { - 1 - } else -1 - } - createProjectGuide.start(index) - } - } - override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/AbstractStationFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/AbstractStationFragment.java index afd5ea2..5359839 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/station/AbstractStationFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/AbstractStationFragment.java @@ -11,18 +11,16 @@ import androidx.appcompat.widget.SwitchCompat; import androidx.fragment.app.Fragment; import com.bingce.controlapphelper.util.Tools; - -import org.jetbrains.annotations.NotNull; - -import java.util.List; - import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.fragment.TipsFragment; -import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; import com.bingce.controlnetwork.activity.fragmentcontainer.IOnBackFilter; import com.bingce.controlnetwork.fragment.TipsFragment; import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; public abstract class AbstractStationFragment extends BaseFragment implements IOnBackFilter { @@ -80,9 +78,16 @@ public abstract class AbstractStationFragment extends BaseFragment implements IO if (view == null) { return false; } - SwitchCompat switchCompat = view.findViewById(id); - if (switchCompat != null) { - return switchCompat.isChecked(); + View view1 = view.findViewById(id); + if (view1 != null) { + if (view1 instanceof SwitchWithText) { + SwitchWithText switchCompat = (SwitchWithText) view1; + return switchCompat.isChecked(); + } + if (view1 instanceof SwitchCompat) { + SwitchCompat switchCompat = (SwitchCompat) view1; + return switchCompat.isChecked(); + } } return false; } @@ -91,12 +96,11 @@ public abstract class AbstractStationFragment extends BaseFragment implements IO return switchIsChecked(getView(), R.id.left_right_switch); } - protected void updateLeftRightMark(View view, boolean need) { if (view == null) { return; } - SwitchCompat switchCompat = view.findViewById(R.id.left_right_switch); + SwitchWithText switchCompat = view.findViewById(R.id.left_right_switch); if (switchCompat != null) { switchCompat.setChecked(need); } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/DefaultStationSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/DefaultStationSetupFragment.java index 0f05fce..424e32f 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/DefaultStationSetupFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/DefaultStationSetupFragment.java @@ -5,9 +5,9 @@ import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.view.View; import androidx.annotation.NonNull; -import androidx.appcompat.widget.SwitchCompat; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; @@ -21,6 +21,7 @@ import com.bingce.controlapphelper.model.StationDetailItem; import com.bingce.controlapphelper.util.PointUtil; import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; import com.bingce.utils.ThreadPoolUtil; import java.util.Arrays; @@ -30,6 +31,8 @@ public class DefaultStationSetupFragment extends AbstractSingleStationPointListF public static final String TAG = DefaultStationSetupFragment.class.getName(); private MenuItem confirmItem; + private boolean lastConfirmEnable = false; + @Override protected int layoutRes() { return R.layout.fragment_default_surveyor_station_setup_layout; @@ -57,9 +60,8 @@ public class DefaultStationSetupFragment extends AbstractSingleStationPointListF inflater.inflate(R.menu.menu_confirm, menu); confirmItem = menu.findItem(R.id.menu_confirm); if (confirmItem != null) { - confirmItem.setEnabled(false); + confirmItem.setEnabled(lastConfirmEnable); } - super.onCreateOptionsMenu(menu, inflater); } @Override @@ -184,16 +186,19 @@ public class DefaultStationSetupFragment extends AbstractSingleStationPointListF @Override protected void onItemChanged() { if (confirmItem != null) {//设置menuItem enable - confirmItem.setEnabled(isCurrentDataValidate()); + boolean confirmEnable = isCurrentDataValidate(); + confirmItem.setEnabled(confirmEnable); + lastConfirmEnable = confirmEnable; } //检测左右角是否 - SwitchCompat leftAndRightSwitch = findViewById(R.id.left_right_switch); + SwitchWithText leftAndRightSwitch = findViewById(R.id.left_right_switch); if (leftAndRightSwitch != null) { - if (surveyorPointSize() == 2) { - leftAndRightSwitch.setEnabled(true); + int pointSize = surveyorPointSize(); + if (pointSize == 2) { + leftAndRightSwitch.setVisibility(View.VISIBLE); } else { - leftAndRightSwitch.setEnabled(false); leftAndRightSwitch.setChecked(false); + leftAndRightSwitch.setVisibility(View.GONE); } } } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationSetupFragment.java index f5e63a0..d41096f 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationSetupFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationSetupFragment.java @@ -5,7 +5,6 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.widget.SwitchCompat; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; import com.bingce.controlapphelper.datasource.database.line.LineRecord; @@ -16,6 +15,7 @@ import com.bingce.controlapphelper.util.Tools; import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.fragment.StringInputFragment; import com.bingce.controlnetwork.fragment.station.AbstractStationFragment; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; import com.bingce.controlnetwork.util.SurveyorStationUtil; import com.bingce.utils.IOnListGetCallback; import com.bingce.utils.ThreadPoolUtil; @@ -39,11 +39,6 @@ public abstract class AbstractLineStationSetupFragment extends AbstractStationFr @Override public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - //显示左右角开关 -// SwitchCompat switchCompat = view.findViewById(R.id.left_right_switch); -// if (switchCompat != null) { -// switchCompat.setEnabled(true); -// } setLeftRightEnable(initLeftRightMeasure()); //读取projectRecord ThreadPoolUtil.execute(() -> { @@ -63,7 +58,7 @@ public abstract class AbstractLineStationSetupFragment extends AbstractStationFr //显示左右角开关 View view = getView(); if (view != null) { - SwitchCompat switchCompat = view.findViewById(R.id.left_right_switch); + SwitchWithText switchCompat = view.findViewById(R.id.left_right_switch); if (switchCompat != null) { switchCompat.setEnabled(isEnable); } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/close/LineStationCloseSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/close/LineStationCloseSetupFragment.java index 7c70d50..1e5d2f2 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/close/LineStationCloseSetupFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/close/LineStationCloseSetupFragment.java @@ -6,7 +6,6 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.widget.SwitchCompat; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; @@ -43,12 +42,10 @@ public class LineStationCloseSetupFragment extends LineStationSingleSetupFragmen @Override public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - SwitchCompat setOnce = view.findViewById(R.id.start_point_setup_once); - if (setOnce == null) { - return; + View leftRightSwitch = view.findViewById(R.id.left_right_switch); + if (leftRightSwitch != null) { + leftRightSwitch.setVisibility(View.GONE); } - setOnce.setVisibility(View.VISIBLE); - setOnce.setChecked(true); } @Override diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/SingleStationDetailAndEditFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/SingleStationDetailAndEditFragment.java index 1102918..427addd 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/SingleStationDetailAndEditFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/SingleStationDetailAndEditFragment.java @@ -17,16 +17,16 @@ import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyor import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; import com.bingce.controlapphelper.model.BundleConstants; import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.databinding.FragmentSurveyorStationDetailOrEditLayoutBinding; import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.station.defaultstation.ComponentSingleStationPointListFragment; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; import com.bingce.utils.ThreadPoolUtil; import org.jetbrains.annotations.NotNull; -import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.databinding.FragmentSurveyorStationDetailOrEditLayoutBinding; -import com.bingce.controlnetwork.fragment.station.defaultstation.ComponentSingleStationPointListFragment; - /** * 测站详情--包含编辑测点、站点功能,可能是「多测回测角」,也可能是「导线测站」中某站 */ @@ -39,6 +39,7 @@ public class SingleStationDetailAndEditFragment extends BaseFragment { private FragmentSurveyorStationDetailOrEditLayoutBinding mBinding; private String stationId; private boolean isHasDataForStation;//测站是否有测量记录 + private SwitchWithText leftRightSwitch; @Override @@ -60,6 +61,8 @@ public class SingleStationDetailAndEditFragment extends BaseFragment { return; } + leftRightSwitch = view.findViewById(R.id.left_right_switch); + stationDetailViewModel = new ViewModelProvider(requireActivity()).get(StationDetailViewModel.class); //创建显示点列表的fragment @@ -80,10 +83,9 @@ public class SingleStationDetailAndEditFragment extends BaseFragment { mBinding.autoCloseSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> updateStationAutoClose(isChecked)); - mBinding.leftRightSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> updateStationLeftRightSurveyor(isChecked)); + leftRightSwitch.setOnCheckChangeListener(this::updateStationLeftRightSurveyor); } - private void initData() { ThreadPoolUtil.execute(() -> { SurveyorStationRecord stationRecord = SurveyorDatabaseFactory.instance.getSurveyorStation().getRecordSync(stationId); @@ -102,12 +104,12 @@ public class SingleStationDetailAndEditFragment extends BaseFragment { } private void refreshViewCheckEnable(int surveyorPointSize) { - if (isVisiable(mBinding.leftRightSwitch)) { + if (isVisiable(leftRightSwitch)) { boolean canLeftOrRightSurveyor = StationUtil.isCanLeftOrRightSurveyor(surveyorPointSize); - boolean checkNew = canLeftOrRightSurveyor && mBinding.leftRightSwitch.isChecked(); - mBinding.leftRightSwitch.setChecked(checkNew); + boolean checkNew = canLeftOrRightSurveyor && leftRightSwitch.isChecked(); + leftRightSwitch.setChecked(checkNew); - mBinding.leftRightSwitch.setEnabled(canLeftOrRightSurveyor); + leftRightSwitch.setEnabled(canLeftOrRightSurveyor); } if (isVisiable(mBinding.autoCloseSwitch)) { boolean canZeroSurveyor = StationUtil.isCanZeroSurveyor(surveyorPointSize); @@ -136,10 +138,9 @@ public class SingleStationDetailAndEditFragment extends BaseFragment { runOnUI(() -> { if (!isTriangleProject(projectRecord)) { mBinding.autoCloseSwitch.setVisibility(View.GONE); - mBinding.leftRightSwitch.setVisibility(View.GONE); + leftRightSwitch.setVisibility(View.GONE); mBinding.tips.setText(R.string.tips_forbid_edit_line_station); } else { - if (stationRecord.isLineStation()) { mBinding.tips.setText(R.string.tips_forbid_edit_line_station); } else { @@ -149,7 +150,7 @@ public class SingleStationDetailAndEditFragment extends BaseFragment { } } - mBinding.leftRightSwitch.setChecked(stationRecord.leftAndRightSurveyor); + leftRightSwitch.setChecked(stationRecord.leftAndRightSurveyor); mBinding.autoCloseSwitch.setChecked(stationRecord.autoClose); refreshViewCheckEnable(stationRecord.items.size() - 1); diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingsFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingsFragment.java index 60bf388..7fc342e 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingsFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingsFragment.java @@ -16,6 +16,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; +import com.bingce.controlapphelper.datasource.database.ProjectType; import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; @@ -29,6 +30,7 @@ import com.bingce.controlapphelper.datasource.database.surveyorstation.model.Sur import com.bingce.controlapphelper.util.HideKeyUtil; import com.bingce.controlapphelper.util.StationUtil; import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; import com.bingce.controlnetwork.adapter.BaseAdapter; import com.bingce.controlnetwork.adapter.SpinnerAdapter; @@ -42,11 +44,6 @@ import java.util.List; import blankj.utilcode.util.ToastUtils; -import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; -import com.bingce.controlnetwork.adapter.BaseAdapter; -import com.bingce.controlnetwork.adapter.SpinnerAdapter; - /** * 仪器棱镜设置 */ @@ -134,9 +131,11 @@ public class StationSettingsFragment extends BaseStationSettingFragment { if (surveyorStationRecord.getInstrumentHeight() == null) { surveyorStationRecord.setInstrumentHeight("0"); } + //是否是联系测量 + boolean isConnection = ProjectType.isConnection(surveyorStationRecord.projectType); //添加point title - items.add(new _PointTitleItem()); + items.add(new _PointTitleItem(isConnection)); //添加点坐标 IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); List stationItems = surveyorStationRecord.getItems(); @@ -164,7 +163,8 @@ public class StationSettingsFragment extends BaseStationSettingFragment { pointRecord.getName(), surveyorPoint, prismRecords, - !stationHasRecord + !stationHasRecord, + isConnection )); } } @@ -249,14 +249,28 @@ public class StationSettingsFragment extends BaseStationSettingFragment { } private static class _PointTitleItem extends _Item { - _PointTitleItem() { + private final boolean isConnection;//是否是联系测量 + + _PointTitleItem(boolean isConnection) { super(_VH.TYPE_POINT_TITLE, null); + this.isConnection = isConnection; } @Override String prepare2Save() { return null; } + + @Override + void attach(View itemView) { + super.attach(itemView); + TextView tvAloneDistanceTitle = itemView.findViewById(R.id.tvAloneDistanceTitle); + if (isConnection) { + tvAloneDistanceTitle.setVisibility(View.VISIBLE); + } else { + tvAloneDistanceTitle.setVisibility(View.INVISIBLE); + } + } } private static class _1EditTextItem extends _Item { @@ -328,16 +342,19 @@ public class StationSettingsFragment extends BaseStationSettingFragment { private final SurveyorPoint surveyorPoint; private final List prismRecords; private final boolean isCanSelectAloneDistance; + private final boolean isConnection;//是否是联系测量 private final List prismTypes; _2EditTextItem(String pointName, SurveyorPoint surveyorPoint, List prismRecords, - boolean isCanSelectAloneDistance) { + boolean isCanSelectAloneDistance, + boolean isConnection) { super(_VH.TYPE_2_EDIT_TEXT, pointName); this.surveyorPoint = surveyorPoint; this.prismRecords = prismRecords; this.isCanSelectAloneDistance = isCanSelectAloneDistance; + this.isConnection = isConnection; prismTypes = new ArrayList<>(); for (PrismRecord prismRecord : prismRecords) { prismTypes.add(prismRecord.getShowPrismTypeName()); @@ -377,10 +394,15 @@ public class StationSettingsFragment extends BaseStationSettingFragment { CheckBox checkBox = itemView.findViewById(R.id.checkBox); if (checkBox != null) { - checkBox.setEnabled(isCanSelectAloneDistance); - checkBox.setOnCheckedChangeListener((compoundButton, checked) -> { - surveyorPoint.setAloneDistance(checked); - }); + if (isConnection) { + checkBox.setVisibility(View.VISIBLE); + checkBox.setEnabled(isCanSelectAloneDistance); + checkBox.setOnCheckedChangeListener((compoundButton, checked) -> { + surveyorPoint.setAloneDistance(checked); + }); + } else { + checkBox.setVisibility(View.INVISIBLE); + } } } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/StationSurveyorFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/StationSurveyorFragment.java index d95508b..697f929 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/StationSurveyorFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/StationSurveyorFragment.java @@ -39,6 +39,7 @@ import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragme import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment; import com.bingce.controlnetwork.fragment.base.BaseFragment; import com.bingce.controlnetwork.fragment.stationsetting.StationSettingsFragment; +import com.bingce.controlnetwork.newui.stationsetting.StationSettingsActivity; import com.bingce.controlnetwork.surveyor.surveyor.TestDataSelectFragment; import com.bingce.utils.ThreadPoolUtil; import com.github.razir.progressbutton.DrawableButtonExtensionsKt; @@ -61,22 +62,6 @@ public class StationSurveyorFragment extends BaseFragment { private SurveyorStationRecord surveyorStationRecord; private int cycleIndex = 0; - public StationSurveyorFragment() { - super(); - } - - @Override - public void onStart() { - super.onStart(); - EventBus.getDefault().register(this); - } - - @Override - public void onStop() { - super.onStop(); - EventBus.getDefault().unregister(this); - } - @Subscribe(threadMode = ThreadMode.MAIN) public void onRefreshGoBack(RefreshGoBackButton event) { if (goBack != null) { @@ -133,7 +118,6 @@ public class StationSurveyorFragment extends BaseFragment { @Override public void onResume() { super.onResume(); - ThreadPoolUtil.execute(() -> MethodCheckSetting.checkStationSettings(stationId(), fragment, this::runOnUI)); //测量界面保持常亮 if (getActivity() != null) { getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); @@ -149,11 +133,19 @@ public class StationSurveyorFragment extends BaseFragment { } } + @Override + public void onDestroyView() { + super.onDestroyView(); + EventBus.getDefault().unregister(this); + } + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + EventBus.getDefault().register(this); + View view = inflater.inflate(R.layout.fragment_project_surveyor_station_detail_layout, container, false); @@ -187,7 +179,7 @@ public class StationSurveyorFragment extends BaseFragment { .getSurveyorStation() .getRecordSync(stationId()); //监听当前测回切换 - monitorCurrentCycle(view); + initObserver(view); //监听数据变化 ToleranceDetailRecord toleranceRecord = getTolerance(surveyorStationRecord); if (toleranceRecord == null) { @@ -229,6 +221,23 @@ public class StationSurveyorFragment extends BaseFragment { return view; } + private void initObserver(View view) { + runOnUI(() -> { + monitorCurrentCycle(view); + //监听测站变化 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + stationRecord -> checkStationSettings()); + }); + } + + private void checkStationSettings() { + ThreadPoolUtil.execute(() -> MethodCheckSetting.checkStationSettings(stationId(), fragment, this::runOnUI)); + } + @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -236,28 +245,25 @@ public class StationSurveyorFragment extends BaseFragment { } - @WorkerThread private void monitorCurrentCycle(View view) { - if (getActivity() != null) { - getActivity().runOnUiThread(() -> SurveyorDatabaseFactory - .instance - .getScheduleDataSource() - .findSchedule(SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null)) - .observe(getViewLifecycleOwner(), record -> { - TextView circleText = view.findViewById(R.id.circle_text); - //测回发生变化的时候,更新相应ui - int cycleIndex = DigitalUtil.valueOfIntString(record == null ? "0" : record.getStatue(), 0); - //更新测回名称 - if (circleText != null) { - boolean showLeftOrRight = true; - if (surveyorStationRecord != null) { - showLeftOrRight = surveyorStationRecord.leftAndRightSurveyor; - } - circleText.setText(SurveyorCycleUtil.cycleName(cycleIndex, showLeftOrRight)); + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findSchedule(SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null)) + .observe(getViewLifecycleOwner(), record -> { + TextView circleText = view.findViewById(R.id.circle_text); + //测回发生变化的时候,更新相应ui + int cycleIndex = DigitalUtil.valueOfIntString(record == null ? "0" : record.getStatue(), 0); + //更新测回名称 + if (circleText != null) { + boolean showLeftOrRight = true; + if (surveyorStationRecord != null) { + showLeftOrRight = surveyorStationRecord.leftAndRightSurveyor; } - StationSurveyorFragment.this.cycleIndex = cycleIndex; - })); - } + circleText.setText(SurveyorCycleUtil.cycleName(cycleIndex, showLeftOrRight)); + } + StationSurveyorFragment.this.cycleIndex = cycleIndex; + }); } private static void setSurveyorClick(View rootView, int id, Runnable runnable) { @@ -289,40 +295,39 @@ public class StationSurveyorFragment extends BaseFragment { } else { inflater.inflate(R.menu.menu_surveyor_station_record_data_edit_release, menu); } - MenuItem stationCheck = menu.findItem(R.id.menu_item_station_check); - MenuItem stationAdjust = menu.findItem(R.id.menu_item_station_adjust); +// MenuItem stationCheck = menu.findItem(R.id.menu_item_station_check); +// MenuItem stationAdjust = menu.findItem(R.id.menu_item_station_adjust); goBack = menu.findItem(R.id.menu_item_go_back); - SurveyorDatabaseFactory - .instance - .getScheduleDataSource() - .findSchedule(SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null)) - .observe(getViewLifecycleOwner(), surveyorScheduleRecord -> { - boolean checkStatue = false; - boolean adjustStatue = false; - if (surveyorScheduleRecord != null) { - String statue = surveyorScheduleRecord.getStatue(); - if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(statue)) { - adjustStatue = true; - } else if (SurveyorScheduleConstants.STATUE_VALUE_COMPLETED.equals(statue)) { - checkStatue = true; - } else if (SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED.equals(statue)) { - //重置提醒标识 - String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId(); - SurveyorDatabaseFactory - .instance - .getConfigDataSource() - .set(key, ConfigConstants.VALUE_NO); - } - } - //更新菜单enable - if (stationCheck != null) { - stationCheck.setEnabled(checkStatue); - } - if (stationAdjust != null) { - stationAdjust.setEnabled(adjustStatue); - } - }); - super.onCreateOptionsMenu(menu, inflater); +// SurveyorDatabaseFactory +// .instance +// .getScheduleDataSource() +// .findSchedule(SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null)) +// .observe(getViewLifecycleOwner(), surveyorScheduleRecord -> { +// boolean checkStatue = false; +// boolean adjustStatue = false; +// if (surveyorScheduleRecord != null) { +// String statue = surveyorScheduleRecord.getStatue(); +// if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(statue)) { +// adjustStatue = true; +// } else if (SurveyorScheduleConstants.STATUE_VALUE_COMPLETED.equals(statue)) { +// checkStatue = true; +// } else if (SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED.equals(statue)) { +// //重置提醒标识 +// String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId(); +// SurveyorDatabaseFactory +// .instance +// .getConfigDataSource() +// .set(key, ConfigConstants.VALUE_NO); +// } +// } +// //更新菜单enable +// if (stationCheck != null) { +// stationCheck.setEnabled(checkStatue); +// } +// if (stationAdjust != null) { +// stationAdjust.setEnabled(adjustStatue); +// } +// }); } @Override @@ -350,7 +355,8 @@ public class StationSurveyorFragment extends BaseFragment { fragment.goBack(); } else if (R.id.menu_item_station_environment_prism_settings == item.getItemId()) { //环境、棱镜设置 - StationSettingsFragment.start(getContext(), stationId()); + StationSettingsActivity.start(requireContext(),stationId()); +// StationSettingsFragment.start(getContext(), stationId()); } else if (R.id.menu_item_surveyor_settings == item.getItemId()) { //测量设置 ThreadPoolUtil.execute(() -> { @@ -360,6 +366,9 @@ public class StationSurveyorFragment extends BaseFragment { } else if (R.id.menu_item_station_adjust == item.getItemId()) { //测站平差,平差检测 fragment.stationAdjust(); + } else if (R.id.menu_item_check_adjust == item.getItemId()) { + //检测平差 + fragment.stationCheckAdjust(); } return super.onOptionsItemSelected(item); } diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureFragment.java index 05e9ae3..d4cab4e 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureFragment.java @@ -136,7 +136,7 @@ public class MeasureFragment extends MeasureBaseFragment { currentFragment.deleteStationAllPeroidRecord(); } } else if (R.id.menu_item_station_check == item.getItemId() && currentFragment != null) { - //测站检测 + //测站检测 被检测平差替代 stationCheckBefore(); } else if (R.id.menu_item_data_source == item.getItemId()) { //数据源 debug使用 @@ -153,8 +153,8 @@ public class MeasureFragment extends MeasureBaseFragment { String name = StationUtil.getStationName(surveyorStationRecord); runOnUI(() -> SurveyorSettingsFragment.start(getContext(), surveyorStationRecord.getId(), name)); }); - } else if (R.id.menu_item_station_adjust == item.getItemId() && currentFragment != null) { - //测站平差 + } else if (R.id.menu_item_check_adjust == item.getItemId() && currentFragment != null) { + //检测平差 stationCheckAdjustBefore(); } return super.onOptionsItemSelected(item); diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/base/MeasureBaseFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/base/MeasureBaseFragment.java index da46c93..2bfc492 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/base/MeasureBaseFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/base/MeasureBaseFragment.java @@ -302,7 +302,8 @@ public abstract class MeasureBaseFragment extends BaseFragment { SurveyStateEvent.postIdle(position); } - setCycleForSwitchPage(); + //切换tab测回可能会变刷新当前fragment + refreshCycleAndFragment(); currentFragment.refreshGoBackBtnEnable(); } @@ -315,7 +316,7 @@ public abstract class MeasureBaseFragment extends BaseFragment { }); } - private void setCycleForSwitchPage() { + private void refreshCycleAndFragment() { ThreadPoolUtil.execute(() -> { SurveyorScheduleRecord record = SurveyorDatabaseFactory .instance diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseFragment.kt index 7dbaa22..9bbe7e6 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseFragment.kt +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseFragment.kt @@ -14,6 +14,7 @@ import com.bingce.controlapphelper.util.Tools import com.bingce.controlnetwork.R import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment import com.bingce.controlnetwork.fragment.stationsetting.StationSettingHeightTraverseFragment import com.bingce.controlnetwork.fragment.stationsurvey.base.MeasureBaseFragment import com.bingce.controlnetwork.surveyor.state.heighttraverse.__BaseState @@ -40,10 +41,10 @@ class MeasureHeightTraverseFragment : MeasureBaseFragment() { val bundle = Bundle() bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId) FragmentContainerActivity.start( - context, - TAG, - surveyorStationName, - bundle + context, + TAG, + surveyorStationName, + bundle ) } @@ -53,7 +54,6 @@ class MeasureHeightTraverseFragment : MeasureBaseFragment() { fragment.arguments = args return fragment } - } override fun isShowSelectCycle(position: Int): Boolean { @@ -74,33 +74,33 @@ class MeasureHeightTraverseFragment : MeasureBaseFragment() { val stationId = stationId() val stationRecord = - SurveyorDatabaseFactory.instance.surveyorStation.getRecordSync(stationId) + SurveyorDatabaseFactory.instance.surveyorStation.getRecordSync(stationId) val configRecord = - SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() - .getRecordByProjectId(stationRecord.getProjectId()) + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + .getRecordByProjectId(stationRecord.getProjectId()) if (configRecord?.stationLayout == StationLayout.SEPARATE) { fragments.add( - MeasureHeightTraverseSubFragment.newInstance( - stationId, - POSITION_BACK_PAGE - ) + MeasureHeightTraverseSubFragment.newInstance( + stationId, + POSITION_BACK_PAGE + ) ) fragments.add( - MeasureHeightTraverseSubFragment.newInstance( - stationId, - POSITION_FRONT_PAGE - ) + MeasureHeightTraverseSubFragment.newInstance( + stationId, + POSITION_FRONT_PAGE + ) ) tabs.add(Tools.getString(R.string.rearview)) tabs.add(Tools.getString(R.string.forward_view)) } else if (configRecord?.stationLayout == StationLayout.EVERY) { fragments.add( - MeasureHeightTraverseSubFragment.newInstance( - stationId, - POSITION_FRONT_PAGE - ) + MeasureHeightTraverseSubFragment.newInstance( + stationId, + POSITION_FRONT_PAGE + ) ) tabs.add(Tools.getString(R.string.forward_view)) } @@ -116,33 +116,37 @@ class MeasureHeightTraverseFragment : MeasureBaseFragment() { override fun getCurrentPageCycleKey(): String { return SurveyorScheduleConstants.getCurrentCycleKey( - stationId(), - __BaseState.getScheduleKey(mBinding.vp.currentItem) + stationId(), + __BaseState.getScheduleKey(mBinding.vp.currentItem) ) } override fun getScheduleIdForAllCycle(): String { - val measureHeightTraverseSubFragment = currentFragment as MeasureHeightTraverseSubFragment - val positionFragment = measureHeightTraverseSubFragment.backOrFrontPosition + val positionFragment = getCurrentMeasurePos() return SurveyorScheduleConstants.getAllCycleScheduleKey( - stationId(), - __BaseState.getScheduleKey(positionFragment) + stationId(), + __BaseState.getScheduleKey(positionFragment) ) } + private fun getCurrentMeasurePos(): Int { + val measureHeightTraverseSubFragment = currentFragment as MeasureHeightTraverseSubFragment + return measureHeightTraverseSubFragment.backOrFrontPosition + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) monitorCurrentCycle( - SurveyorScheduleConstants.getCurrentCycleKey( - stationId(), - SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_BACK - ) + SurveyorScheduleConstants.getCurrentCycleKey( + stationId(), + SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_BACK + ) ) monitorCurrentCycle( - SurveyorScheduleConstants.getCurrentCycleKey( - stationId(), - SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_FRONT - ) + SurveyorScheduleConstants.getCurrentCycleKey( + stationId(), + SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_FRONT + ) ) } @@ -151,14 +155,11 @@ class MeasureHeightTraverseFragment : MeasureBaseFragment() { //删除当前测回记录 if (surveyorStationRecord != null && currentFragment != null) { //通知fragment - currentFragment.deleteStationOnePeriodRecord(cycleIndex) + currentFragment.deleteStationOnePeriodRecord(getCurrentMeasurePos()) } } else if (R.id.menu_item_delete_all_records == item.itemId) { //删除所有测回记录 - if (surveyorStationRecord != null && currentFragment != null) { - //通知fragment - currentFragment.deleteStationAllPeroidRecord() - } + showDeleteStationRecord() } else if (R.id.menu_item_station_check == item.itemId && currentFragment != null) { //测站检测 stationCheckBefore() @@ -177,18 +178,52 @@ class MeasureHeightTraverseFragment : MeasureBaseFragment() { val name = getStationName(surveyorStationRecord) runOnUI { SurveyorSettingsFragment.start( - context, - surveyorStationRecord.getId(), - name + context, + surveyorStationRecord.getId(), + name ) } } - } else if (R.id.menu_item_station_adjust == item.itemId && currentFragment != null) { - //测站平差 + } else if (R.id.menu_item_check_adjust == item.itemId && currentFragment != null) { + //检测平差 stationCheckAdjustBefore() } return super.onOptionsItemSelected(item) } + /** + * 删除测站的后视和前视的所有测回记录 + */ + private fun showDeleteStationRecord() { + if (surveyorStationRecord == null || currentFragment == null) { + return + } + val fragment = currentFragment as MeasureHeightTraverseSubFragment + if (fragment.isInvalite || fragment.isDead) { + return + } + + val msg = if (fragments.size == 1) { + "是否确定删除该站的所有测回数据?" + } else { + "是否确定删除该站的后视和前视的所有测回数据?" + } + + TipsWith2OptionFragment.tips( + childFragmentManager, + this, + null, + null, + null, + msg, + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + for (fragmentI in fragments) { + fragmentI.deleteStationAllPeroidRecord() + } + } + }) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseSubFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseSubFragment.java index 1d8e2d0..89d7499 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseSubFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseSubFragment.java @@ -30,6 +30,7 @@ import com.bingce.controlapphelper.surveyor.state.ISurveyState; import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; import com.bingce.controlapphelper.util.IUIRunner; import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.adapter.MeasureHeightTraverseAdapter; import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; @@ -43,16 +44,6 @@ import com.bingce.utils.ThreadPoolUtil; import org.greenrobot.eventbus.EventBus; -import com.bingce.controlnetwork.R; -import com.bingce.controlnetwork.adapter.MeasureHeightTraverseAdapter; -import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; -import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; -import com.bingce.controlnetwork.fragment.base.BaseLazyFragment; -import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; -import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureVm; -import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; -import com.bingce.controlnetwork.surveyor.state.heighttraverse.StateManagerHeightTraverse; - /** * 测角测距 */ @@ -300,11 +291,11 @@ public class MeasureHeightTraverseSubFragment extends BaseLazyFragment } @Override - public void deleteStationOnePeriodRecord(int cycleIndex) { + public void deleteStationOnePeriodRecord(int positionFragment) { if (stateManager == null) { return; } - stateManager.deleteCurrentStationSurveyorData(cycleIndex); + stateManager.deleteCurrentStationSurveyorData(positionFragment); } @Override @@ -398,6 +389,14 @@ public class MeasureHeightTraverseSubFragment extends BaseLazyFragment return false; } + public boolean isInvalite() { + return stateManager.isInValidate(); + } + + public boolean isDead() { + return stateManager.isDead(); + } + private static final String KEY_STATION_ID = "__station_id"; private static final String KEY_TYPE_BACK_OR_FRONT = "__KEY_TYPE_BACK_OR_FRONT"; public static final String TAG = ComponentStationSurveyorDataListFragment.class.getName(); diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/activity/LevelStationSettingActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/activity/LevelStationSettingActivity.kt new file mode 100644 index 0000000..bea6c46 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/activity/LevelStationSettingActivity.kt @@ -0,0 +1,145 @@ +package com.bingce.controlnetwork.func.level.activity + +import android.content.Context +import android.content.Intent +import android.view.Menu +import android.view.MenuItem +import androidx.activity.viewModels +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.viewpager.widget.ViewPager.OnPageChangeListener +import com.bingce.controlnetwork.func.level.fragment.LevelStationSettingConditionFragment +import com.bingce.controlnetwork.func.level.fragment.LevelStationSettingInformationFragment +import com.bingce.controlnetwork.func.level.viewmodel.LevelStationSettingVm +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityLevelStationSettingBinding +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import com.bingce.controlnetwork.newui.stationsetting.IStationSettingOperate + +class LevelStationSettingActivity : BaseBindingActivity() { + + private val viewModel by viewModels() + private val fragments = mutableListOf() + private val fragmentTitleList = listOf("观测信息", "观测条件") + + companion object { + private const val KEY_IS_SAVE_END_STATION = "KEY_IS_SAVE_END_STATION" + + @JvmStatic + fun start(context: Context, routeId: String, stationId: String, isSaveEndStation: Boolean) { + context.startActivity(Intent(context, LevelStationSettingActivity::class.java).apply { + putExtra(BundleConstants.KEY_ROUTE_ID, routeId) + putExtra(BundleConstants.KEY_SURVEYOR_STATION_ID, stationId) + putExtra(KEY_IS_SAVE_END_STATION, isSaveEndStation) + }) + } + } + + + override fun getBinding(): ActivityLevelStationSettingBinding { + return ActivityLevelStationSettingBinding.inflate(layoutInflater) + } + + override fun initView() { + viewModel.initRouteStationId(getRouteId(), getStationId()) + initViewPager() + } + + override fun initData() { + viewModel.getEditLastData(getStationId()) + + viewModel.getInitCurrentTabPos { + mBinding.tabLayout.currentTab = it + } + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_confirm, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.menu_confirm == item.itemId) { + doConfirm() + } + return super.onOptionsItemSelected(item) + } + + private fun initViewPager() { + fragments.add(LevelStationSettingInformationFragment()) + fragments.add(LevelStationSettingConditionFragment()) + mBinding.vp.offscreenPageLimit = 3 + mBinding.vp.adapter = MyPagerAdapter(supportFragmentManager) + mBinding.tabLayout.setViewPager(mBinding.vp) + mBinding.vp.addOnPageChangeListener(object : OnPageChangeListener { + override fun onPageScrolled( + position: Int, + positionOffset: Float, + positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + + } + + override fun onPageScrollStateChanged(state: Int) { + + } + }) + +// //设置当前tab为仪高镜高 +// mBinding.vp.currentItem = 1 + } + + + private inner class MyPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { + override fun getCount(): Int { + return fragments.size + } + + override fun getPageTitle(position: Int): CharSequence { + return fragmentTitleList[position] + } + + override fun getItem(position: Int): Fragment { + return fragments[position] + } + + override fun getItemPosition(`object`: Any): Int { + return POSITION_NONE + } + } + + private fun doConfirm() { + //检查未完成的选项 + for (fragment in fragments) { + val operate = fragment as IStationSettingOperate + if (operate.checkSaveNot()) { + val fragmentNotFinishPos = fragments.indexOf(fragment) + if (mBinding.vp.currentItem != fragmentNotFinishPos) { + mBinding.tabLayout.currentTab = fragmentNotFinishPos + } + return + } + } + + viewModel.createNeedSaveLevelRouteSave(getRouteId(), getStationId()) + //赋值 + for (fragment in fragments) { + val operate = fragment as IStationSettingOperate + operate.setDataToStation() + } + + viewModel.save(getIsSaveEndStation()) { + finish() + } + } + + private fun getStationId() = intent.getStringExtra(BundleConstants.KEY_SURVEYOR_STATION_ID)!! + + private fun getRouteId() = intent.getStringExtra(BundleConstants.KEY_ROUTE_ID)!! + private fun getIsSaveEndStation() = intent.getBooleanExtra(KEY_IS_SAVE_END_STATION, false) +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListAdapter.java new file mode 100644 index 0000000..6ec1daf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListAdapter.java @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.func.level.adapter; + + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord; +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil; + +import com.bingce.controlnetwork.databinding.ItemLevelRouteListBinding; +import com.bingce.controlnetwork.newui.adapter.BaseAdapterNew; + + +public class LevelRouteListAdapter extends BaseAdapterNew { + + public LevelRouteListAdapter(Context context) { + super(context); + } + + @NonNull + @Override + public LevelRouteListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new LevelRouteListViewHolder(ItemLevelRouteListBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(LevelRouteListViewHolder holder, int position) { + LevelRouteRecord bean = mDataList.get(position); + holder.mBinding.tvIndex.setText(String.valueOf(position + 1)); + holder.mBinding.tvRouteName.setText(bean.getRouteName()); + holder.mBinding.tvOrderType.setText(LevelingMeasureOrderUtil.INSTANCE.getTextByLevelingMeasureOrder(bean.getLevelingMeasureOrder())); + holder.mBinding.tvWay.setText(bean.getObservationDirection()); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListViewHolder.java new file mode 100644 index 0000000..12bc6ce --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListViewHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.func.level.adapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.ItemLevelRouteListBinding; + + +public class LevelRouteListViewHolder extends RecyclerView.ViewHolder { + public final ItemLevelRouteListBinding mBinding; + + public LevelRouteListViewHolder(ItemLevelRouteListBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelConstant.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelConstant.kt new file mode 100644 index 0000000..eda529e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelConstant.kt @@ -0,0 +1,13 @@ +package cn.liuyanbing.surveyor.function.level.constant + +/** + * 水准常量 + */ +object LevelConstant { + /** + * 默认经纬度郑州 + */ + const val LONGITUDE_DEFAULT = 113.6482317 + const val LATITUDE_DEFAULT = 34.7492133 + const val HEIGHT_DEFAULT = 0.0 +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelStationSettingContant.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelStationSettingContant.kt new file mode 100644 index 0000000..b76a247 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelStationSettingContant.kt @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.func.level.constant + +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R + +object LevelStationSettingContant { + val observationDirectionList = listOf("往测", "返测", "检往", "检返", "重往", "重返") + val weatherList = listOf("晴", "阴", "雨", "雪") + val imagingList = + listOf("清晰", "小雾", "中雾", "大雾") + val sunDirectionList = + listOf("无太阳", "前", "后", "左", "右") + val windDirectionList = + listOf( + "无", + "东", + "南", + "西", + "北", + "东南", + "西南", + "东北", + "西北" + ) + val windSpeedList = + listOf( + "无", + "0级无风", + "1级软风", + "2级轻风", + "3级微风", + "4级和风", + "5级清劲风", + "6级强风", + "7级疾风", + "8级大风" + ) + val roadsList = + listOf( + Tools.getString(R.string.please_choose), + "柏油路", "水泥路", "土路", "砂石路", "铁路", "其他" + ) + + val soilList = + listOf( + Tools.getString(R.string.please_choose), + "柏油", "水泥", "实土", "沙石", "草地" + ) + + val rulerTypeList = listOf("铟瓦尺", "木质", "其他") + + //尺承类型 + val rulerReceptTypeList = + listOf("钢尺桩", "5kg以上尺台", "不足5kg尺台", "钢帽钉", "木桩", "其他") +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/dialog/LevelToleranceTipsFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/dialog/LevelToleranceTipsFragment.java new file mode 100644 index 0000000..e6bd0f7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/dialog/LevelToleranceTipsFragment.java @@ -0,0 +1,129 @@ +package com.bingce.controlnetwork.func.level.dialog; + +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_IGNORE; +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_REMEASURE_POINT; +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_REMEASURE_STATION; + +import android.app.Dialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.R; + +/** + * 水准限差超限提示框 + */ +public class LevelToleranceTipsFragment extends AppCompatDialogFragment { + + private static final String KEY_TITLE = "__TITLE"; + private static final String KEY_CONTENT = "___CONTENT"; + private static final String KEY_RESULT = "KEY_RESULT"; + private static final String KEY_BUNDLE = "KEY_BUNDLE"; + + private static final String TAG = LevelToleranceTipsFragment.class.getName(); + + public static void tips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String title, + String content, + IOperatorCallback callback) { + Bundle args = new Bundle(); + LevelToleranceTipsFragment fragment = new LevelToleranceTipsFragment(); + fragment.setArguments(args); + args.putString(KEY_TITLE, title); + args.putString(KEY_CONTENT, content); + fragmentManager + .setFragmentResultListener( + KEY_BUNDLE, + lifecycleOwner, + (requestKey, result) -> { + int type = result.getInt(KEY_RESULT, -1); + if (VALUE_IGNORE == type) { + callback.onIgnore(); + } else if (VALUE_REMEASURE_STATION == type) { + callback.onReMeasureStation(); + } else if (VALUE_REMEASURE_POINT == type) { + callback.onReMeasurePoint(); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IOperatorCallback { + void onReMeasureStation(); + + void onReMeasurePoint(); + + void onIgnore(); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_level_tolerance_tips, container, false); + + TextView tvTitle = contentView.findViewById(R.id.tvTitle); + tvTitle.setText(getTitle()); + TextView tvContent = contentView.findViewById(R.id.tvContent); + tvContent.setText(getContent()); + + contentView.findViewById(R.id.btnIgnore).setOnClickListener(v -> { + setBackResult(VALUE_IGNORE); + }); + contentView.findViewById(R.id.btnRemeasureStation).setOnClickListener(v -> { + setBackResult(VALUE_REMEASURE_STATION); + }); + contentView.findViewById(R.id.btnRemeasureCurrent).setOnClickListener(v -> { + setBackResult(VALUE_REMEASURE_POINT); + }); + return contentView; + } + + private void setBackResult(int clickType) { + Bundle bundle = new Bundle(); + bundle.putInt(KEY_RESULT, clickType); + getParentFragmentManager().setFragmentResult(KEY_BUNDLE, bundle); + //关闭dialog + dismissAllowingStateLoss(); + } + + @Override + public void onStart() { + super.onStart(); + Dialog dialog = getDialog(); + if (dialog == null) { + return; + } + dialog.getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + private String getTitle() { + Bundle arguments = getArguments(); + if (arguments != null) { + return arguments.getString(KEY_TITLE); + } + return null; + } + + private String getContent() { + Bundle arguments = getArguments(); + if (arguments != null) { + return arguments.getString(KEY_CONTENT); + } + return null; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportIDetection.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportIDetection.kt new file mode 100644 index 0000000..d715a5e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportIDetection.kt @@ -0,0 +1,231 @@ +package cn.liuyanbing.surveyor.function.level.export + +import android.util.Log +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil +import com.bingce.controlapphelper.model.getLength +import com.bingce.controlnetwork.func.level.util.LevelDateUtil +import com.bingce.controlnetwork.func.level.util.LevelDateUtil.getLevelHeadDateHourMin + +/** + * i角检测导出 + */ +class LevelExportIDetection { + + private var levelNoIndex = 0 + + companion object { + const val _N = "\r\n" + const val _S = "\u0020" + const val LEVEL_NO = "LEVEL|No" + const val TO = "TO" + const val INF = "INF" + const val SHU = "|" + const val CHECK_RECORD_SIZE = 20 + } + + + @WorkerThread + fun export(iDetection: LevelIDetectionList): String? { + val recordList = + LevelingDbFactory.instance.iDetectionRecordDataSource.getRecordsByIDetectionId( + iDetection.id + ) + + if (recordList.isEmpty() || recordList.size != CHECK_RECORD_SIZE) { + return null + } + if (iDetection.iResult == null) { + return null + } + if (iDetection.shortDistance == null || iDetection.longDistance == null + || iDetection.measureType == null + ) { + return null + } + val firstRecordCreateDate = recordList.first().createDate + val dateYMD = + LevelDateUtil.getLevelHeadDateYearMonthDay(firstRecordCreateDate) + val dateHM = getLevelHeadDateHourMin(firstRecordCreateDate) + + val settting = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId(iDetection.id) + + val sb = StringBuilder() + + //startI + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append(TO).append(getSpace2()).append("Start-I").append(getSpace10()) + .append(iDetection.measureType).append(SHU).append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU).append(getSpace30()).append(SHU) + .append(_N) + + levelNoIndexIncrease() + + //i角检测的设置 + appendSetting(sb, "instrumentModel", toString(settting.instrumentModel)) + appendSetting(sb, "deviceNumber", "No.${toString(settting.deviceNumber)}") + appendSetting(sb, "dateYMD", dateYMD) + appendSetting(sb, "dateHM", dateHM) + appendSetting(sb, "rulerNum1", toString(settting.rulerNum1)) + appendSetting(sb, "rulerNum2", toString(settting.rulerNum2)) + appendSetting(sb, "imaging", toString(settting.imaging)) + appendSetting(sb, "watcher", toString(settting.watcher)) + appendSetting(sb, "recorder", toString(settting.recorder)) + appendSetting(sb, "examiner", toString(settting.examiner)) + //D1 D2 + appendD1D2(sb, "D1", iDetection.shortDistance) + appendD1D2(sb, "D2", iDetection.longDistance) + + //先排个序 + recordList.sortWith( + Comparator.comparing(LevelIDetectionRecord::stationType) + .thenComparing(LevelIDetectionRecord::rulerType) + .thenComparing(LevelIDetectionRecord::measureTime) + ) + for (record in recordList) { + Log.d( + "hwhw", + "" + record.stationType + "," + record.rulerType + "," + record.measureTime + ) + appendRecord(sb, record) + } + //iResult + val iResultUnit = if (iDetection.iResult != null) { + "${iDetection.iResult} s" + } else { + "" + } + val spaceIResultLeft = getSpace(30 - 4 - iResultUnit.length - 1) + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append("I").append(getSpace(29)).append(SHU) + .append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU) + .append("I").append(spaceIResultLeft).append(iResultUnit).append(getSpace4()) + .append(SHU) + .append(_N) + levelNoIndexIncrease() + //endI + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append(TO).append(getSpace(4)).append("End-I").append(getSpace(19)).append(SHU) + .append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU) + .append(_N) + + return sb.toString() + } + + private fun levelNoIndexIncrease() { + levelNoIndex++ + } + + private fun appendRecord(sb: StringBuilder, record: LevelIDetectionRecord) { + val hourMinSec = LevelDateUtil.getHourMinSec(record.createDate) + + val height = LevelFormatUtil.formatHeight(record.height) + val distance = LevelFormatUtil.formatDistance(record.distance) + val heightUnit = "$height m" + val distanceUnit = "$distance m" + + val space2 = getSpace2() + val spaceHeightLeft = getSpace(24 - 2 - heightUnit.length) + val spaceDistanceLeft = getSpace(28 - 2 - distanceUnit.length) + + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append("KD1").append(getSpace10()).append("${record.measureTime + 1}") + .append(getSpace8()).append(hourMinSec).append(SHU) + .append(getRI1A(record)).append(spaceHeightLeft).append(heightUnit).append(space2) + .append(SHU) + .append("HD").append(spaceDistanceLeft).append(distanceUnit).append(space2).append(SHU) + .append(getSpace30()).append(SHU) + .append(_N) + + levelNoIndexIncrease() + } + + private fun getRI1A(record: LevelIDetectionRecord): String { + return if (record.stationType == LevelIDetectionConstant.STATION_TYPE_0) { + if (record.rulerType == LevelIDetectionConstant.RULER_TYPE_0) { + "R_I1_A" + } else { + "R_I1_B" + } + } else { + if (record.rulerType == LevelIDetectionConstant.RULER_TYPE_0) { + "R_I2_A" + } else { + "R_I2_B" + } + } + } + + private fun appendD1D2(sb: StringBuilder, d1: String, d1Value: String) { + val d1ValueFormat = LevelFormatUtil.formatHeight(toDouble(d1Value)) + val d1ValueUnit = "$d1ValueFormat m" + + val d1ValueUnitLength = d1ValueUnit.length + + val spaceValueLeft = getSpace(30 - 4 - d1ValueUnitLength - 1) + val spaceValueRight = getSpace4() + + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append(d1).append(getSpace28()).append(SHU) + .append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU) + .append("D").append(spaceValueLeft).append(d1ValueUnit).append(spaceValueRight) + .append(SHU) + .append(_N) + levelNoIndexIncrease() + } + + private fun appendSetting(sb: StringBuilder, key: String, value: String) { + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append(INF).append(getSpace27()).append(SHU) + .append(key).append(getSettingKeyRightSpace(key)).append(SHU) + .append(getSpace30()).append(SHU) + .append(value).append(getSettingValueRightSpace(value)).append(SHU) + .append(_N) + levelNoIndexIncrease() + } + + private fun getLevelNoRightSpace(): String { + val length = getNoIndexName().length + return getSpace(8 - length) + } + + private fun getSettingKeyRightSpace(key: String): String { + val length = key.length + return getSpace(30 - length) + } + + private fun getSettingValueRightSpace(value: String): String { + val length = getLength(value) + return getSpace(30 - length) + } + + private fun getNoIndexName() = "${levelNoIndex + 1}" + + + private fun getSpace2() = getSpace(2) + private fun getSpace4() = getSpace(4) + private fun getSpace8() = getSpace(8) + private fun getSpace10() = getSpace(10) + private fun getSpace27() = getSpace(27) + private fun getSpace28() = getSpace(28) + + private fun getSpace30() = getSpace(30) + + private fun getSpace(size: Int) = _S.repeat(size) + + private fun toString(value: String?) = value ?: "" + private fun toDouble(value: String?): Double { + return value?.toDouble() ?: 0.0 + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportSingalHeight.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportSingalHeight.kt new file mode 100644 index 0000000..3813d9c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportSingalHeight.kt @@ -0,0 +1,218 @@ +package com.bingce.controlnetwork.func.level.export + +import android.text.TextUtils +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model._N +import com.bingce.controlapphelper.model._S +import com.bingce.controlapphelper.model._T +import com.bingce.controlapphelper.surveyor.method.ExportStationMethod +import com.bingce.controlapphelper.surveyor.method.model.MeasureConstant +import java.io.File + +class LevelExportSingalHeight { + private var routeIndex = 0 + + private val singalHeightSb = StringBuilder() + private val rulerLengthSb = StringBuilder() + private val pointNumNameSb = StringBuilder() + private val heightDistanceSb = StringBuilder() + private val pointKnownSb = StringBuilder() + + + @WorkerThread + fun export(projectFolder: File, projectId: String) { + collectRulerLength(projectId) + collectPoint(projectId) + collectSingalHeight(projectId) + + val prepare4Folder = initPrepare4Folder(projectFolder) + + saveData(projectFolder, singalHeightSb, "SingalHeight.txt") + saveData(prepare4Folder, rulerLengthSb, "尺长.txt") + saveData(prepare4Folder, pointNumNameSb, "点名点号.txt") + saveData(prepare4Folder, heightDistanceSb, "高差文件.txt") + saveData(prepare4Folder, pointKnownSb, "已知.txt") + } + + private fun saveData(projectFolder: File, data: StringBuilder, fileName: String) { + if (data.isNotEmpty()) { + ExportStationMethod.save( + data.toString(), + projectFolder, + fileName + ) + } + } + + private fun collectSingalHeight(projectId: String) { + val routeList = LevelingDbFactory.instance.levelDataSource.getByProjectIdSync(projectId) + + for (route in routeList) { + + val routeId = route.getId() + + val pointNameStart = getPointName(route.startPointId) + val pointNameEnd = getPointName(route.endPointId) + + val levelingMeasureOrder = route.levelingMeasureOrder + val isHasTwiceStation = when (levelingMeasureOrder) { + LevelingMeasureOrder.SIM_BF, + LevelingMeasureOrder.SIM_BFFB -> { + true + } + + else -> false + } + + val routeLastStationSetting = + LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + + appendData( + projectId, + routeId, + pointNameStart, + pointNameEnd, + false, + routeLastStationSetting + ) + if (isHasTwiceStation) { + appendData( + projectId, + routeId, + pointNameStart, + pointNameEnd, + true, + routeLastStationSetting + ) + } + } + + heightDistanceSb.append("END") + } + + /** + * 点名点号 + * 已知点 + */ + private fun collectPoint(projectId: String) { + val pointList = SurveyorDatabaseFactory.instance.pointDataSource.findByProjectIdSync(projectId) + for (point in pointList) { + if (PointRecord.TYPE_KNOWN_POINT == point.pointType) { + pointKnownSb.append(point.getName()).append(_S).append(point.getZFormat(4)) + } + pointNumNameSb.append(point.getName()).append(_S).append("") + .append(_N) + } + pointNumNameSb.append("END") + pointKnownSb.append("END") + } + + /** + * 收集尺长 + */ + private fun collectRulerLength(projectId: String) { + val routeList = SurveyorDatabaseFactory.instance.pointDataSource.findByProjectIdSync(projectId) + for (route in routeList) { + val latest = LevelingDbFactory.instance.stationSettingDataSource.getLatest(route.id) + + val rulerCorrectionFactor = if (!TextUtils.isEmpty(latest.rulerCorrectionFactor)) { + "${latest.rulerCorrectionFactor.toDouble() / 1000}" + } else { + "0" + } + + rulerLengthSb.append("1").append(_S).append(rulerCorrectionFactor) + .append(_N) + } + rulerLengthSb.append("END") + } + + private fun appendData( + projectId: String, + routeId: String, + pointNameStart: String, + pointNameEnd: String, + twiceStation: Boolean, + routeLatestSetting: LevelingStationSettingRecord + ) { + + val stationFirst = + LevelingDbFactory.instance.stationDataSource.getStationFirstTwiceStation( + projectId, + routeId, + twiceStation + ) + + val stationLatest = + LevelingDbFactory.instance.stationDataSource.getStationLatestTwiceStation( + projectId, + routeId, + twiceStation + ) + + val measureStation = + LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationLatest.getId()) + ?: return + + singalHeightSb.append(getRouteNum()).append(_T)//编号 + .append(pointNameStart).append(_T)//起点 + .append(pointNameEnd).append(_T)//终点 + .append(LevelFormatUtil.formatHeight(measureStation.heightDiffTotal)).append(_T)//高差 + .append(LevelFormatUtil.formatHeight(measureStation.distanceTotal)).append(_T)//距离 + .append("0.00000").append(_T)//温度改正 + .append(getExportRulerCorrectionFactor(routeLatestSetting)).append(_T)//标尺改正系数 + .append("1").append(_T)//结束标志 + .append(routeLatestSetting.soil ?: "水泥").append(_T)//土质 + .append(stationFirst.createDate.time).append(_T)//开始时间 + .append(stationLatest.createDate.time).append(_T)//结束时间 + .append(routeLatestSetting.temperature ?: MeasureConstant.DEFAULT_TEMPERATURE) + .append(_T)//温度 + .append(routeLatestSetting.firstStationFrontFootNumber ?: "").append(_T)//标尺1 + .append(routeLatestSetting.firstStationBackFootNumber ?: "").append(_T)//标尺2 + .append(measureStation.stationNumForenoonTotal).append(_T)//上午测站数 + .append(measureStation.stationNumAfternoonTotal).append(_T)//下午测站数 + .append(_N) + + heightDistanceSb.append(pointNameStart).append(_S) + .append(pointNameEnd).append(_S) + .append(LevelFormatUtil.formatHeight(measureStation.heightDiffTotal)).append(_S)//高差 + .append(LevelFormatUtil.formatHeight(measureStation.distanceTotal)).append(_S)//距离 + .append("1").append(_N)//结束标志 + + routeIndex++ + } + + private fun getExportRulerCorrectionFactor(routeLatestSetting: LevelingStationSettingRecord): String { + return if (!TextUtils.isEmpty(routeLatestSetting.rulerCorrectionFactor)) { + "${routeLatestSetting.rulerCorrectionFactor.toDouble() / 1000}" + } else { + "0" + } + } + + private fun getPointName(pointId: String): String { + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId)?.getName() ?: "" + } + + private fun getRouteNum(): String { + return String.format("%04d", routeIndex + 1) + } + + /** + * 初始化平差准备文件夹 + */ + private fun initPrepare4Folder(projectFolder: File): File { + val exportFolder = File(projectFolder, "平差准备文件") + if (!exportFolder.exists()) { + exportFolder.mkdir() + } + return exportFolder + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelIDetectionCreateFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelIDetectionCreateFragment.java new file mode 100644 index 0000000..479c420 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelIDetectionCreateFragment.java @@ -0,0 +1,86 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.AbstractFullScreenDialogFragment; + +/** + * 新建编辑i角检测 + */ +public class LevelIDetectionCreateFragment extends AbstractFullScreenDialogFragment { + @Override + protected View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_level_i_detection_create_edit, container, false); + EditText editText = view.findViewById(R.id.editor); + if (editText != null && getArguments() != null) { + editText.setText(getArguments().getString(KEY_DEFAULT_STRING)); + } + return view; + } + + @Override + protected void onConfirm() { + Bundle args = new Bundle(); + if (getView() != null) { + EditText editText = getView().findViewById(R.id.editor); + if (editText.getText() != null) { + String string = editText.getText().toString(); + if (string.isEmpty()) { + Toast.makeText(getContext(), + R.string.string_no_empty, + Toast.LENGTH_SHORT).show(); + return; + } + args.putString(KEY_STRING_RESULT, string); + } + } + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST_INPUT, args); + super.onConfirm(); + } + + private static final String TAG = LevelIDetectionCreateFragment.class.getName(); + private static final String KEY_REQUEST_INPUT = LevelIDetectionCreateFragment.class.getName() + "_REQUEST"; + private static final String KEY_STRING_RESULT = LevelIDetectionCreateFragment.class.getName() + "_result"; + private static final String KEY_DEFAULT_STRING = LevelIDetectionCreateFragment.class.getName() + "__DEFAULT_STRING"; + + + public static void input(FragmentManager fragmentManager, + String title, + String defaultString, + LifecycleOwner lifecycleOwner, + IInputCallback callback) { + Bundle args = new Bundle(); + LevelIDetectionCreateFragment fragment = new LevelIDetectionCreateFragment(); + fragment.setArguments(args); + if (defaultString != null) { + args.putString(KEY_DEFAULT_STRING, defaultString); + } + AbstractFullScreenDialogFragment.setArgs(args, title, null); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_INPUT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_INPUT.equals(requestKey)) { + callback.onGetInput(result.getString(KEY_STRING_RESULT)); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IInputCallback { + void onGetInput(String string); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputAllowFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputAllowFragment.java new file mode 100644 index 0000000..8ec55ec --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputAllowFragment.java @@ -0,0 +1,91 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; + + +public class LevelInputAllowFragment extends AppCompatDialogFragment { + + public static String KEY_AUTO = "KEY_AUTO"; + public static String KEY_REQUEST = "KEY_REQUEST"; + + public static void show(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + boolean auto, IConfirmCallback callback) { + Bundle args = new Bundle(); + LevelInputAllowFragment fragment = new LevelInputAllowFragment(); + fragment.setArguments(args); + args.putBoolean(KEY_AUTO, auto); + + fragmentManager + .setFragmentResultListener( + KEY_REQUEST, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST.equals(requestKey)) { + if (callback != null) { + callback.onConfirm(result.getBoolean(KEY_AUTO)); + } + } + }); + + fragment.show(fragmentManager, null); + + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_level_input_allow, container, false); + SwitchWithText receiveDataType = contentView.findViewById(R.id.receiveDataType); + + receiveDataType.setChecked(getAuto()); + + contentView.findViewById(R.id.btnConfirm).setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putBoolean(KEY_AUTO, receiveDataType.isChecked()); + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST, bundle); + dismissAllowingStateLoss(); + }); + + return contentView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + public interface IConfirmCallback { + void onConfirm(Boolean auto); + } + + /** + * 仪器获取 + */ + private boolean getAuto() { + if (getArguments() != null) { + return getArguments().getBoolean(KEY_AUTO); + } + return true; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputFragment.java new file mode 100644 index 0000000..135b644 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputFragment.java @@ -0,0 +1,102 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.EditText; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.R; + +import blankj.utilcode.util.ToastUtils; + + +public class LevelInputFragment extends AppCompatDialogFragment { + + public static String KEY_DISTANCE = "KEY_DISTANCE"; + public static String KEY_HEIGHT = "KEY_HEIGHT"; + public static String KEY_REQUEST = "KEY_REQUEST"; + + public static void show(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + IConfirmCallback callback) { + Bundle args = new Bundle(); + LevelInputFragment fragment = new LevelInputFragment(); + fragment.setArguments(args); + + fragmentManager + .setFragmentResultListener( + KEY_REQUEST, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST.equals(requestKey)) { + if (callback != null) { + double distance = result.getDouble(KEY_DISTANCE); + double height = result.getDouble(KEY_HEIGHT); + callback.onConfirm(distance, height); + } + } + }); + + fragment.show(fragmentManager, null); + + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_level_input, container, false); + + EditText etDisTance = contentView.findViewById(R.id.etDisTance); + EditText etHeight = contentView.findViewById(R.id.etHeight); + + contentView.findViewById(R.id.btnConfirm).setOnClickListener(v -> { + + String disTance = getEtValue(etDisTance); + String height = getEtValue(etHeight); + if (TextUtils.isEmpty(disTance)) { + ToastUtils.showShort("请输入距离"); + return; + } + if (TextUtils.isEmpty(height)) { + ToastUtils.showShort("请输入高度"); + return; + } + + Bundle bundle = new Bundle(); + bundle.putDouble(KEY_DISTANCE, Double.parseDouble(disTance)); + bundle.putDouble(KEY_HEIGHT, Double.parseDouble(height)); + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST, bundle); + dismissAllowingStateLoss(); + }); + + return contentView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + private String getEtValue(EditText et) { + return et.getText().toString().trim(); + } + + public interface IConfirmCallback { + void onConfirm(double distance, double height); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteCreateEditFragment.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteCreateEditFragment.kt new file mode 100644 index 0000000..6e8260a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteCreateEditFragment.kt @@ -0,0 +1,382 @@ +package com.bingce.controlnetwork.func.level.fragment + +import android.content.Context +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter +import android.widget.EditText +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import cn.liuyanbing.surveyor.function.level.constant.LevelConstant +import com.bingce.controlnetwork.func.level.constant.LevelStationSettingContant +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil.getSpinnerText +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil +import com.bingce.controlapphelper.model.PickPointResult +import com.bingce.controlapphelper.util.CheckLocationUtil +import com.bingce.controlapphelper.util.GetLocationUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlnetwork.databinding.FragmentLevelCreateRouteBinding +import com.bingce.controlnetwork.fragment.PickPointFragment +import com.bingce.controlnetwork.func.level.viewmodel.LevelCreateOrEditRouteVm +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.newui.projectedit.ProjectLastData +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelRouteCreateEditFragment : BaseFragmentBinding() { + + private val viewModel by viewModels() + + private val SELECT_POINT_TYPE_START = "SELECT_POINT_TYPE_START" + private val SELECT_POINT_TYPE_END = "SELECT_POINT_TYPE_END" + + private var pickPointResultStart: PickPointResult? = null + private var pickPointResultEnd: PickPointResult? = null + + private lateinit var levelingMeasureOrder: LevelingMeasureOrder + + private val getLocation by lazy { + GetLocationUtil() + } + + + private val defaultStationLauncher = PickPointFragment.createActivityLauncher( + this + ) { type: String, pickPointResult: PickPointResult -> + if (SELECT_POINT_TYPE_START == type) { + pickPointResultStart = pickPointResult + } else if (SELECT_POINT_TYPE_END == type) { + pickPointResultEnd = pickPointResult + } + if (pickPointResult.selectedIds.isNullOrEmpty() + || pickPointResult.selectedNames.isNullOrEmpty() + || pickPointResult.selectedNames.size != pickPointResult.selectedIds.size + ) { + ToastUtils.showShort(R.string.abnormal_point_selection) + return@createActivityLauncher + } + setSelectPointUi() + } + + + companion object { + @JvmField + val TAG = LevelRouteCreateEditFragment::class.java.getName() + + @JvmStatic + fun newInstance(args: Bundle?): Fragment { + val fragment: Fragment = LevelRouteCreateEditFragment() + fragment.setArguments(args) + return fragment + } + + @JvmStatic + fun start(context: Context, projectId: String, routeId: String?, title: String) { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + bundle.putString(BundleConstants.KEY_ROUTE_ID, routeId) + FragmentContainerActivity.start(context, TAG, title, bundle) + } + } + + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentLevelCreateRouteBinding { + return FragmentLevelCreateRouteBinding.inflate(inflater, container, false) + } + + override fun initView() { + lifecycle.addObserver(getLocation) + initLevelOrder() + initListener() + } + + private fun initListener() { + mBinding.btnConfirm.setOnClickListener { + checkConfirm() + } + mBinding.btnDetermineAndMeasure.setOnClickListener { + + } + + mBinding.ivSelectStartPoint.setOnClickListener { + selectPoint(SELECT_POINT_TYPE_START) + } + mBinding.ivSelectEndPoint.setOnClickListener { + selectPoint(SELECT_POINT_TYPE_END) + } + + mBinding.ivGetLocation.setOnClickListener { + getLocation { + setLocation(mBinding.etLongitude, mBinding.etLatitude, mBinding.etHeight, it) + } + } + } + + override fun initData() { + initSpinnerObservationDirection() + + initEditData() + } + + private fun initEditData() { + val routeId = getRouteId() + if (routeId != null) { + viewModel.getEditRouteData(routeId) { + mBinding.etStartPoint.setText(it.startPointName) + mBinding.etEndPoint.setText(it.endPointName) + mBinding.spinnerObservationDirection.setSelection( + LevelStationSettingContant.observationDirectionList.indexOf( + it.observationDirection + ) + ) + +// //经纬度 +// if (isEmpty(it.longitude) || isEmpty(it.latitude)) { +// setDefaultLocation() +// } else { +// setLocation( +// mBinding.etLongitude, +// mBinding.etLatitude, +// mBinding.etHeight, +// it.longitude, +// it.latitude, +// it.z +// ) +// } + + } + } else { + setDefaultLocation() + } + } + + private fun setSelectPointUi() { + if (pickPointResultStart == null) { + mBinding.etStartPoint.setText("") + } else { + mBinding.etStartPoint.setText(pickPointResultStart!!.selectedNames[0]) + } + if (pickPointResultEnd == null) { + mBinding.etEndPoint.setText("") + } else { + mBinding.etEndPoint.setText(pickPointResultEnd!!.selectedNames[0]) + } + } + + private fun selectPoint(type: String) { + var title: String? = null + var pickPointResultSelected: PickPointResult? = null + var filderIds: List? = null + if (SELECT_POINT_TYPE_START == type) { + pickPointResultSelected = pickPointResultStart + filderIds = pickPointResultEnd?.selectedIds + title = getString(R.string.choose_starting_point) + } else if (SELECT_POINT_TYPE_END == type) { + pickPointResultSelected = pickPointResultStart + filderIds = pickPointResultStart?.selectedIds + title = getString(R.string.select_end_point) + } + PickPointFragment.pickKnownAndUnknownPoint( + context, + type, + 1, + title, + filderIds, + getProjectId(), + pickPointResultSelected, + defaultStationLauncher + ) + } + + /** + * 照准次序 + */ + private fun initLevelOrder() { + val showList = LevelingMeasureOrderUtil.getShowList() + mBinding.spinner.setAdapter( + ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + showList + ) + ) + mBinding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, + view: View, + position: Int, + id: Long + ) { + levelingMeasureOrder = LevelingMeasureOrderUtil.getLevelingMeasureOrderByCreate( + showList[position] + ) + } + + override fun onNothingSelected(parent: AdapterView<*>?) {} + } + + + + mBinding.spinner.setSelection(0) + } + + /** + * 观测方向 + */ + private fun initSpinnerObservationDirection() { + mBinding.spinnerObservationDirection.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.observationDirectionList + ) + mBinding.spinnerObservationDirection.onItemSelectedListener = + object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, + view: View, + position: Int, + id: Long + ) { + + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + } + + private fun checkConfirm() { + val projectId = getProjectId() + if (projectId == null) { + ToastUtils.showShort(R.string.project_data_is_empty) + return + } + + val startPointName = mBinding.etStartPoint.getText().toString().trim() + if (TextUtils.isEmpty(startPointName)) { + ToastUtils.showShort(R.string.please_enter_or_select_a_starting_point) + return + } + val endPointName = mBinding.etEndPoint.getText().toString().trim() + if (TextUtils.isEmpty(endPointName)) { + ToastUtils.showShort(R.string.please_enter_or_select_a_destination) + return + } + + val longitude = mBinding.etLongitude.getText().toString().trim() + if (TextUtils.isEmpty(longitude)) { + ToastUtils.showShort(R.string.please_input_longitude) + return + } + val latitude = mBinding.etLatitude.getText().toString().trim() + if (TextUtils.isEmpty(latitude)) { + ToastUtils.showShort(R.string.please_input_latitude) + return + } + val height = mBinding.etHeight.getText().toString().trim() + if (TextUtils.isEmpty(height)) { + ToastUtils.showShort(R.string.please_enter_elevation) + return + } + + val levelRouteSave = LevelRouteSave() + levelRouteSave.projectId = projectId + levelRouteSave.routeId = getRouteId() + levelRouteSave.routeName = "$startPointName-$endPointName" + levelRouteSave.startPointName = startPointName + levelRouteSave.endPointName = endPointName + levelRouteSave.levelingMeasureOrder = levelingMeasureOrder + + //观测方向 + levelRouteSave.observationDirection = getSpinnerText(mBinding.spinnerObservationDirection) + + viewModel.startSave(requireContext(), levelRouteSave) { isSuccess: Boolean -> + if (isSuccess) requireActivity().finish() + } + } + + private fun getProjectId() = getArgumentString(BundleConstants.KEY_PROJECT_ID) + private fun getRouteId() = getArgumentString(BundleConstants.KEY_ROUTE_ID) + + + private fun getLocation(resultListener: GetLocationUtil.IResultListener) { + CheckLocationUtil.check(requireContext()) { + getLocation.getResult(resultListener) + } + } + + private fun setLocation( + etLongitude: EditText, + etLatitude: EditText, + etHeight: EditText, + result: GetLocationUtil.Result? + ) { + setLocation( + etLongitude, + etLatitude, + etHeight, + result?.longitude, + result?.latitude, + result?.altitude + ) + } + + private fun setLocation( + etLongitude: EditText, + etLatitude: EditText, + etHeight: EditText, + longitude: String?, + latitude: String?, + z: String? + ) { + etLongitude.setText(longitude) + etLatitude.setText(latitude) + etHeight.setText(z) + } + + private fun setDefaultLocation() { + lifecycleScope.launch(Dispatchers.IO) { + val longitude = ProjectLastData.getLongitude() + val latitude = ProjectLastData.getLatitude() + withContext(Dispatchers.Main) { + if (isEmpty(latitude) || isEmpty(latitude)) { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + mBinding.etHeight, + LevelConstant.LONGITUDE_DEFAULT.toString(), + LevelConstant.LATITUDE_DEFAULT.toString(), + LevelConstant.HEIGHT_DEFAULT.toString() + ) + } else { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + mBinding.etHeight, + longitude, + latitude, + LevelConstant.HEIGHT_DEFAULT.toString() + ) + } + } + } + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteFragment.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteFragment.kt new file mode 100644 index 0000000..8e77396 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteFragment.kt @@ -0,0 +1,158 @@ +package com.bingce.controlnetwork.func.level.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import androidx.room.withTransaction +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.func.level.viewmodel.LevelCreateOrEditRouteVm +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit +import com.bingce.controlnetwork.databinding.FragmentListLayoutBinding +import com.bingce.controlnetwork.fragment.TipsFragment +import com.bingce.controlnetwork.func.level.adapter.LevelRouteListAdapter +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelRouteFragment : Fragment() { + + private val createOrEditRouteVm by viewModels() + + private var _binding: FragmentListLayoutBinding? = null + val mBinding get() = _binding!! + + private val dataList = mutableListOf() + + private val adapter by lazy { + LevelRouteListAdapter(requireContext()) + } + + private fun doLookAndEditRoute(item: LevelRouteRecord) { + createOrEditRouteVm.showCreateOrEditDialog( + requireContext(), + getProjectId(), + routeId = item.getId() + ) + } + + private fun doDelete(item: LevelRouteRecord) { + lifecycleScope.launch(Dispatchers.IO) { + + val stationList = SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRoute( + item.projectId, + item.getId() + ) + + var hasData = false + for (stationItem in stationList) { + val recordCount = + SurveyorDatabaseFactory.instance.surveyorRecordDataSource.recordCount( + stationItem.getId() + ) + if (recordCount > 0) { + hasData = true + break + } + } + + if (hasData) { + withContext(Dispatchers.Main) { + TipsFragment.cancelAbleTips( + childFragmentManager, viewLifecycleOwner, context, + getString(R.string.tips_is_sure_to_delete_route_with_record), + 4 + ) { + deleteDatabase(item) + } + } + } else { + deleteDatabase(item) + } + } + } + + private fun deleteDatabase(routeRecord: LevelRouteRecord) { + lifecycleScope.launch(Dispatchers.IO) { + SurveyorDataBase.getInstance().withTransaction { + //删除路线 + LevelingDbFactory.instance.levelDataSource.delete(routeRecord) + //删除测站 + LevelingDbFactory.instance.stationDataSource.deleteByRouteId(routeRecord.getId()) + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentListLayoutBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initAdapter() + + LevelingDbFactory.instance.levelDataSource.getListLiveData(getProjectId()) + .observe(viewLifecycleOwner) { + adapter.refreshData(it) + } + } + + private fun initAdapter() { + mBinding.list.adapter = adapter + + adapter.setAdapterContextMenu(object : ContextMenuDeleteEdit() { + override fun delete(item: LevelRouteRecord) { + doDelete(item) + } + + override fun edit(item: LevelRouteRecord) { + doLookAndEditRoute(item) + } + }) + } + + + fun getProjectId() = requireArguments().getString(BundleConstants.KEY_PROJECT_ID)!! + + + companion object { + @JvmStatic + fun newInstance(projectId: String): LevelRouteFragment { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + val routeFragment = LevelRouteFragment() + routeFragment.arguments = bundle + return routeFragment + } + } + + /** + * 获取即将要测量的路线id + */ + fun getSurveyorRouteId(): String? { + if (dataList.isNotEmpty()) { + return dataList.last().getId() + } + return null + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSelectExportFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSelectExportFragment.java new file mode 100644 index 0000000..7b60018 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSelectExportFragment.java @@ -0,0 +1,248 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.os.Environment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.surveyor.method.ExportUtils; +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlapphelper.widget.treeview.TreeNode; +import com.bingce.controlapphelper.widget.treeview.TreeView; +import com.bingce.controlapphelper.widget.treeview.custom.MyNodeViewFactory; +import com.bingce.controlnetwork.BuildConfig; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.databinding.FragmentSelectExportBinding; +import com.bingce.controlnetwork.fragment.FullLoadingFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.func.level.util.LevelExportUtilTj; +import com.bingce.controlnetwork.func.level.viewmodel.LevelSelectExportVm; +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding; +import com.bingce.file.FileOperator; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.zip.ZipUtil; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; + +import blankj.utilcode.util.FileUtils; +import blankj.utilcode.util.ToastUtils; + + +/** + * 水准选择导出 + */ +public class LevelSelectExportFragment extends BaseFragmentBinding { + public static final String TAG = LevelSelectExportFragment.class.getName(); + + private LevelSelectExportVm viewModel; + + private TreeNode rootNode; + + public static LevelSelectExportFragment newInstance(Bundle args) { + LevelSelectExportFragment fragment = new LevelSelectExportFragment(); + fragment.setArguments(args); + return fragment; + } + + public static void start(Context context) { + FragmentContainerActivity.start(context, TAG, R.string.level_export, null); + } + + @Override + protected FragmentSelectExportBinding getViewBinding(@NonNull LayoutInflater inflater, ViewGroup container) { + return FragmentSelectExportBinding.inflate(inflater, container, false); + } + + @Override + protected void initView() { + viewModel = new ViewModelProvider(this).get(LevelSelectExportVm.class); + mBinding.title.setText(R.string.tips_select_expected_export_data_level); + initListener(); + } + + private void initListener() { + mBinding.export.setOnClickListener(v -> { + if (ExportUtils.isCanExport()) { + CheckStorageUtil.check(requireContext(), this::startExport); + } + }); + } + + private void startExport() { + DialogFragment dialogFragment = FullLoadingFragment.showLoading(getChildFragmentManager()); + + doExport(new ICallback() { + @Override + public void onFailureInMainThread(String msg) { + dialogFragment.dismiss(); + ToastUtils.showShort(msg); + } + + @Override + public void onSuccessInMainThread(File zip) { + if (dialogFragment.isVisible()) { + dialogFragment.dismiss(); + } + TipsWith2OptionFragment.tipsCannotCancel(getChildFragmentManager(), getViewLifecycleOwner(), + getString(R.string.share), + getString(R.string.cancel), + getString(R.string.export_successful), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + FileOperator.shareFile(getContext(), zip, BuildConfig.APPLICATION_ID); + } + }); + } + }); + } + + private void doExport(ICallback callback) { + List projectList = rootNode.getChildren(); + + ThreadPoolUtil.execute(() -> { + List exportRouteList = new ArrayList<>(); + HashSet exportProjectIdSet = new HashSet<>(); + for (TreeNode projectNode : projectList) { + List children = projectNode.getChildren(); + for (TreeNode routeNode : children) { + if (routeNode.isEnable() && routeNode.isSelected()) { + String projectId = projectNode.getValue().getId(); + String projectName = projectNode.getValue().getValue().toString(); + exportProjectIdSet.add(projectId); + exportRouteList.add(new ExportRoute(projectId, projectName, + routeNode.getValue().getId(), + routeNode.getValue().getValue().toString())); + } + } + } + if (exportRouteList.isEmpty()) { + backError(callback, "没有要导出的数据"); + return; + } + + try { + LevelExportUtilTj levelExportUtilTj = new LevelExportUtilTj(); + //导出路线数据 + for (ExportRoute exportRoute : exportRouteList) { + levelExportUtilTj.doExportRouteData(exportRoute.projectId, + exportRoute.routeId); + } + + for (String projectId : exportProjectIdSet) { + //导出项目数据 + levelExportUtilTj.exportProjectTxt(projectId); + //导出点信息 + levelExportUtilTj.exportControlTxt(projectId); + //导出i角检测 + levelExportUtilTj.exportIDetection(projectId); + //导出SingalHeight和平差准备文件 + levelExportUtilTj.exportTjSingalHeight(projectId); + } + + } catch (Exception e) { + e.printStackTrace(); + backError(callback, Tools.getString(R.string.export_failure)); + File sourceFileFolder = LevelExportUtilTj.Companion.getExportOutFolder(); + FileUtils.delete(sourceFileFolder); + return; + } + + //压缩文件 + File file = startZipFile(); + if (file == null) { + return; + } + ThreadPoolUtil.executeInMain(() -> callback.onSuccessInMainThread(file)); + }); + } + + private void backError(ICallback callback, String msg) { + ThreadPoolUtil.executeInMain(() -> callback.onFailureInMainThread(msg)); + } + + private File startZipFile() { + //源数据文件 + File sourceFileFolder = LevelExportUtilTj.Companion.getExportOutFolder(); + if (!sourceFileFolder.exists()) return null; + File[] files = sourceFileFolder.listFiles(); + if (files == null || files.length == 0) return null; + List sourceFileList = Arrays.asList(files); + + //将文件存储到一个zip中 + File zipFolder = new File(Environment.getExternalStorageDirectory(), ExportUtils.getExportFirstDirectory()); + if (!zipFolder.exists()) { + zipFolder.mkdir(); + } + + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.getDefault()); + String dateString = format.format(date); + File zip = new File(zipFolder, "水准数据_" + dateString + ".zip"); + if (!ZipUtil.zip(zip, sourceFileList)) { + ToastUtils.showShort(R.string.export_failure); + return null; + } + try { + //存储成功,删除被压缩的源文件 + FileUtils.delete(sourceFileFolder); + } catch (Exception e) { + e.printStackTrace(); + ToastUtils.showShort(R.string.export_failure); + return null; + } + return zip; + } + + @Override + protected void initData() { + viewModel.initData(treeNode -> { + setData(treeNode); + return null; + }); + } + + private void setData(TreeNode treeNode) { + rootNode = treeNode; + TreeView treeView = new TreeView(treeNode, requireContext(), new MyNodeViewFactory()); + treeView.setup(mBinding.list); + mBinding.list.setVisibility(View.VISIBLE); + mBinding.loading.setVisibility(View.GONE); + } + + private interface ICallback { + void onFailureInMainThread(String msg); + + void onSuccessInMainThread(File zip); + } + + private static class ExportRoute { + public String projectId; + public String projectName; + public String routeId; + public String routeName; + + public ExportRoute(String projectId, String projectName, String routeId, String routeName) { + this.projectId = projectId; + this.projectName = projectName; + this.routeId = routeId; + this.routeName = routeName; + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingConditionFragment.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingConditionFragment.kt new file mode 100644 index 0000000..7096797 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingConditionFragment.kt @@ -0,0 +1,185 @@ +package com.bingce.controlnetwork.func.level.fragment + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ArrayAdapter +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.constant.LevelStationSettingContant +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil +import com.bingce.controlnetwork.func.level.viewmodel.LevelStationSettingVm +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.surveyor.method.model.MeasureConstant +import com.bingce.controlnetwork.databinding.FragmentLevelStationSettingConditionBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.newui.stationsetting.IStationSettingOperate + +/** + * 水准测站设置-观测条件 + */ +class LevelStationSettingConditionFragment : + BaseFragmentBinding(), IStationSettingOperate { + + private val stationSettingVm by activityViewModels() + + private lateinit var levelRouteSave: LevelRouteSave + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentLevelStationSettingConditionBinding { + return FragmentLevelStationSettingConditionBinding.inflate(inflater, container, false) + } + + override fun initView() { + initEditTextTitle() + } + + private fun initEditTextTitle() { + mBinding.ilTemperature.tvTitle.text = "温度(℃)" + } + + override fun initData() { + initSpinnerWeather() + initSpinnerImaging() + initSpinnerSunDirection() + initSpinnerWindDirection() + initSpinnerWindSpeed() + initSpinnerRoads() + initSpinnerSoil() + + stationSettingVm.editLastDataLiveData.observe(viewLifecycleOwner) { + if (it == null) { + setTemperatureData(MeasureConstant.DEFAULT_TEMPERATURE) + } else { + setData(it) + } + } + } + + private fun initSpinnerSoil() { + mBinding.spinnerSoil.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.soilList + ) + } + + private fun initSpinnerRoads() { + mBinding.spinnerRoads.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.roadsList + ) + } + + private fun initSpinnerWindSpeed() { + mBinding.spinnerWindSpeed.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.windSpeedList + ) + } + + private fun initSpinnerWindDirection() { + mBinding.spinnerWindDirection.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.windDirectionList + ) + } + + private fun initSpinnerSunDirection() { + mBinding.spinnerSunDirection.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.sunDirectionList + ) + } + + private fun initSpinnerImaging() { + mBinding.spinnerImaging.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.imagingList + ) + } + + private fun initSpinnerWeather() { + mBinding.spinnerWeather.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.weatherList + ) + } + + override fun checkSaveNot(): Boolean { + if (isEmpty(mBinding.ilTemperature.editText.text.toString().trim())) { + ToastUtils.showShort("请输入温度") + return true + } + collectData() + return false + } + + override fun setDataToStation() { + stationSettingVm.addConditionDataToLevelRouteSave(levelRouteSave) + } + + private fun collectData() { + levelRouteSave = LevelRouteSave() + levelRouteSave.temperature = mBinding.ilTemperature.editText.text.toString().trim() + levelRouteSave.weather = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerWeather) + levelRouteSave.imaging = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerImaging) + levelRouteSave.sunDirection = + LevelStationSettingUtil.getSpinnerText(mBinding.spinnerSunDirection) + levelRouteSave.windDirection = + LevelStationSettingUtil.getSpinnerText(mBinding.spinnerWindDirection) + levelRouteSave.windSpeed = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerWindSpeed) + levelRouteSave.roads = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerRoads) + levelRouteSave.soil = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerSoil) + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + + private fun setData(levelRouteSave: LevelRouteSave) { + setTemperatureData(levelRouteSave.temperature) + + mBinding.spinnerWeather.setSelection( + LevelStationSettingContant.weatherList.indexOf( + levelRouteSave.weather + ) + ) + mBinding.spinnerImaging.setSelection( + LevelStationSettingContant.imagingList.indexOf( + levelRouteSave.imaging + ) + ) + mBinding.spinnerSunDirection.setSelection( + LevelStationSettingContant.sunDirectionList.indexOf( + levelRouteSave.sunDirection + ) + ) + mBinding.spinnerWindDirection.setSelection( + LevelStationSettingContant.windDirectionList.indexOf( + levelRouteSave.windDirection + ) + ) + mBinding.spinnerWindSpeed.setSelection( + LevelStationSettingContant.windSpeedList.indexOf( + levelRouteSave.windSpeed + ) + ) + mBinding.spinnerRoads.setSelection( + LevelStationSettingContant.roadsList.indexOf( + levelRouteSave.roads + ) + ) + mBinding.spinnerSoil.setSelection(LevelStationSettingContant.soilList.indexOf(levelRouteSave.soil)) + } + + private fun setTemperatureData(value: String?) { + mBinding.ilTemperature.editText.setText(value) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingInformationFragment.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingInformationFragment.kt new file mode 100644 index 0000000..cbbb4d5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingInformationFragment.kt @@ -0,0 +1,201 @@ +package com.bingce.controlnetwork.func.level.fragment + +import android.text.TextUtils +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.TextView +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.constant.LevelStationSettingContant +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil +import com.bingce.controlnetwork.func.level.viewmodel.LevelStationSettingVm +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentLevelStationSettingInformationBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.newui.stationsetting.IStationSettingOperate +import com.bingce.controlnetwork.widget.editspinner.EditSpinner +import com.bingce.controlnetwork.widget.editspinner.SimpleAdapter + +/** + * 水准测站设置-观测信息 + */ +class LevelStationSettingInformationFragment : + BaseFragmentBinding(), IStationSettingOperate { + + private val viewModel by activityViewModels() + + private lateinit var levelRouteSave: LevelRouteSave + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentLevelStationSettingInformationBinding { + return FragmentLevelStationSettingInformationBinding.inflate(inflater, container, false) + } + + override fun initView() { + initEditTextTitle() + initSpinnerRulerType() + initRulerReceptType() + viewModel.initHasTwoRuler { hasTwoRuler -> + if (hasTwoRuler) { + mBinding.ilFirstStationBackFootNumber.tvTitle.setText(R.string.first_station_back_foot_number_l) + mBinding.ilFirstStationFrontFootNumber.tvTitle.setText(R.string.first_station_front_foot_number_l) + mBinding.llRuler2.visibility = View.VISIBLE + } else { + mBinding.llRuler2.visibility = View.GONE + } + } + } + + /** + * 初始化editText坐标的title + */ + private fun initEditTextTitle() { + mBinding.ilWatcher.tvTitle.text = "观测者" + mBinding.ilRecorder.tvTitle.text = "记录者" + mBinding.ilExaminer.tvTitle.text = "检查者" + mBinding.ilFirstStationBackFootNumber.tvTitle.text = + Tools.getString(R.string.first_station_back_foot_number) + mBinding.ilFirstStationFrontFootNumber.tvTitle.text = + Tools.getString(R.string.first_station_front_foot_number) + mBinding.ilFirstStationBackFootNumber2.tvTitle.text = + Tools.getString(R.string.first_station_back_foot_number_r) + mBinding.ilFirstStationFrontFootNumber2.tvTitle.text = + Tools.getString(R.string.first_station_front_foot_number_r) + mBinding.ilInstrumentModel.tvTitle.text = "仪器型号" + mBinding.ilDeviceNumber.tvTitle.text = "仪器编号" + mBinding.ilSteelRuleParam.tvTitle.text = "标尺因瓦带膨胀系数" + mBinding.ilRulerCorrectionFactor.tvTitle.text = "标尺改正系数(mm/m)" + mBinding.ilRulerLengthProvingTemperature.tvTitle.text = "标尺长度检定温度(℃)" + } + + private fun initRulerReceptType() { + initEditSpinner( + mBinding.ilEditSpinnerRulerRecept.tvName, + "尺承类型", + mBinding.ilEditSpinnerRulerRecept.etSpinner, + "请输入或选择" + ) + val adapter = + SimpleAdapter(requireContext(), LevelStationSettingContant.rulerReceptTypeList) + mBinding.ilEditSpinnerRulerRecept.etSpinner.setAdapter(adapter) + } + + private fun initSpinnerRulerType() { + mBinding.spinnerRulerType.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.rulerTypeList + ) + } + + override fun initData() { + viewModel.editLastDataLiveData.observe(viewLifecycleOwner) { + if (it == null) { + setRulerReceptTypeData("不足5kg尺台") + } else { + setData(it) + } + } + } + + override fun checkSaveNot(): Boolean { + collectData() + if (isEmpty(levelRouteSave.frontFootNumber)) { + ToastUtils.showShort(R.string.first_station_front_foot_number_hint) + return true + } + if (isEmpty(levelRouteSave.backFootNumber)) { + ToastUtils.showShort(R.string.first_station_back_foot_number_hint) + return true + } + + if (mBinding.llRuler2.visibility == View.VISIBLE) { + if (isEmpty(levelRouteSave.frontFootNumber2)) { + ToastUtils.showShort(R.string.first_station_front_foot_number_hint) + return true + } + if (isEmpty(levelRouteSave.backFootNumber2)) { + ToastUtils.showShort(R.string.first_station_back_foot_number_hint) + return true + } + } + + return false + } + + override fun setDataToStation() { + viewModel.addInforDataToLevelRouteSave(levelRouteSave) + } + + private fun collectData() { + levelRouteSave = LevelRouteSave() + levelRouteSave.watcher = mBinding.ilWatcher.editText.text.toString().trim() + levelRouteSave.recorder = mBinding.ilRecorder.editText.text.toString().trim() + levelRouteSave.examiner = mBinding.ilExaminer.editText.text.toString().trim() + levelRouteSave.frontFootNumber = + mBinding.ilFirstStationFrontFootNumber.editText.text.toString().trim() + levelRouteSave.backFootNumber = + mBinding.ilFirstStationBackFootNumber.editText.text.toString().trim() + if (mBinding.llRuler2.visibility == View.VISIBLE) { + levelRouteSave.frontFootNumber2 = + mBinding.ilFirstStationFrontFootNumber2.editText.text.toString().trim() + levelRouteSave.backFootNumber2 = + mBinding.ilFirstStationBackFootNumber2.editText.text.toString().trim() + } + levelRouteSave.instrumentModel = mBinding.ilInstrumentModel.editText.text.toString().trim() + levelRouteSave.deviceNumber = mBinding.ilDeviceNumber.editText.text.toString().trim() + levelRouteSave.steelRuleParam = mBinding.ilSteelRuleParam.editText.text.toString().trim() + levelRouteSave.rulerCorrectionFactor = + mBinding.ilRulerCorrectionFactor.editText.text.toString().trim() + levelRouteSave.rulerLengthProvingTemperature = + mBinding.ilRulerLengthProvingTemperature.editText.text.toString().trim() + levelRouteSave.rulerType = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerRulerType) + levelRouteSave.rulerReceptType = mBinding.ilEditSpinnerRulerRecept.etSpinner.text.trim() + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + + private fun setData(levelRouteSave: LevelRouteSave) { + mBinding.ilWatcher.editText.setText(levelRouteSave.watcher) + mBinding.ilRecorder.editText.setText(levelRouteSave.recorder) + mBinding.ilExaminer.editText.setText(levelRouteSave.examiner) + mBinding.ilFirstStationBackFootNumber.editText.setText(levelRouteSave.backFootNumber) + mBinding.ilFirstStationFrontFootNumber.editText.setText(levelRouteSave.frontFootNumber) + mBinding.ilFirstStationBackFootNumber2.editText.setText(levelRouteSave.backFootNumber2) + mBinding.ilFirstStationFrontFootNumber2.editText.setText(levelRouteSave.frontFootNumber2) + mBinding.ilInstrumentModel.editText.setText(levelRouteSave.instrumentModel) + mBinding.ilDeviceNumber.editText.setText(levelRouteSave.deviceNumber) + mBinding.ilSteelRuleParam.editText.setText(levelRouteSave.steelRuleParam) + mBinding.ilRulerCorrectionFactor.editText.setText(levelRouteSave.rulerCorrectionFactor) + mBinding.ilRulerLengthProvingTemperature.editText.setText(levelRouteSave.rulerLengthProvingTemperature) + + mBinding.spinnerRulerType.setSelection( + LevelStationSettingContant.rulerTypeList.indexOf( + levelRouteSave.rulerType + ) + ) + setRulerReceptTypeData(levelRouteSave.rulerReceptType) + } + + private fun setRulerReceptTypeData(value: String?) { + mBinding.ilEditSpinnerRulerRecept.etSpinner.text = value + } + + private fun initEditSpinner( + textView: TextView, + textViewName: String, + view: EditSpinner, + textHint: String + ) { + textView.text = textViewName + view.setHint(textHint) + view.setEtGravity(Gravity.CENTER_VERTICAL or Gravity.END) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyFragment.java new file mode 100644 index 0000000..f50967c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyFragment.java @@ -0,0 +1,497 @@ +package com.bingce.controlnetwork.func.level.fragment; + + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.lifecycle.ViewModelProvider; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord; +import com.bingce.controlapphelper.leveling.detaction.ILevelRefreshBtn; +import com.bingce.controlapphelper.leveling.detaction.INextStation; +import com.bingce.controlapphelper.leveling.detaction.LevelCheckBtnUtil; +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.databinding.FragmentLevelSurveyorBinding; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.func.level.activity.LevelStationSettingActivity; +import com.bingce.controlnetwork.func.level.viewmodel.LevelSuveyorVm; +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding; +import com.bingce.controlnetwork.util.DialogUtil; +import com.bingce.controlnetwork.util.StationSettingCheckUtil; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; +import com.bingce.controlnetwork.func.level.sendreceive.ILevelBackData; +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequest; +import cn.liuyanbing.surveyor.function.level.sendreceive.LevelRequestRelease; +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequestTest; + +/** + * 水准测量页 + */ +public class LevelSurveyFragment extends BaseFragmentBinding { + public static final String TAG = LevelSurveyFragment.class.getName(); + + public static final String KEY_STATION_INDEX = "STATION_INDEX"; + private LevelSuveyorVm viewModel; + private List fragments; + private MenuItem rollBackBtn; + private MenuItem reMeasureStationBtn; + + private StationSettingCheckUtil stationSettingCheckUtil; + + private final INextStation nextStationI = this::showSelectLevelNextStepDialog; + + private LevelRequest levelRequest; + private final ILevelBackData levelBackData = new ILevelBackData() { + @Override + public void receive(@NonNull LevelReceiveData data) { + receiveData(data); + } + + @Override + public void measureError(@NonNull String msg) { + if (getView() == null) { + return; + } + DialogUtil.showAlertDialog(requireContext(), getChildFragmentManager(), getViewLifecycleOwner(), msg); + } + }; + + private MyPagerAdapter myPagerAdapter; + + private void receiveData(LevelReceiveData data) { + if (getView() == null) { + return; + } + LevelSurveySubFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.recieveData(data); + } + } + + private final ILevelRefreshBtn levelRefreshBtnI = new ILevelRefreshBtn() { + @Override + public void refreshMeasureBtn() { + boolean measureEnable = LevelCheckBtnUtil.getMeasureEnable(viewModel.getCurrentStationId()); + ThreadPoolUtil.executeInMain(() -> { + setViewEnable(mBinding.surveyor, measureEnable); + setViewEnable(mBinding.btnInput, measureEnable); + }); + } + + @Override + public void refreshNextStationBtn() { + boolean measureEnable = LevelCheckBtnUtil.getNextStationEnable(viewModel.getCurrentStationId()); + ThreadPoolUtil.executeInMain(() -> setViewEnable(mBinding.btnNextStation, measureEnable)); + } + + @Override + public void refreshRollBackBtn() { + doRefreshRollBackBtn(); + } + + @Override + public void refreshReMeasureBtn() { + doRefreshReMeasureBtn(); + } + }; + + private void doRefreshReMeasureBtn() { + if (reMeasureStationBtn != null) { + boolean measureEnable = LevelCheckBtnUtil.getReMeasureStationEnable(viewModel.getCurrentStationId()); + ThreadPoolUtil.executeInMain(() -> reMeasureStationBtn.setEnabled(measureEnable)); + } + } + + private void doRefreshRollBackBtn() { + if (rollBackBtn != null) { + boolean measureEnable = LevelCheckBtnUtil.getRollBackEnable(viewModel.getCurrentStationId()); + ThreadPoolUtil.executeInMain(() -> rollBackBtn.setEnabled(measureEnable)); + } + } + + public static void start(Context context, String projectId, String routeId, String routeName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_ROUTE_ID, routeId); + bundle.putString(BundleConstants.KEY_ROUTE_NAME, routeName); + FragmentContainerActivity.start(context, TAG, "水准测量", bundle); + } + + public static Fragment newInstance(Bundle args) { + Fragment fragment = new LevelSurveyFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + protected FragmentLevelSurveyorBinding getViewBinding(@NonNull LayoutInflater inflater, ViewGroup container) { + return FragmentLevelSurveyorBinding.inflate(inflater, container, false); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.menu_level_survey, menu); + rollBackBtn = menu.findItem(R.id.rollBack); + reMeasureStationBtn = menu.findItem(R.id.reMeasureStation); + doRefreshRollBackBtn(); + doRefreshReMeasureBtn(); + } + + @Override + public void onPrepareOptionsMenu(@NonNull Menu menu) { + if (Test.DEBUG) { + menu.findItem(R.id.test).setVisible(true); + } + super.onPrepareOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (R.id.rollBack == item.getItemId()) { + showConfirmDialog(getString(R.string.level_roll_back_hint), () -> { + LevelSurveySubFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.startRollBack(); + } + }); + } else if (R.id.reMeasureStation == item.getItemId()) { + showConfirmDialog(getString(R.string.level_remeasure_station_hint), () -> { + LevelSurveySubFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.reMeasureStation(); + } + }); + } else if (R.id.surveyorSettings == item.getItemId()) { + LevelingStationRecord currentStation = viewModel.getCurrentStation(); + if (currentStation != null) { + LevelStationSettingActivity.start(requireContext(), getRouteId(), currentStation.getId(), false); + } + } else if (R.id.levelRouteResult == item.getItemId()) { + viewModel.calLevelRouteResult(result -> { + DialogUtil.showAlertDialog(requireContext(), getChildFragmentManager(), getViewLifecycleOwner(), result); + return null; + }); + } else if (R.id.receiveDataType == item.getItemId()) { + LevelInputAllowFragment.show(getChildFragmentManager(), getViewLifecycleOwner(), + mBinding.surveyor.getVisibility() == View.VISIBLE,//是否仪器获取数据 + auto -> { + viewModel.setGetDataAuto(getRouteId(), auto); + refreshManuleAutoInput(auto); + }); + } else if (R.id.test == item.getItemId()) { + TestDataSelectLevelFragment.show(getChildFragmentManager(), position -> { + LevelRequestTest levelReceiveData1 = (LevelRequestTest) levelRequest; + levelReceiveData1.initTestData(position); + }); + } else if (R.id.rollBackStation == item.getItemId()) { + startRollBackStation(); + } + return super.onOptionsItemSelected(item); + } + + private void startRollBackStation() { + if (!viewModel.getMeasureStationList().isEmpty()) { + String lastStationId = viewModel.getMeasureStationList().get(0).lastStationId; + if (TextUtils.isEmpty(lastStationId)) { + ToastUtils.showShort("没有上一站了"); + return; + } + showConfirmDialog("是否要回退至上一站,该操作将清空当前站所有数据", () -> { + viewModel.rollBackStation(); + }); + } + } + + + @Override + public void onDestroyView() { + super.onDestroyView(); +// EventBus.getDefault().unregister(this); + levelRequest.onDestroy(); + LevelCheckBtnUtil.destroy(); + } + + @Override + protected void initView() { + setHasOptionsMenu(true); + initLevelRequest(); + stationSettingCheckUtil = new StationSettingCheckUtil(); + viewModel = new ViewModelProvider(this).get(LevelSuveyorVm.class); + + viewModel.initData(levelRefreshBtnI, () -> { + initViewPager(); + return null; + }, integer -> { + mBinding.vp.setCurrentItem(integer); + return null; + }, nextStationI); + + viewModel.getGetDadaAuto(getRouteId(), auto -> { + refreshManuleAutoInput(auto); + return null; + }); + + initTitle(); + + initListener(); + } + + private void initLevelRequest() { + if (Test.DEBUG) { + levelRequest = new LevelRequestTest(levelBackData); + } else { + levelRequest = new LevelRequestRelease(levelBackData); + } + levelRequest.onStart(); + } + + private void initTitle() { + mBinding.tvRouteName.setText("测段:" + getRouteName()); + } + + @Override + protected void initData() { + viewModel.initDataStationList(getProjectId(), getRouteId()); + + viewModel.checkSunTime(getProjectId(), hint -> { + if (!TextUtils.isEmpty(hint)) { + DialogUtil.showAlertDialog(requireContext(), getChildFragmentManager(), getViewLifecycleOwner(), hint); + } + return null; + }); + } + + private void initListener() { + mBinding.surveyor.setOnClickListener(v -> { + stationSettingCheckUtil.checkStationSettingsLevel(viewModel.getCurrentStationId(), getChildFragmentManager(), this, + requireContext(), + this, + () -> levelRequest.requeset()); + }); + + mBinding.btnNextStation.setOnClickListener(v -> { + stationSettingCheckUtil.checkStationSettingsLevel(viewModel.getCurrentStationId(), getChildFragmentManager(), this, + requireContext(), + this, + () -> { + LevelSurveySubFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.nextStation(); + } + }); + }); + + mBinding.btnInput.setOnClickListener(v -> { + stationSettingCheckUtil.checkStationSettingsLevel(viewModel.getCurrentStationId(), getChildFragmentManager(), this, + requireContext(), + this, + () -> { + runOnUI(() -> { + LevelInputFragment.show(getChildFragmentManager(), getViewLifecycleOwner(), + (distance, height) -> receiveData(new LevelReceiveData(height, distance))); + + }); + }); + }); + + } + + private String getProjectId() { + return getArgumentString(BundleConstants.KEY_PROJECT_ID); + } + + private String getRouteId() { + return getArgumentString(BundleConstants.KEY_ROUTE_ID); + } + + private String getRouteName() { + return getArgumentString(BundleConstants.KEY_ROUTE_NAME); + } + + private void initViewPager() { + fragments = new ArrayList<>(); + for (int i = 0; i < viewModel.getMeasureStationList().size(); i++) { + fragments.add(LevelSurveySubFragment.newInstance(i)); + } + + if (myPagerAdapter == null) { + mBinding.vp.setOffscreenPageLimit(3); + myPagerAdapter = new MyPagerAdapter(getChildFragmentManager()); + mBinding.vp.setAdapter(myPagerAdapter); + mBinding.tabLayout.setViewPager(mBinding.vp); + + mBinding.vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + viewModel.setCurrentFragmentPos(position); + viewModel.switchRefreshBtnEnable(); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + } else { + myPagerAdapter.notifyDataSetChanged(); + mBinding.tabLayout.notifyDataSetChanged(); + mBinding.tabLayout.setCurrentTab(0); + } + } + + private LevelSurveySubFragment getCurrentFragment() { + int currentFragmentPos = viewModel.getCurrentFragmentPos(); + if (fragments != null && fragments.size() > currentFragmentPos) { + return fragments.get(currentFragmentPos); + } + return null; + } + + private void setViewEnable(View view, boolean measureEnable) { + view.setEnabled(measureEnable); + if (measureEnable) { + view.setAlpha(1); + } else { + view.setAlpha(.4f); + } + } + + private class MyPagerAdapter extends FragmentStatePagerAdapter { + public MyPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public int getCount() { + return fragments.size(); + } + + @Override + public CharSequence getPageTitle(int position) { + return viewModel.getMeasureStationList().get(position).stationName; + } + + @Override + public Fragment getItem(int position) { + return fragments.get(position); + } + + @Override + public int getItemPosition(@NonNull Object object) { + return PagerAdapter.POSITION_NONE; + } + } + + + private void showConfirmDialog(String content, TipsFragment.IConfirmCallback callback) { + TipsFragment.cancelAbleTips(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + content, -1, callback); + } + + /** + * 下一站的弹框 + */ + private void showSelectLevelNextStepDialog(LevelingStationRecord station) { + runOnUI(() -> SelectLevelNextStationTypeFragment.select(getChildFragmentManager(), getViewLifecycleOwner(), type -> { + switch (type) { + case SelectLevelNextStationTypeFragment.TYPE_CONTINUE_OBSERVE: + //继续观测 + startMeasureNextStation(station); + break; + case SelectLevelNextStationTypeFragment.TYPE_INTERMITTENT: + viewModel.intermittent(station); + break; + case SelectLevelNextStationTypeFragment.TYPE_END_STATION: + checkEndStation(station); + break; + } + })); + } + + /** + * 点击结束测站时验证 + * + * @param station + */ + private void checkEndStation(LevelingStationRecord station) { + ThreadPoolUtil.execute(() -> { + //增加确认结束测站的提醒 + if (station.isOddStation()) { + //当前是奇数站 + ToastUtils.showShort("结束测站必须是偶数站!"); + return; + } + //是否设置过结束测站的测站设置 + boolean isSetEndStationSetting = viewModel.isHaveSetEndStationSetting(station.getId()); + if (!isSetEndStationSetting) { + runOnUI(() -> StationSettingCheckUtil.showLevelSetStationSetting(getChildFragmentManager(), + getViewLifecycleOwner(), getContext(), StationSettingCheckUtil.HINT_LEVEL_END, + getRouteId(), station.getId(), true)); + return; + } + runOnUI(() -> showConfirmEndRouteStartEndStation(station)); + }); + + } + + /** + * 下一站继续观测 + */ + public void startMeasureNextStation(LevelingStationRecord station) { + viewModel.contineObserve(station); + } + + /** + * 结束路线开始下一站的确认提醒 + * + * @param station + */ + private void showConfirmEndRouteStartEndStation(LevelingStationRecord station) { + DialogUtil.showConfirmDialog(getChildFragmentManager(), getViewLifecycleOwner(), Tools.getString(R.string.level_end_route_hint), Tools.getString(R.string.confirm), new DialogUtil.IConfirmBack() { + @Override + public void onConfirm() { + viewModel.endStation(station); + } + }); + } + + private void refreshManuleAutoInput(boolean receiveDataTypeAuto) { + if (receiveDataTypeAuto) { + mBinding.surveyor.setVisibility(View.VISIBLE); + mBinding.btnInput.setVisibility(View.GONE); + } else { + mBinding.btnInput.setVisibility(View.VISIBLE); + mBinding.surveyor.setVisibility(View.GONE); + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveySubFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveySubFragment.java new file mode 100644 index 0000000..fd65769 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveySubFragment.java @@ -0,0 +1,380 @@ +package com.bingce.controlnetwork.func.level.fragment; + + +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_IGNORE; +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_REMEASURE_POINT; +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_REMEASURE_STATION; + +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory; +import com.bingce.controlapphelper.datasource.database.leveling.measure.backfront.LevelingMeasureBackFrontRecord; +import com.bingce.controlapphelper.datasource.database.leveling.measure.station.LevelingMeasureStationRecord; +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord; +import com.bingce.controlapphelper.leveling.detaction.IDetectionHint; +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData; +import com.bingce.controlapphelper.leveling.detaction.LevelSpeakMsg; +import com.bingce.controlapphelper.leveling.detaction.surveyorcache.SurveyorCacheData; +import com.bingce.controlapphelper.model.LevelToleranceNotice; +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.FragmentLevelSurveyorSubBinding; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.func.level.dialog.LevelToleranceTipsFragment; +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding; + +import java.util.ArrayList; +import java.util.List; +import com.bingce.controlnetwork.func.level.viewmodel.LevelSuveyorSubVm; +import com.bingce.controlnetwork.func.level.viewmodel.LevelSuveyorVm; +import com.bingce.controlnetwork.util.DialogUtil; + +/** + * 水准测量页 + */ +public class LevelSurveySubFragment extends BaseFragmentBinding { + public static final String TAG = LevelSurveySubFragment.class.getName(); + private LevelSuveyorSubVm viewModel; + private LevelSuveyorVm stationListVm; + + + private final ActivityResultLauncher defaultStationLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { +// if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { +// return; +// } +// //只有前视才允许选点 +// String pointId = pickPointResult.getSelectedIds().get(0); +// viewModel.saveMeasureFrontPointId(pointId, () -> { +// setFrontPointNameUi(pickPointResult.getSelectedNames().get(0)); +// return null; +// }); + }); + +// private void setFrontPointNameUi(String name) { +// mBinding.ilPoint.tvPoint.setText(name); +// } + + public static LevelSurveySubFragment newInstance(int stationIndex) { + Bundle args = new Bundle(); + args.putInt(LevelSurveyFragment.KEY_STATION_INDEX, stationIndex); + LevelSurveySubFragment fragment = new LevelSurveySubFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + protected FragmentLevelSurveyorSubBinding getViewBinding(@NonNull LayoutInflater inflater, ViewGroup container) { + return FragmentLevelSurveyorSubBinding.inflate(inflater, container, false); + } + + @Override + protected void initView() { + viewModel = new ViewModelProvider(this).get(LevelSuveyorSubVm.class); + stationListVm = new ViewModelProvider(requireParentFragment()).get(LevelSuveyorVm.class); + + mBinding.ilSightDistanceDiffCurrent.tvTitle.setText("视距差:"); + mBinding.ilDistanceTotal.tvTitle.setText("总距离:"); + mBinding.ilSightDistanceDiffTotal.tvTitle.setText("累积视距差:"); + mBinding.ilHeightDiffTotal.tvTitle.setText("总高差:"); + mBinding.ilZ.tvTitle.setText("高程:"); + initListener(); + initObserver(); + } + + private void initObserver() { + viewModel.getStationLiveData().observe(this, stationRecord -> { + boolean measureBack = LevelingMeasureOrderUtil.INSTANCE.isMeasureBack(stationRecord); + + String backFrontType = measureBack ? getString(R.string.rearview) : getString(R.string.forward_view); + mBinding.tvBackFrontType.setText(backFrontType); + + //除了结束测站的第一个前视点可以选择测点 +// setSelectPointShowHide(stationRecord); + + setMeasureOrderAndCurrent(stationRecord); + + setSurveyorCacheUiVisiable(stationRecord); + +// viewModel.getMeasurePointName(stationRecord, pointName -> { +// setFrontPointNameUi(pointName); +// return null; +// }); + + }); + + viewModel.getSurveyorCacheDataLiveData().observe(this, this::setSurveyorCacheUi); + + viewModel.getMeasureStationLiveData().observe(this, this::setMeasureStationUi); + + //监听路线的最后一次设置更新尺子编号 + if (stationListVm.getRouteId() != null) { + LevelingDbFactory.instance.getStationSettingDataSource().getLatestLiveData(stationListVm.getRouteId()) + .observe(getViewLifecycleOwner(), levelingStationSettingRecord -> { + if (levelingStationSettingRecord != null) { + int stationIndex = getStationIndex(); + if (stationIndex == 0) { + mBinding.tvRulerNumBack.setText(getRulerNumShow(levelingStationSettingRecord.firstStationBackFootNumber)); + mBinding.tvRulerNumFront.setText(getRulerNumShow(levelingStationSettingRecord.firstStationFrontFootNumber)); + } else { + mBinding.tvRulerNumBack.setText(getRulerNumShow(levelingStationSettingRecord.firstStationBackFootNumber2)); + mBinding.tvRulerNumFront.setText(getRulerNumShow(levelingStationSettingRecord.firstStationFrontFootNumber2)); + } + } + }); + } + + } + + private String getRulerNumShow(String rulerNum) { + if (rulerNum==null) { + rulerNum = ""; + } + return "No." + rulerNum; + } + + private void setSelectPointShowHide(LevelingStationRecord stationRecord) { + viewModel.isEndStation(stationRecord, endStation -> { + //非单程双侧,前视,非终点站可以选择测点 + boolean measureFirstFront = LevelingMeasureOrderUtil.INSTANCE.isMeasureFirstFront(stationRecord); + boolean canSelectPoint = measureFirstFront && getStationIndex() == 0 && !endStation; +// mBinding.ilPoint.ivSelectPoint.setVisibility(canSelectPoint ? View.VISIBLE : View.INVISIBLE); +// mBinding.ilPoint.tvPoint.setClickable(canSelectPoint); + return null; + }); + } + + private void setSurveyorCacheUiVisiable(LevelingStationRecord stationRecord) { + boolean showTwiceRead = LevelingMeasureOrderUtil.INSTANCE.isShowTwiceRead(stationRecord); + if (showTwiceRead) { + mBinding.ilB2.getRoot().setVisibility(View.VISIBLE); + mBinding.ilF2.getRoot().setVisibility(View.VISIBLE); + } else { + mBinding.ilB2.getRoot().setVisibility(View.GONE); + mBinding.ilF2.getRoot().setVisibility(View.GONE); + } + + viewModel.setMeasureTextColor(stationRecord, mBinding.ilB1, mBinding.ilB2, mBinding.ilF1, mBinding.ilF2); + } + + private void setMeasureOrderAndCurrent(LevelingStationRecord stationRecord) { +// String textByLevelingMeasureOrder = LevelingMeasureOrderUtil.INSTANCE.getTextByLevelingMeasureOrder(stationRecord.levelingMeasureOrder); +// mBinding.tvOrderType.setText(textByLevelingMeasureOrder); + + CharSequence[] currentOrderArray = viewModel.getCurrentOrderArray(stationRecord); + mBinding.tvCurrentOrderOdd.setText(currentOrderArray[0]); + mBinding.tvCurrentOrderEven.setText(currentOrderArray[1]); + } + + private void setSurveyorCacheUi(SurveyorCacheData surveyorCacheData) { + LevelingMeasureBackFrontRecord b1Data = surveyorCacheData.getB1Data(); + LevelingMeasureBackFrontRecord b2Data = surveyorCacheData.getB2Data(); + LevelingMeasureBackFrontRecord f1Data = surveyorCacheData.getF1Data(); + LevelingMeasureBackFrontRecord f2Data = surveyorCacheData.getF2Data(); + + setSurveyorPointData(mBinding.ilB1.tvDisTance, mBinding.ilB1.tvHeight, b1Data); + setSurveyorPointData(mBinding.ilB2.tvDisTance, mBinding.ilB2.tvHeight, b2Data); + setSurveyorPointData(mBinding.ilF1.tvDisTance, mBinding.ilF1.tvHeight, f1Data); + setSurveyorPointData(mBinding.ilF2.tvDisTance, mBinding.ilF2.tvHeight, f2Data); + + //更新视距差 + String currentFrontBackDistancceDiff = surveyorCacheData.getCurrentFrontBackDistancceDiff(); + mBinding.ilSightDistanceDiffCurrent.tvValue.setText(currentFrontBackDistancceDiff); + } + + private void setSurveyorPointData(TextView tvDisTance, TextView tvHeight, LevelingMeasureBackFrontRecord data) { + if (data == null) { + tvDisTance.setText(""); + tvHeight.setText(""); + } else { + tvDisTance.setText(data.getMeasureDistanceShow()); + tvHeight.setText(data.getMeasureHeightShow()); + } + } + + private void setMeasureStationUi(LevelingMeasureStationRecord record) { + if (record == null) { + mBinding.ilDistanceTotal.tvValue.setText(""); + mBinding.ilSightDistanceDiffTotal.tvValue.setText(""); + mBinding.ilHeightDiffTotal.tvValue.setText(""); + mBinding.ilZ.tvValue.setText(""); + return; + } + + viewModel.getZ(z -> { + mBinding.ilZ.tvValue.setText(record.getZShow(z)); + return null; + }); + + mBinding.ilDistanceTotal.tvValue.setText(record.getDistanceTotalShow()); + mBinding.ilSightDistanceDiffTotal.tvValue.setText(record.getCumulativeVisualDistanceDiffShow()); + mBinding.ilHeightDiffTotal.tvValue.setText(record.getHeightDiffTotalShow()); + } + + @Override + protected void initData() { + String currentStationId = getCurrentStationId(); + if (currentStationId != null) { + viewModel.initData(currentStationId, new IDetectionHint() { + + @Override + public void noticeHint(@NonNull LevelToleranceNotice notice) { + LevelToleranceTipsFragment.tips(getChildFragmentManager(), getViewLifecycleOwner(), + notice.getTitle(), notice.getContent(), new LevelToleranceTipsFragment.IOperatorCallback() { + @Override + public void onReMeasureStation() { + notice.getNoticeBack().levelContinue(VALUE_REMEASURE_STATION, notice.getIgnoreToleranceList()); + } + + @Override + public void onReMeasurePoint() { + notice.getNoticeBack().levelContinue(VALUE_REMEASURE_POINT, notice.getIgnoreToleranceList()); + } + + @Override + public void onIgnore() { + notice.getNoticeBack().levelContinue(VALUE_IGNORE, notice.getIgnoreToleranceList()); + } + }); + } + + @Override + public void stationCheckFinish(@NonNull LevelingStationRecord stationRecord) { + if (stationRecord.endStation) { + LevelSpeakMsg.speakStationFinish("该测段已观测完毕"); + stationListVm.calLevelRouteResult(result -> { + DialogUtil.showAlertDialog(requireContext(), getChildFragmentManager(), getViewLifecycleOwner(), + "该测段已观测完毕\n" + result); + return null; + }); + } else { + boolean simStation = stationRecord.isSimStation(); + if (simStation && !stationRecord.twiceStation) { + String hint = "请观测单程双转第二测站"; + LevelSpeakMsg.speakStationFinish(hint); + //单程双转的第一个测站提示 + TipsFragment.cancelAbleTips(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + hint, -1, + () -> switchTwiceStation(stationRecord)); + } else { + String hint = getString(R.string.level_check_finish_next_station_hint); + LevelSpeakMsg.speakStationFinish(hint); + + TipsFragment.tipsOnly(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + hint); + } + } + } + }, stationListVm.getNextStationI()); + } + } + + private String getCurrentStationId() { + int stationIndex = getStationIndex(); + List measureStationList = stationListVm.getMeasureStationList(); + if (stationIndex >= 0 && measureStationList.size() > stationIndex) { + return measureStationList.get(stationIndex).getId(); + } + return null; + } + + /** + * 开始切换到第二测站(第二个tab) + */ + private void switchTwiceStation(LevelingStationRecord record) { + LevelSurveyFragment parentFragment = (LevelSurveyFragment) getParentFragment(); + if (parentFragment != null) { + parentFragment.startMeasureNextStation(record); + } + } + + /** + * 去创建测段 + */ + private void goCreateRoute() { + String projectId = viewModel.getProjectId(); + if (projectId != null) { + LevelRouteCreateEditFragment.start(requireContext(), projectId, null, getString(R.string.create_segment_survey)); + requireActivity().finish(); + } + } + + private void initListener() { +// mBinding.ilPoint.tvPoint.setOnClickListener((v) -> { +// StringInputFragment.input(getChildFragmentManager(), "新建点", getViewLifecycleOwner(), string -> { +// if (TextUtils.isEmpty(string)) return; +// viewModel.saveMeasureFrontPoint(PointRecordTj.createHidePoint(string), () -> { +// setFrontPointNameUi(string); +// return null; +// }); +// }); +// }); +// +// mBinding.ilPoint.ivSelectPoint.setOnClickListener((v) -> { +// if (viewModel.getProjectId() == null) return; +// PickPointResult alreadyResult = getAlreadySelectFrontPoint(); +// PickPointFragment.pickKnownAndUnknownPoint(getChildFragmentManager(), +// getViewLifecycleOwner(), +// getContext(), +// "", +// 1, +// getString(R.string.select_surveyor_point), +// null, +// viewModel.getProjectId(), alreadyResult, defaultStationLauncher); +// }); + + } + + @Nullable + private PickPointResult getAlreadySelectFrontPoint() { + PickPointResult alreadyResult = null; + LevelingStationRecord station = viewModel.getStationLiveData().getValue(); + String measurePointId = null; + if (station != null) { + measurePointId = LevelingMeasureOrderUtil.INSTANCE.getMeasurePointId(station); + } + if (measurePointId != null) { + alreadyResult = new PickPointResult(); + List ids = new ArrayList<>(); + List names = new ArrayList<>(); + ids.add(measurePointId); + alreadyResult.setSelectedIds(ids); + alreadyResult.setSelectedNames(names); + } + return alreadyResult; + } + + public void startRollBack() { + viewModel.startRollBack(); + } + + public void reMeasureStation() { + viewModel.reMeasureStation(); + } + + public void recieveData(LevelReceiveData data) { + if (viewModel != null) { + viewModel.recieveData(data); + } + } + + public void nextStation() { + viewModel.nextStation(); + } + + private int getStationIndex() { + return requireArguments().getInt(LevelSurveyFragment.KEY_STATION_INDEX); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyorHomeFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyorHomeFragment.java new file mode 100644 index 0000000..c92082c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyorHomeFragment.java @@ -0,0 +1,107 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory; +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.databinding.FragmentLevelSurveyorHomeBinding; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.func.level.adapter.LevelRouteListAdapter; + +import blankj.utilcode.util.ToastUtils; + + +/** + * 水准测量首页 + */ +public class LevelSurveyorHomeFragment extends BaseFragment { + public static final String TAG = LevelSurveyorHomeFragment.class.getName(); + private LevelRouteListAdapter adapter; + private FragmentLevelSurveyorHomeBinding mBinding; + + private static final String KEY_DETAIL_OR_SURVEYOR = "___editable___";//标识点击item进入测量界面还是测站详情 + + public static LevelSurveyorHomeFragment newInstance(String projectId, String routeId) { + return newInstance(projectId, routeId, true); + } + + public static LevelSurveyorHomeFragment newInstance(String projectId, String routeId, boolean detailOrSurveyor) { + LevelSurveyorHomeFragment fragment = new LevelSurveyorHomeFragment(); + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_ROUTE_ID, routeId); + bundle.putBoolean(KEY_DETAIL_OR_SURVEYOR, detailOrSurveyor); + fragment.setArguments(bundle); + return fragment; + } + + /** + * 去测量 + */ + private void goMeasurePage(LevelRouteRecord item) { + String projectId = item.getProjectId(); + if (projectId == null) { + ToastUtils.showShort("项目id异常"); + return; + } + LevelSurveyFragment.start(getContext(), projectId, item.getId(), item.getRouteName()); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = FragmentLevelSurveyorHomeBinding.inflate(inflater, container, false); + return mBinding.getRoot(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initView(); + initData(); + } + + private void initView() { + adapter = new LevelRouteListAdapter(requireContext()); + mBinding.recyclerView.setAdapter(adapter); + adapter.setOnItemClickListener(this::goMeasurePage); + } + + private void initData() { + String projectId = getProjectId(); + if (projectId != null) { + LevelingDbFactory.instance.getLevelDataSource().getListLiveData(projectId) + .observe(getViewLifecycleOwner(), routeList -> { + adapter.refreshData(routeList); + }); + } + } + + private String getProjectId() { + if (getArguments() != null) { + return getArguments().getString(BundleConstants.KEY_PROJECT_ID); + } + return null; + } + + private String getRouteId() { + if (getArguments() != null) { + return getArguments().getString(BundleConstants.KEY_ROUTE_ID); + } + return null; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectDetailLevelFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectDetailLevelFragment.java new file mode 100644 index 0000000..58c5eeb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectDetailLevelFragment.java @@ -0,0 +1,162 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.config.ConfigOperate; +import com.bingce.controlapphelper.event.SwitchPageEvent; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.PointListFragment; +import com.bingce.controlnetwork.fragment.ProjectToleranceSettingFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionListActivity; +import com.bingce.controlnetwork.func.level.viewmodel.LevelCreateOrEditRouteVm; +import com.bingce.controlnetwork.ui.ViewUtil; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; +import org.jetbrains.annotations.NotNull; + + +/** + * 水准路线列表,新建测段 + */ +public class ProjectDetailLevelFragment extends BaseFragment { + public static final int title = R.string.project_detail; + public static final String TAG = ProjectDetailLevelFragment.class.getName(); + private String projectId = ""; + private String projectType = ""; + //测站列表 + private LevelRouteFragment fragment; + + private LevelCreateOrEditRouteVm createEditRouteVm; + + + @Override + public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + if (getArguments() != null) { + projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + projectType = getArguments().getString(BundleConstants.KEY_PROJECT_TYPE); + } + createEditRouteVm = new ViewModelProvider(this).get(LevelCreateOrEditRouteVm.class); + View view = inflater.inflate(R.layout.fragment_project_detail_list_level, container, false); + fragment = LevelRouteFragment.newInstance(projectId); + getChildFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, fragment, "__station_list") + .commit(); + //已知点 + View known = view.findViewById(R.id.known_point_list); + initKnownPoint(known); + //未知点 + View unknown = view.findViewById(R.id.unknown_point_list); + initUnKnownPoint(unknown); + //新建测段 + View ilBtn = view.findViewById(R.id.ilBtn); + Button createNewRoute = ilBtn.findViewById(R.id.btnOne); + createNewRoute.setText(R.string.create_segment_survey); + initCreateNewRoute(createNewRoute); + //去测量页面 + Button ivGoMeasurePage = ilBtn.findViewById(R.id.btnTwo); + ivGoMeasurePage.setText(R.string.start_surveyor); + initGoMeasurePage(ivGoMeasurePage); + + setHasOptionsMenu(true); + return view; + } + + private void initGoMeasurePage(View ivGoMeasurePage) { + ViewUtil.setOnClick(ivGoMeasurePage, v -> { + FragmentActivity activity = getActivity(); + if (activity != null) { + activity.finish(); + } + + ThreadPoolUtil.execute(() -> { + String surveyorRouteId = fragment.getSurveyorRouteId(); + ConfigOperate.changeDefaultProjectAndRoute(projectId, surveyorRouteId); + EventBus.getDefault().post(new SwitchPageEvent<>(SwitchPageEvent.TYPE_SWITCH_TO_MEASURE_PAGE_AND_DATA, null)); + }); + }); + } + + private void initUnKnownPoint(View unknown) { + ViewUtil.setOnClick(unknown, + v -> PointListFragment.go2UnknownPointList(projectId, getContext())); + } + + private void initKnownPoint(View known) { + ViewUtil.setOnClick( + known, + v -> PointListFragment.go2KnownPointList(projectId, getContext())); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getData(); + } + + private void getData() { + + } + + /** + * 新建测段 + */ + private void initCreateNewRoute(View viewCreateRoute) { + if (viewCreateRoute != null) { + viewCreateRoute.setOnClickListener((v) -> createEditRouteVm.showCreateOrEditDialog( + requireContext(), + projectId, + null + )); + } + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.project_detail_fragment_menu_level, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.project_parameter_setting) { + //设置参数点击事件 + ProjectToleranceSettingFragment.start(getContext(), projectId, projectType); + return true; + } else if (R.id.iAngleDetection == item.getItemId()) { + LevelIDetectionListActivity.launch(requireContext(), projectId); + } + return super.onOptionsItemSelected(item); + } + + public static void start(Context context, String projectType, String projectId, String projectName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, projectName, bundle); + } + + public static ProjectDetailLevelFragment newInstance(Bundle bundle) { + ProjectDetailLevelFragment fragment = new ProjectDetailLevelFragment(); + fragment.setArguments(bundle); + return fragment; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectEditForLevelFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectEditForLevelFragment.java new file mode 100644 index 0000000..e5d04eb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectEditForLevelFragment.java @@ -0,0 +1,282 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.Toast; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; +import com.bingce.controlapphelper.model.LevelingMeasureOrder; +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil; +import com.bingce.controlapphelper.util.ToleranceUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.AbstractFullScreenDialogFragment; +import com.bingce.controlnetwork.fragment.ToleranceSelectFragment; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; +import com.bingce.utils.DateUtils; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + + +/** + * 水准新建编辑项目 + */ +public class ProjectEditForLevelFragment extends AbstractFullScreenDialogFragment { + public final String TAG = ProjectEditForLevelFragment.class.getSimpleName(); + private String toleranceId; + private final ActivityResultLauncher activityResultLauncher; + + private LevelingMeasureOrder levelingMeasureOrder; + + public ProjectEditForLevelFragment() { + super(); + activityResultLauncher = ToleranceSelectFragment + .createActivityLauncher( + this, + this::dealSelectTolerance); + } + + @Override + protected View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_project_edit_for_level, container, false); + + Button selectToleranceButton = view.findViewById(R.id.select_tolerance); + if (selectToleranceButton != null) { + selectToleranceButton.setOnClickListener(v -> + //选择限差方案 + ToleranceSelectFragment.start(getContext(), toleranceId, ProjectTypeValue.LEVEL, activityResultLauncher) + ); + } + //设置项目名称 + EditText projectNameEdit = view.findViewById(R.id.editor); + if (projectNameEdit != null && getArguments() != null) { + String projectName = getArguments().getString(KEY_PROJECT_NAME); + if (projectName == null || projectName.isEmpty()) { + projectName = DateUtils.ymdWithCharacter(new Date()); + } + projectNameEdit.setText(projectName); + } + if (getArguments() != null) { + toleranceId = getArguments().getString(KEY_TOLERANCE_ID); + if (toleranceId != null && !toleranceId.isEmpty()) { + ThreadPoolUtil.execute(() -> { + ToleranceDetailRecord instance = + SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(toleranceId); + updateTolerance(selectToleranceButton, instance); + }); + } + + String projectId = getArguments().getString(KEY_PROJECT_ID); + if (projectId != null && !projectId.isEmpty()) { + ThreadPoolUtil.execute(() -> { + ProjectRecord projectRecord = + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(projectId); + if (projectRecord == null) { + return; + } + }); + } + } + return view; + } + + @WorkerThread + private void updateTolerance(Button button, IToleranceDetail iToleranceDetail) { + if (iToleranceDetail == null) { + return; + } + toleranceId = iToleranceDetail.getId(); + + IToleranceOperate operate = ToleranceOperateUtil.getOperate(toleranceId); + if (operate == null) return; + ToleranceGroupRecord group = operate.getGroup(iToleranceDetail); + ToleranceLevelRecord level = operate.getLevel(iToleranceDetail); + runOnUI(() -> { + if (button != null) { + String toleranceShowName = ToleranceUtil.completedToleranceName(group, level, iToleranceDetail); + button.setText(toleranceShowName); + } + }); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + List showList = LevelingMeasureOrderUtil.INSTANCE.getShowList(); + Spinner spinner = view.findViewById(R.id.spinner); + spinner.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, showList)); +// spinner.setSelection(editTextItem.prismTypes.indexOf(editTextItem.surveyorPoint.getPrismTypeName())); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + levelingMeasureOrder = LevelingMeasureOrderUtil.INSTANCE.getLevelingMeasureOrderByCreate(showList.get(position)); + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } + + private void runOnUI(Runnable runnable) { + if (getActivity() != null) { + getActivity().runOnUiThread(runnable); + } + } + + @Override + protected boolean quitWhenTouchBg() { + return true; + } + + @Override + protected void onConfirm() { + View view = getView(); + if (view == null) { + return; + } + //判断项目名称是否为空 + EditText editor = view.findViewById(R.id.editor); + String projectName = editor.getText().toString(); + if (projectName.isEmpty()) { + Toast.makeText(getContext(), R.string.tips_need_select_input_project_name, Toast.LENGTH_SHORT).show(); + return; + } + //判断限差参数 + if (toleranceId == null || toleranceId.isEmpty()) { + Toast.makeText(getContext(), R.string.tips_need_select_project_tolerance, Toast.LENGTH_SHORT).show(); + return; + } + if (levelingMeasureOrder == null) { + ToastUtils.showShort(R.string.please_select_measure_order); + return; + } + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(KEY_PROJECT_ID); + boolean showSlop = true; + if (projectId == null || projectId.isEmpty()) { + ProjectRecord projectRecord = new ProjectRecord(projectName); + projectRecord.setToleranceId(toleranceId); + projectRecord.projectType = ProjectTypeValue.LEVEL; + projectRecord.setShowSlopDistance(showSlop); + //存储 + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .saveRecordSync(projectRecord); + + + //判断是否需要记录默认项目和测期 +// ThreadPoolUtil.execute(() -> { +// IConfigDataSource configDataSource = +// TjDbFactory.instance.getConfigDataSource(); +// ConfigRecord defaultProject = configDataSource.getByKeySync(ConfigConstantsTj.KEY_DEFAULT_PROJECT_ID); +// if (defaultProject != null && !defaultProject.getConfigValue().isEmpty()) { +// return; +// } +// }); + } else { + ThreadPoolUtil.execute(() -> { + ProjectRecord projectRecord = + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(projectId); + projectRecord.setProjectName(projectName); + projectRecord.setToleranceId(toleranceId); + projectRecord.setShowSlopDistance(showSlop); + //存储 + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .saveRecordSync(projectRecord); + }); + } + super.onConfirm(); + } + + private static final String KEY_PROJECT_ID = "___project__id"; + private static final String KEY_TOLERANCE_ID = "___tolerance_id"; + private static final String KEY_PROJECT_NAME = "___project___name___"; + + private static DialogFragment newInstance(Context context, String projectId, String toleranceId, String projectName) { + ProjectEditForLevelFragment fragment = new ProjectEditForLevelFragment(); + Bundle args = new Bundle(); + if (projectId == null || projectId.isEmpty()) { + setArgs(args, context.getString(R.string.title_create_new_project), null); + } else { + setArgs(args, context.getString(R.string.title_edit_project), null); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_TOLERANCE_ID, toleranceId); + args.putString(KEY_PROJECT_NAME, projectName); + } + fragment.setArguments(args); + return fragment; + } + + public static void editProject(FragmentManager fragmentManager, + Context context, + String projectId, String toleranceId, String projectName) { + newInstance(context, projectId, toleranceId, projectName).show(fragmentManager, "_edit_project_fragment"); + } + + public static void createProject(FragmentManager fragmentManager, Context context) { + newInstance(context, null, null, null) + .show(fragmentManager, "__create_project_fragment__"); + } + + /** + * 处理选择返回的限差id + * + * @param id + */ + private void dealSelectTolerance(String id) { + ThreadPoolUtil.execute(() -> { + IToleranceOperate operate = ToleranceOperateUtil.getOperate(id); + if (operate == null) return; + IToleranceDetail toleranceDetail = operate.getIToleranceDetail(id); + //存限差数据 + operate.saveToleranceDetail(toleranceDetail); + View view = getView(); + if (view != null) { + updateTolerance(view.findViewById(R.id.select_tolerance), toleranceDetail); + } + }); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectProjectTypeFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/SelectLevelNextStationTypeFragment.java similarity index 53% rename from app/src/main/java/com/bingce/controlnetwork/fragment/SelectProjectTypeFragment.java rename to app/src/main/java/com/bingce/controlnetwork/func/level/fragment/SelectLevelNextStationTypeFragment.java index 94406dd..731d225 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectProjectTypeFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/SelectLevelNextStationTypeFragment.java @@ -1,4 +1,4 @@ -package com.bingce.controlnetwork.fragment; +package com.bingce.controlnetwork.func.level.fragment; import android.os.Bundle; import android.view.LayoutInflater; @@ -11,60 +11,48 @@ import androidx.annotation.Nullable; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.LifecycleOwner; -import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlnetwork.fragment.SelectProjectAndSurveyorCycleFragment; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; -import blankj.utilcode.util.ToastUtils; - import com.bingce.controlnetwork.R; /** - * 选择项目类型 + * 水准选择下一站观测方式 */ -public class SelectProjectTypeFragment extends BottomSheetDialogFragment { +public class SelectLevelNextStationTypeFragment extends BottomSheetDialogFragment { public static final String TAG = SelectProjectAndSurveyorCycleFragment.class.getName(); + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_TYPE = "__SELECT_TYPE__"; + public static final String TYPE_CONTINUE_OBSERVE = "TYPE_CONTINUE_OBSERVE"; + public static final String TYPE_INTERMITTENT = "TYPE_INTERMITTENT"; + public static final String TYPE_END_STATION = "TYPE_END_STATION"; + + private SelectLevelNextStationTypeFragment() { + } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater - .inflate( - R.layout.fragment_select_project_type, - container, - false); - View.OnClickListener onClickListener = v -> { - if (v == null) { - dismiss(); - return; - } - int id = v.getId(); - String type = null; - if (id == R.id.btnTriangleWire) { - type = ProjectType.TRIANGLE.getFlag(); - } else if (id == R.id.btnConnectionSurvey) { - type = ProjectType.CONNECTION.getFlag(); - } else if (id == R.id.btnHeightTraverse) { - type = ProjectType.HEIGHT_TRAVERSE.getFlag(); - } - - if (type == null) { - ToastUtils.showShort("该导线正在开发中,请稍后..."); - return; - } - - - Bundle args = new Bundle(); - args.putString(KEY_TYPE, type); - getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); - dismiss(); - }; + View view = inflater.inflate( + R.layout.fragment_select_level_next_station_type, + container, + false); + initClickListener(view); + return view; + } - setOnClickListener(view, R.id.btnTriangleWire, onClickListener); - setOnClickListener(view, R.id.btnConnectionSurvey, onClickListener); - setOnClickListener(view, R.id.btnHeightTraverse, onClickListener); + private void initClickListener(View view) { + setOnClickListener(view, R.id.continueObserve, v -> backData(TYPE_CONTINUE_OBSERVE)); + setOnClickListener(view, R.id.intermittent, v -> backData(TYPE_INTERMITTENT)); + setOnClickListener(view, R.id.endStation, v -> backData(TYPE_END_STATION)); setOnClickListener(view, R.id.cancel, v -> dismiss()); + } - return view; + private void backData(String type) { + Bundle args = new Bundle(); + args.putString(KEY_TYPE, type); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismissAllowingStateLoss(); } private static void setOnClickListener(View root, int id, View.OnClickListener onClickListener) { @@ -74,14 +62,10 @@ public class SelectProjectTypeFragment extends BottomSheetDialogFragment { } } - private static final String KEY_REQUEST_SELECT = "__SELECT__"; - private static final String KEY_TYPE = "__SELECT_TYPE__"; - - - public static void start(FragmentManager fragmentManager, - @NonNull LifecycleOwner lifecycleOwner, - IOnSelectCallback callback) { - SelectProjectTypeFragment fragment = new SelectProjectTypeFragment(); + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + IOnSelectCallback callback) { + SelectLevelNextStationTypeFragment fragment = new SelectLevelNextStationTypeFragment(); fragmentManager .setFragmentResultListener( KEY_REQUEST_SELECT, diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/TestDataSelectLevelFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/TestDataSelectLevelFragment.java new file mode 100644 index 0000000..a77e6e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/TestDataSelectLevelFragment.java @@ -0,0 +1,136 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.func.level.sendreceive.TestData; + +public class TestDataSelectLevelFragment extends DialogFragment { + private static IClickItem clickItem; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_single_list_layout, container, false); + + // Set the adapter + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + refreshRecyclerView(recyclerView); + } + + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Dialog dialog = getDialog(); + if (dialog == null) { + return; + } + Window window = dialog.getWindow(); + if (window == null) { + return; + } + window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); + WindowManager.LayoutParams lps = window.getAttributes(); + lps.verticalMargin = 0.4F; + lps.horizontalMargin = 0.4F; + window.setAttributes(lps); + } + + protected void refreshRecyclerView(RecyclerView recyclerView) { + List list = TestData.Companion.getTextShowList(); + recyclerView.setAdapter(new MyAdapter(list)); + } + + public static void show(FragmentManager fragmentManager, IClickItem clickItem) { + TestDataSelectLevelFragment.clickItem = clickItem; + TestDataSelectLevelFragment fragment = new TestDataSelectLevelFragment(); + fragment.show(fragmentManager, TestDataSelectLevelFragment.class.getName()); + } + + private class MyAdapter extends RecyclerView.Adapter { + + private final List data; + + public MyAdapter(List data) { + this.data = data; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + Context context = parent.getContext(); + LayoutInflater inflater = LayoutInflater.from(context); + + // Inflate the custom layout + View itemView = inflater.inflate(R.layout.list_item_index_text_layout, parent, false); + + // Return a new holder instance + return new ViewHolder(itemView); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + // Get the data model based on position + String item = data.get(position); + + // Set item views based on your views and data model + holder.index.setText(String.valueOf(position + 1)); + holder.text.setText(item); + + holder.itemView.setOnClickListener(v -> { + if (clickItem != null) { + clickItem.click(holder.getBindingAdapterPosition()); + + dismissAllowingStateLoss(); + } + + }); + } + + @Override + public int getItemCount() { + return data.size(); + } + + // Provide a reference to the views for each data item + + } + + private static class ViewHolder extends RecyclerView.ViewHolder { + public TextView index; + public TextView text; + + public ViewHolder(View itemView) { + super(itemView); + index = itemView.findViewById(R.id.index); + text = itemView.findViewById(R.id.text); + } + } + + public interface IClickItem { + void click(int position); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionCalUtil.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionCalUtil.kt new file mode 100644 index 0000000..435cd77 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionCalUtil.kt @@ -0,0 +1,234 @@ +package com.bingce.controlnetwork.func.level.idetection + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord +import kotlin.math.pow + +object LevelIDetectionCalUtil { + private val station1 = LevelIDetectionConstant.STATION_TYPE_0 + private val station2 = LevelIDetectionConstant.STATION_TYPE_1 + private val ruler1 = LevelIDetectionConstant.RULER_TYPE_0 + private val ruler2 = LevelIDetectionConstant.RULER_TYPE_1 + private val measureTime1 = LevelIDetectionConstant.MEASURE_TIME_0 + private val measureTime2 = LevelIDetectionConstant.MEASURE_TIME_1 + private val measureTime3 = LevelIDetectionConstant.MEASURE_TIME_2 + private val measureTime4 = LevelIDetectionConstant.MEASURE_TIME_3 + private val measureTime5 = LevelIDetectionConstant.MEASURE_TIME_4 + + /** + * 单位mm + * d1短距 + * d2长距 + */ + fun getIResult( + iDetectionId: String, + measureType: String, + d1: Double, + d2: Double, + stationRecordMap: HashMap + ): Double { + val a1 = getA1(iDetectionId, stationRecordMap) + val b1 = getB1(iDetectionId, stationRecordMap) + val a2 = getA2(iDetectionId, stationRecordMap) + val b2 = getB2(iDetectionId, stationRecordMap) + val deTa = getDeTa(measureType, a1, b1, a2, b2) + return getI(deTa, d1, d2) + } + + private fun getI(deTa: Double, d1: Double, d2: Double) = + deTa * 206265 / (d2 - d1) - 1.61 * 10.0.pow(-5.0) * (d1 + d2) + + + private fun getDeTa( + measureType: String, + a1: Double, + b1: Double, + a2: Double, + b2: Double + ): Double { + return if (LevelIDetectionConstant.A_I_I_B == measureType || LevelIDetectionConstant.I_A_B_I == measureType) { + ((a2 - b2) - (a1 - b1)) / 2 + } else { + (a2 - b2) - (a1 - b1) + } + } + + + /** + * 一站一尺 + */ + private fun getA1( + iDetectionId: String, + stationRecordMap: HashMap + ): Double { + val height1 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime1 + )] + ) + val height2 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime2 + )] + ) + val height3 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime3 + )] + ) + val height4 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime4 + )] + ) + val height5 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime5 + )] + ) + return getAverage(height1, height2, height3, height4, height5) + } + + /** + * 一站二尺 + */ + private fun getB1( + iDetectionId: String, + stationRecordMap: HashMap + ): Double { + val height1 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime1 + )] + ) + val height2 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime2 + )] + ) + val height3 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime3 + )] + ) + val height4 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime4 + )] + ) + val height5 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime5 + )] + ) + return getAverage(height1, height2, height3, height4, height5) + } + + /** + * 二站一尺 + */ + private fun getA2( + iDetectionId: String, + stationRecordMap: HashMap + ): Double { + val height1 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime1 + )] + ) + val height2 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime2 + )] + ) + val height3 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime3 + )] + ) + val height4 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime4 + )] + ) + val height5 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime5 + )] + ) + return getAverage(height1, height2, height3, height4, height5) + } + + /** + * 二站二尺 + */ + private fun getB2( + iDetectionId: String, + stationRecordMap: HashMap + ): Double { + val height1 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime1 + )] + ) + val height2 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime2 + )] + ) + val height3 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime3 + )] + ) + val height4 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime4 + )] + ) + val height5 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime5 + )] + ) + return getAverage(height1, height2, height3, height4, height5) + } + + private fun getHeight(record: LevelIDetectionRecord?): Double { + return record?.height ?: 0.0 + } + + /** + * 返回单位mm + */ + private fun getAverage( + height1: Double, + height2: Double, + height3: Double, + height4: Double, + height5: Double + ): Double { + return (height1 + height2 + height3 + height4 + height5) / 5 * 1000 + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionListActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionListActivity.kt new file mode 100644 index 0000000..9b168ce --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionListActivity.kt @@ -0,0 +1,101 @@ +package com.bingce.controlnetwork.func.level.idetection + +import android.content.Context +import android.content.Intent +import androidx.activity.viewModels +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlapphelper.widget.swiperecyclerview.widget.DefaultItemDecoration +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityLevelIDetectionListBinding +import com.bingce.controlnetwork.func.level.fragment.LevelIDetectionCreateFragment +import com.bingce.controlnetwork.func.level.idetection.adapter.LevelIDetectionListAdapter +import com.bingce.controlnetwork.func.level.idetection.viewmodel.LevelIDetectionListVm +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import com.bingce.controlnetwork.newui.widget.swipemenu.SwipeMenuDelete +import com.bingce.controlnetwork.util.DialogUtil +import com.bingce.utils.DateUtils +import java.util.Date + +/** + * 水准i角检测列表 + */ +class LevelIDetectionListActivity : BaseBindingActivity() { + private val viewModel by viewModels() + + private val adater by lazy { + LevelIDetectionListAdapter(this) + } + + companion object { + @JvmStatic + fun launch(context: Context, projectId: String) { + context.startActivity(Intent(context, LevelIDetectionListActivity::class.java).apply { + putExtra(BundleConstants.KEY_PROJECT_ID, projectId) + }) + } + } + + override fun getBinding(): ActivityLevelIDetectionListBinding { + return ActivityLevelIDetectionListBinding.inflate(layoutInflater) + } + + override fun initView() { + initAdapter() + initListener() + } + + private fun initListener() { + mBinding.tvCreateIAngleDetection.setOnClickListener { + LevelIDetectionCreateFragment.input( + supportFragmentManager, + "i角检测名称", + DateUtils.ymdHMSWithCharacter(Date()), + this + ) { name -> viewModel.saveNewRecord(getProjectId(), name) } + + } + } + + private fun initAdapter() { + mBinding.ilSwipeList.swipeRecyclerView.addItemDecoration( + DefaultItemDecoration( + Tools.getColor(R.color.transparent), 1, 1 + ) + ) + mBinding.ilSwipeList.swipeRecyclerView.setSwipeMenuCreator( + SwipeMenuDelete(this) + ) + mBinding.ilSwipeList.swipeRecyclerView.setOnItemMenuClickListener { menuBridge, adapterPosition -> + menuBridge.closeMenu() + dealMenuClick(menuBridge.position, adater.getBean(adapterPosition)) + } + mBinding.ilSwipeList.swipeRecyclerView.setOnItemClickListener { view, adapterPosition -> + val bean = adater.getBean(adapterPosition) + LevelIDetectionRecordActivity.launch(this, bean.id) + } + mBinding.ilSwipeList.swipeRecyclerView.adapter = adater + } + + private fun dealMenuClick(position: Int, bean: LevelIDetectionList?) { + DialogUtil.showConfirmDialog( + supportFragmentManager, this, "您确定要删除该i角检测吗?", + Tools.getString(R.string.confirm) + ) { + bean?.let { + viewModel.deleteRecord(it) + } + } + } + + override fun initData() { + viewModel.getListLiveData(getProjectId()).observe(this) { + adater.refreshData(it) + } + } + + private fun getProjectId() = intent.getStringExtra(BundleConstants.KEY_PROJECT_ID)!! + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionRecordActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionRecordActivity.kt new file mode 100644 index 0000000..0101c58 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionRecordActivity.kt @@ -0,0 +1,371 @@ +package com.bingce.controlnetwork.func.level.idetection + +import android.content.Context +import android.content.Intent +import android.text.TextUtils +import android.view.Menu +import android.view.MenuItem +import android.view.View +import android.widget.EditText +import androidx.activity.viewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.idetection.viewmodel.LevelIDetectionRecordVm +import com.bingce.controlnetwork.func.level.sendreceive.ILevelBackData +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequest +import cn.liuyanbing.surveyor.function.level.sendreceive.LevelRequestRelease +import com.bingce.controlnetwork.newui.widget.selectitem.SelectIDetectionStationFragment +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.I_A_B_I +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlapphelper.widget.swiperecyclerview.widget.DefaultItemDecoration +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityLevelIDetectionRecordBinding +import com.bingce.controlnetwork.event.RefreshEvent +import com.bingce.controlnetwork.fragment.TipsFragment +import com.bingce.controlnetwork.func.level.fragment.LevelInputAllowFragment +import com.bingce.controlnetwork.func.level.fragment.LevelInputFragment +import com.bingce.controlnetwork.func.level.idetection.adapter.LevelIDetectionRecordAdapter +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import com.bingce.controlnetwork.newui.widget.selectitem.BaseSelectItemFragment +import com.bingce.controlnetwork.newui.widget.selectitem.SelectIDetectionStationMeasureTypeFragment +import com.bingce.controlnetwork.util.DialogUtil +import com.bingce.controlnetwork.util.StationSettingCheckUtil +import com.bingce.utils.ScreenUtil +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode + +/** + * 水准i角检测-测量 + */ +class LevelIDetectionRecordActivity : BaseBindingActivity() { + private val viewModel by viewModels() + + private val stationSettingCheckUtil = StationSettingCheckUtil() + + private val adapter by lazy { + LevelIDetectionRecordAdapter(this, surveyorData) + } + + private val surveyorData by lazy { + LevelIDetectionSurveyorData(getIDetectionId()) + } + + private val levelReceiveData: LevelRequest = LevelRequestRelease(object : ILevelBackData { + override fun receive(data: LevelReceiveData) { + receiveData(data) + } + + override fun measureError(msg: String) { + if (isDestroyed || isFinishing) { + return + } + DialogUtil.showAlertDialog( + this@LevelIDetectionRecordActivity, + supportFragmentManager, + this@LevelIDetectionRecordActivity, + msg + ) + } + }) + + @Subscribe(threadMode = ThreadMode.BACKGROUND) + fun refresh(event: RefreshEvent<*>) { + if (event.type == RefreshEvent.REFRESH_BY_LEVEL_I_DETECTION_SETTING_UPDATE) { + viewModel.updateStationSetting() + adapter.setStationSetting(viewModel.stationSetting) + runOnUiThread { + adapter.notifyDataSetChanged() + } + } + } + + companion object { + @JvmStatic + fun launch(context: Context, levelIDetectionId: String) { + context.startActivity(Intent(context, LevelIDetectionRecordActivity::class.java).apply { + putExtra(BundleConstants.KEY_I_DETECTION_ID, levelIDetectionId) + }) + } + } + + override fun getBinding(): ActivityLevelIDetectionRecordBinding { + return ActivityLevelIDetectionRecordBinding.inflate(layoutInflater) + } + + override fun onDestroy() { + super.onDestroy() + levelReceiveData.onDestroy() + EventBus.getDefault().unregister(this) + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_level_survey_i_detection, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.result == item.itemId) { + startIResult() + } else if (R.id.stationSetting == item.itemId) { + goLevelIDetectionSetting() + } else if (R.id.rollBack == item.itemId) { + startRollBack() + } else if (R.id.level_i_detection_sample == item.itemId) { + LevelIDetectionSampleActivity.launch(this) + } else if (R.id.receiveDataType == item.itemId) { + showReceiveDataTypeDialog() + } + return super.onOptionsItemSelected(item) + } + + /** + * i角检测的测站设置 + */ + private fun goLevelIDetectionSetting() { + LevelIDetectionStationSettingActivity.launch(this, getIDetectionId()) + } + + private fun showReceiveDataTypeDialog() { + LevelInputAllowFragment.show( + supportFragmentManager, + this, + mBinding.surveyor.visibility == View.VISIBLE + ) { + viewModel.setGetDataAuto(getIDetectionId(), it) + refreshManuleAutoInput(it) + } + } + + private fun startIResult() { + val d1String = getEtText(mBinding.etShortDistance) + if (TextUtils.isEmpty(d1String)) { + ToastUtils.showShort("请输入短距") + return + } + val d2String = getEtText(mBinding.etLongDistance) + if (TextUtils.isEmpty(d2String)) { + ToastUtils.showShort("请输入长距") + return + } + + if (viewModel.measureType == null) { + ToastUtils.showShort("请选择测量方式") + return + } + + //存短长距和测量方式 + viewModel.saveShortLongDistanceMeasureType(d1String, d2String) + //计算结果 + val result = viewModel.startResult(getD(d1String), getD(d2String)) + if (!TextUtils.isEmpty(result)) { + DialogUtil.showAlertDialog( + this, + supportFragmentManager, + this, + result + ) + } + } + + private fun getEtText(et: EditText): String { + return et.text.toString().trim() + } + + /** + * 返回mm的D + */ + private fun getD(value: String): Double { + return value.toDouble() * 1000 + } + + private fun startRollBack() { + val findRollBackData = viewModel.findRollBackData() + if (findRollBackData == null) { + ToastUtils.showShort("没有可以回退的数据") + return + } + + val deleteStationShow = + LevelIDetectionConstant.getStationTypeShow(findRollBackData.currentStationType) + val deleteRuleShow = + LevelIDetectionConstant.getRulerTypeShow(findRollBackData.currentRulerType) + + val hint = "回退操作将删除 $deleteStationShow $deleteRuleShow 的数据,您是否还要回退?" + + showConfirmDialog(hint) { + viewModel.deleteStationRulerData(findRollBackData) { + refreshAdapterAndButton() + } + } + } + + override fun initView() { + EventBus.getDefault().register(this) + levelReceiveData.onStart() + initAdapter() + + initListener() + + viewModel.getGetDadaAuto(getIDetectionId()) { + refreshManuleAutoInput(it) + } + } + + private fun initListener() { + mBinding.llStation.setOnClickListener { + if (adapter.itemCount == 0) { + ToastUtils.showShort("数据加载中,请稍后尝试") + return@setOnClickListener + } + BaseSelectItemFragment.select( + SelectIDetectionStationFragment(), + supportFragmentManager, + this, object : BaseSelectItemFragment.ISelectItem { + override fun onBack(value: String) { + //value stationType + viewModel.switchStation(value.toInt()) + setCurrentStation() + refreshAdapterAndButton() + } + }) + } + + mBinding.llMeasureType.setOnClickListener { + BaseSelectItemFragment.select( + SelectIDetectionStationMeasureTypeFragment(), + supportFragmentManager, + this, object : BaseSelectItemFragment.ISelectItem { + override fun onBack(value: String) { + switchMeasureType(value) + } + }) + } + + mBinding.surveyor.setOnClickListener { + stationSettingCheckUtil.checkStationSettingsIDetection( + getIDetectionId(), + this, + this::runOnUiThread + ) { + levelReceiveData.requeset() + } + } + + mBinding.btnInput.setOnClickListener { + LevelInputFragment.show( + supportFragmentManager, this + ) { distance: Double, height: Double -> + receiveData(LevelReceiveData(height, distance)) + } + } + } + + private fun receiveData(data: LevelReceiveData) { + if (isFinishing || isDestroyed) { + return + } + viewModel.receiveData(data.height, data.distance) + refreshAdapterAndButton() + } + + /** + * 切换测量方法带存储 + */ + private fun switchMeasureType(measureType: String) { + setCurrentMeasureType(measureType) + viewModel.saveMeasureType(getIDetectionId(), measureType) + } + + private fun setCurrentMeasureType(measureType: String?) { + mBinding.tvMeasureType.text = measureType + viewModel.measureType = measureType + } + + private fun setCurrentStation() { + val stationTypeShow = + LevelIDetectionConstant.getStationTypeShow(surveyorData.currentStationType) + mBinding.tvStation.text = stationTypeShow + } + + private fun initAdapter() { + mBinding.recyclerView.adapter = adapter + mBinding.recyclerView.addItemDecoration( + DefaultItemDecoration( + Tools.getColor(R.color.transparent), + 1, + ScreenUtil.dp2px(this, 10f) + ) + ) + } + + override fun initData() { + viewModel.initData(surveyorData) { + adapter.setStationSetting(viewModel.stationSetting) + + setCurrentStation() + + if (it.measureType == null) { + switchMeasureType(I_A_B_I) + } else { + setCurrentMeasureType(it.measureType) + } + + //设置短长距 + setShortLongDistance(it) + + refreshButton() + + adapter.refreshData(viewModel.dataListAdapter) + } + } + + private fun setShortLongDistance(it: LevelIDetectionList) { + mBinding.etShortDistance.setText(it.shortDistance) + mBinding.etLongDistance.setText(it.longDistance) + } + + private fun getIDetectionId() = intent.getStringExtra(BundleConstants.KEY_I_DETECTION_ID)!! + + + private fun showConfirmDialog(content: String, callback: TipsFragment.IConfirmCallback) { + TipsFragment.cancelAbleTips( + supportFragmentManager, this, this, + content, -1, callback + ) + } + + private fun refreshAdapterAndButton() { + adapter.notifyDataSetChanged() + refreshButton() + } + + private fun refreshButton() { + //刷新测量按钮 + setViewEnable(mBinding.surveyor, surveyorData.isHaveSurveyor()) + setViewEnable(mBinding.btnInput, surveyorData.isHaveSurveyor()) + } + + private fun setViewEnable(view: View, measureEnable: Boolean) { + view.isEnabled = measureEnable + if (measureEnable) { + view.alpha = 1f + } else { + view.alpha = .4f + } + } + + private fun refreshManuleAutoInput(receiveDataTypeAuto: Boolean) { + if (receiveDataTypeAuto) { + mBinding.surveyor.visibility = View.VISIBLE + mBinding.btnInput.visibility = View.GONE + } else { + mBinding.btnInput.visibility = View.VISIBLE + mBinding.surveyor.visibility = View.GONE + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSampleActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSampleActivity.kt new file mode 100644 index 0000000..f223be4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSampleActivity.kt @@ -0,0 +1,31 @@ +package com.bingce.controlnetwork.func.level.idetection + +import android.content.Context +import android.content.Intent +import com.bingce.controlnetwork.databinding.ActivityLevelIDetectionSampleBinding +import com.bingce.controlnetwork.newui.base.BaseBindingActivity + +/** + * 水准i角检测示例图 + */ +class LevelIDetectionSampleActivity : BaseBindingActivity() { + + companion object { + @JvmStatic + fun launch(context: Context) { + context.startActivity(Intent(context, LevelIDetectionSampleActivity::class.java)) + } + } + + override fun getBinding(): ActivityLevelIDetectionSampleBinding { + return ActivityLevelIDetectionSampleBinding.inflate(layoutInflater) + } + + override fun initView() { + + } + + override fun initData() { + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionStationSettingActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionStationSettingActivity.kt new file mode 100644 index 0000000..fa3f9f4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionStationSettingActivity.kt @@ -0,0 +1,173 @@ +package com.bingce.controlnetwork.func.level.idetection + +import android.content.Context +import android.content.Intent +import android.text.TextUtils +import android.view.Menu +import android.view.MenuItem +import android.widget.ArrayAdapter +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.constant.LevelStationSettingContant +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.idetection.isetting.LevelIDetectionSetting +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityLevelIDetectionStationSettingBinding +import com.bingce.controlnetwork.event.RefreshEvent +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.greenrobot.eventbus.EventBus + +/** + * i角检测测站设置 + */ +class LevelIDetectionStationSettingActivity : + BaseBindingActivity() { + + companion object { + @JvmStatic + fun launch(context: Context, iDetectionId: String) { + context.startActivity( + Intent( + context, + LevelIDetectionStationSettingActivity::class.java + ).apply { + putExtra(BundleConstants.KEY_I_DETECTION_ID, iDetectionId) + }) + } + } + + override fun getBinding(): ActivityLevelIDetectionStationSettingBinding { + return ActivityLevelIDetectionStationSettingBinding.inflate(layoutInflater) + } + + override fun initView() { + initEditTextTitle() + initSpinnerImaging() + } + + override fun initData() { + getEditData() + } + + private fun getEditData() { + lifecycleScope.launch(Dispatchers.IO) { + val iDetectionId = getIDetectionId() + val record = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + iDetectionId + ) + + if (record != null) { + withContext(Dispatchers.Main) { + setData(record) + } + } + } + } + + /** + * 初始化editText坐标的title + */ + private fun initEditTextTitle() { + mBinding.ilWatcher.tvTitle.text = "观测者" + mBinding.ilRecorder.tvTitle.text = "记录者" + mBinding.ilExaminer.tvTitle.text = "检查者" + mBinding.ilRuler1.tvTitle.text = "尺一编号" + mBinding.ilRuler2.tvTitle.text = "尺二编号" + mBinding.ilInstrumentModel.tvTitle.text = "仪器型号" + mBinding.ilDeviceNumber.tvTitle.text = "仪器编号" + } + + private fun setData(record: LevelIDetectionSetting) { + mBinding.ilWatcher.editText.setText(record.watcher) + mBinding.ilRecorder.editText.setText(record.recorder) + mBinding.ilExaminer.editText.setText(record.examiner) + mBinding.ilRuler1.editText.setText(record.rulerNum1) + mBinding.ilRuler2.editText.setText(record.rulerNum2) + mBinding.ilInstrumentModel.editText.setText(record.instrumentModel) + mBinding.ilDeviceNumber.editText.setText(record.deviceNumber) + mBinding.spinnerImaging.setSelection(LevelStationSettingContant.imagingList.indexOf(record.imaging)) + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_save, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.menuSave) { + startSave() + } + return super.onOptionsItemSelected(item) + } + + private fun initSpinnerImaging() { + mBinding.spinnerImaging.adapter = ArrayAdapter( + this, + android.R.layout.simple_list_item_1, + LevelStationSettingContant.imagingList + ) + } + + private fun startSave() { + val watcher = mBinding.ilWatcher.editText.text.toString().trim() + val recorder = mBinding.ilRecorder.editText.text.toString().trim() + val examiner = mBinding.ilExaminer.editText.text.toString().trim() + val ruler1 = mBinding.ilRuler1.editText.text.toString().trim() + val ruler2 = mBinding.ilRuler2.editText.text.toString().trim() + val instrumentModel = mBinding.ilInstrumentModel.editText.text.toString().trim() + val deviceNumber = mBinding.ilDeviceNumber.editText.text.toString().trim() + val imaging = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerImaging) + + if (isEmpty(ruler1)) { + ToastUtils.showShort("请输入尺一编号") + return + } + if (isEmpty(ruler2)) { + ToastUtils.showShort("请输入尺二编号") + return + } + + lifecycleScope.launch(Dispatchers.IO) { + val iDetectionId = getIDetectionId() + val record = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + iDetectionId + ) + + val saveRecord = record ?: LevelIDetectionSetting(iDetectionId) + + saveRecord.watcher = watcher + saveRecord.recorder = recorder + saveRecord.examiner = examiner + saveRecord.rulerNum1 = ruler1 + saveRecord.rulerNum2 = ruler2 + saveRecord.instrumentModel = instrumentModel + saveRecord.deviceNumber = deviceNumber + saveRecord.imaging = imaging + + if (record == null) { + LevelingDbFactory.instance.iDetectionSettingDataSource.save(saveRecord) + } else { + LevelingDbFactory.instance.iDetectionSettingDataSource.update(saveRecord) + } + + EventBus.getDefault() + .post(RefreshEvent(RefreshEvent.REFRESH_BY_LEVEL_I_DETECTION_SETTING_UPDATE, null)) + + finish() + } + + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + + + private fun getIDetectionId() = intent.getStringExtra(BundleConstants.KEY_I_DETECTION_ID)!! + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSurveyorData.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSurveyorData.kt new file mode 100644 index 0000000..d7b9782 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSurveyorData.kt @@ -0,0 +1,14 @@ +package com.bingce.controlnetwork.func.level.idetection + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant + +/** + * 当前测量的测站,尺子,第几个 + */ +class LevelIDetectionSurveyorData(val currentIDetectionId: String) { + var currentStationType = LevelIDetectionConstant.STATION_TYPE_0 + var currentMeasureTime = LevelIDetectionConstant.MEASURE_TIME_0 + var currentRulerType = -1//默认不选中尺寸,因为可能已经测完 + + fun isHaveSurveyor() = currentRulerType != -1 +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListAdapter.java new file mode 100644 index 0000000..d102e9f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListAdapter.java @@ -0,0 +1,34 @@ +package com.bingce.controlnetwork.func.level.idetection.adapter; + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList; +import com.bingce.controlnetwork.databinding.ItemLevelIDetectionListBinding; +import com.bingce.controlnetwork.newui.adapter.BaseAdapterNew; + + +/** + * i角检测列表 + */ +public class LevelIDetectionListAdapter extends BaseAdapterNew { + + public LevelIDetectionListAdapter(Context context) { + super(context); + } + + @Override + protected void onBindViewHolderDo(LevelIDetectionListHolder holder, int position) { + LevelIDetectionList bean = mDataList.get(position); + holder.mBinding.tvIndex.setText(String.valueOf(position + 1)); + holder.mBinding.tvName.setText(bean.name); + } + + @NonNull + @Override + public LevelIDetectionListHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new LevelIDetectionListHolder(ItemLevelIDetectionListBinding.inflate(getInflater(), parent, false)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListHolder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListHolder.java new file mode 100644 index 0000000..9fcdb78 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.func.level.idetection.adapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.ItemLevelIDetectionListBinding; + + +public class LevelIDetectionListHolder extends RecyclerView.ViewHolder { + public final ItemLevelIDetectionListBinding mBinding; + + public LevelIDetectionListHolder(ItemLevelIDetectionListBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordAdapter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordAdapter.java new file mode 100644 index 0000000..e7092b8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordAdapter.java @@ -0,0 +1,120 @@ +package com.bingce.controlnetwork.func.level.idetection.adapter; + +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_0; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_1; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_2; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_3; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_4; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_0; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_1; + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant; +import com.bingce.controlapphelper.datasource.database.leveling.idetection.isetting.LevelIDetectionSetting; +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord; +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ItemLevelIDetectionRecordBinding; +import com.bingce.controlnetwork.newui.adapter.BaseAdapterNew; + +import java.util.Map; + +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionSurveyorData; + + +/** + * i角检测列表 + */ +public class LevelIDetectionRecordAdapter extends BaseAdapterNew> { + + private final LevelIDetectionSurveyorData surveyorData; + private LevelIDetectionSetting stationSetting; + + public LevelIDetectionRecordAdapter(Context context, LevelIDetectionSurveyorData surveyorData) { + super(context); + this.surveyorData = surveyorData; + } + + @NonNull + @Override + public LevelIDetectionRecordHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new LevelIDetectionRecordHolder(ItemLevelIDetectionRecordBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(LevelIDetectionRecordHolder holder, int position) { + Map recordMap = mDataList.get(0); + + //尺子 + int rulerType; + if (position == 0) { + rulerType = RULER_TYPE_0; + } else { + rulerType = RULER_TYPE_1; + } + + + //当前测的尺子选中 + boolean isSelect = rulerType == surveyorData.getCurrentRulerType(); + if (isSelect) { + holder.mBinding.getRoot().setBackgroundDrawable(Tools.getDrawable(R.drawable.select_mask)); + } else { + holder.mBinding.getRoot().setBackgroundColor(Tools.getColor(R.color.white)); + } + + LevelIDetectionRecord record1 = getRecord(recordMap, rulerType, MEASURE_TIME_0); + LevelIDetectionRecord record2 = getRecord(recordMap, rulerType, MEASURE_TIME_1); + LevelIDetectionRecord record3 = getRecord(recordMap, rulerType, MEASURE_TIME_2); + LevelIDetectionRecord record4 = getRecord(recordMap, rulerType, MEASURE_TIME_3); + LevelIDetectionRecord record5 = getRecord(recordMap, rulerType, MEASURE_TIME_4); + + //尺几 + holder.mBinding.tvRulerType.setText(LevelIDetectionConstant.getRulerTypeShow(rulerType)); + //尺号 + holder.mBinding.tvRulerNum.setText(LevelIDetectionConstant.getRulerNumShow(rulerType, stationSetting)); + + holder.mBinding.tvHeight1.setText(getHeight(record1)); + holder.mBinding.tvDistance1.setText(getDistance(record1)); + holder.mBinding.tvHeight2.setText(getHeight(record2)); + holder.mBinding.tvDistance2.setText(getDistance(record2)); + holder.mBinding.tvHeight3.setText(getHeight(record3)); + holder.mBinding.tvDistance3.setText(getDistance(record3)); + holder.mBinding.tvHeight4.setText(getHeight(record4)); + holder.mBinding.tvDistance4.setText(getDistance(record4)); + holder.mBinding.tvHeight5.setText(getHeight(record5)); + holder.mBinding.tvDistance5.setText(getDistance(record5)); + } + + private LevelIDetectionRecord getRecord(Map map, int rulerType, int measureTime) { + String recordId = LevelIDetectionRecord.getRecordId(surveyorData.getCurrentIDetectionId(), surveyorData.getCurrentStationType(), rulerType, measureTime); + return map.get(recordId); + } + + private String getHeight(LevelIDetectionRecord record) { + if (record == null) { + return ""; + } + return LevelFormatUtil.INSTANCE.formatHeight(record.height); + } + + private String getDistance(LevelIDetectionRecord record) { + if (record == null) { + return ""; + } + return LevelFormatUtil.INSTANCE.formatDistance(record.distance); + } + + @Override + public int getItemCount() { + return mDataList == null ? 0 : 2; + } + + public void setStationSetting(LevelIDetectionSetting stationSetting) { + this.stationSetting = stationSetting; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordHolder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordHolder.java new file mode 100644 index 0000000..271baf5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.func.level.idetection.adapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.ItemLevelIDetectionRecordBinding; + + +public class LevelIDetectionRecordHolder extends RecyclerView.ViewHolder { + public final ItemLevelIDetectionRecordBinding mBinding; + + public LevelIDetectionRecordHolder(ItemLevelIDetectionRecordBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/util/LevelIDetectionFindUtil.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/util/LevelIDetectionFindUtil.kt new file mode 100644 index 0000000..762300b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/util/LevelIDetectionFindUtil.kt @@ -0,0 +1,247 @@ +package com.bingce.controlnetwork.func.level.idetection.util + +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionSurveyorData +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_2 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_3 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_4 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.STATION_TYPE_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.STATION_TYPE_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord + +/** + * 查找工具 + */ +class LevelIDetectionFindUtil { + + fun getFindMeasureList(iDetectionId: String): List { + val station1 = STATION_TYPE_0 + val station2 = STATION_TYPE_1 + val ruler1 = RULER_TYPE_0 + val ruler2 = RULER_TYPE_1 + val measureTime1 = MEASURE_TIME_0 + val measureTime2 = MEASURE_TIME_1 + val measureTime3 = MEASURE_TIME_2 + val measureTime4 = MEASURE_TIME_3 + val measureTime5 = MEASURE_TIME_4 + + return listOf( + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime5 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime5 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime5 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime5 + ) + ) + } + + fun getFindMeasureList( + iDetectionId: String, + stationType: Int + ): List { + val ruler1 = RULER_TYPE_0 + val ruler2 = RULER_TYPE_1 + val measureTime1 = MEASURE_TIME_0 + val measureTime2 = MEASURE_TIME_1 + val measureTime3 = MEASURE_TIME_2 + val measureTime4 = MEASURE_TIME_3 + val measureTime5 = MEASURE_TIME_4 + + return listOf( + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime5 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime5 + ) + ) + } + + fun find( + recordList: List, + findCase: (LevelIDetectionRecord) -> Boolean + ): LevelIDetectionSurveyorData? { + for (record in recordList) { + if (findCase(record)) { + val surveyorData = LevelIDetectionSurveyorData("") + surveyorData.currentStationType = record.stationType + surveyorData.currentRulerType = record.rulerType + surveyorData.currentMeasureTime = record.measureTime + return surveyorData + } + } + return null + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionListVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionListVm.kt new file mode 100644 index 0000000..274e192 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionListVm.kt @@ -0,0 +1,39 @@ +package com.bingce.controlnetwork.func.level.idetection.viewmodel + +import androidx.lifecycle.LiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class LevelIDetectionListVm : ViewModel() { + + fun getListLiveData(projectId: String): LiveData> { + return LevelingDbFactory.instance.iDetectionListDataSource.getListByProjectIdDescLiveData( + projectId + ) + } + + /** + * 创建i角检测 + */ + fun saveNewRecord(projectId: String, name: String) { + viewModelScope.launch(Dispatchers.IO) { + val bean = LevelIDetectionList.create(projectId, name) + LevelingDbFactory.instance.iDetectionListDataSource.save(bean) + } + } + + /** + * 创建i角检测 + */ + fun deleteRecord(bean: LevelIDetectionList) { + viewModelScope.launch(Dispatchers.IO) { + LevelingDbFactory.instance.iDetectionListDataSource.delete(bean) + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionRecordVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionRecordVm.kt new file mode 100644 index 0000000..8bad019 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionRecordVm.kt @@ -0,0 +1,361 @@ +package com.bingce.controlnetwork.func.level.idetection.viewmodel + +import androidx.annotation.WorkerThread +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionCalUtil +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionSurveyorData +import com.bingce.controlnetwork.func.level.idetection.util.LevelIDetectionFindUtil +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDb +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_2 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_3 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_4 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.isetting.LevelIDetectionSetting +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil +import com.bingce.controlapphelper.util.Tools +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelIDetectionRecordVm : ViewModel() { + + //key 记录id + val dataListAdapter = mutableListOf>() + + //key 记录id + private val stationRecordMap = hashMapOf() + + lateinit var surveyorData: LevelIDetectionSurveyorData + + var measureType: String? = null + + var stationSetting: LevelIDetectionSetting? = null + + val findUtil = LevelIDetectionFindUtil() + + fun initData( + surveyorData: LevelIDetectionSurveyorData, + callBack: (LevelIDetectionList) -> Unit + ) { + this.surveyorData = surveyorData + viewModelScope.launch(Dispatchers.IO) { + dataListAdapter.clear() + dataListAdapter.add(stationRecordMap) + val records = + LevelingDbFactory.instance.iDetectionRecordDataSource.getRecordsByIDetectionId( + surveyorData.currentIDetectionId + ) + //更新测站设置 + updateStationSetting() + + for (record in records) { + stationRecordMap[record.id] = record + } + + //查询第一个需要测量的数据 + val findMeasureDataAll = findMeasureDataAll() + if (findMeasureDataAll != null) { + changeCurrentSurveyorData(findMeasureDataAll) + } + + val iDetectionRecord = + LevelingDbFactory.instance.iDetectionListDataSource.getById(surveyorData.currentIDetectionId) + + withContext(Dispatchers.Main) { + callBack(iDetectionRecord) + } + } + } + + /** + * 存数据 + */ + fun receiveData(height: Double, distance: Double) { + if (surveyorData.currentRulerType == -1) { + ToastUtils.showShort("未找到观测尺") + return + } + + //存当前测量的数据 + val recordId = LevelIDetectionRecord.getRecordId( + surveyorData.currentIDetectionId, + surveyorData.currentStationType, + surveyorData.currentRulerType, + surveyorData.currentMeasureTime + ) + val record = LevelIDetectionRecord.create( + surveyorData.currentIDetectionId, surveyorData.currentStationType, + surveyorData.currentRulerType, surveyorData.currentMeasureTime, + height, distance + ) + + stationRecordMap[recordId] = record + + //测完一个数据更新尺子和测量次数 + if (surveyorData.currentMeasureTime == MEASURE_TIME_4) { + //最后一个测完了 + if (surveyorData.currentRulerType == RULER_TYPE_1) { + //该站全部测完 + surveyorData.currentRulerType = -1 + surveyorData.currentMeasureTime = MEASURE_TIME_0 + + Tools.speak("该测站测量完毕") + } else { + //一尺测量完 + surveyorData.currentRulerType = RULER_TYPE_1 + surveyorData.currentMeasureTime = MEASURE_TIME_0 + Tools.speak("尺一测量完毕") + } + } else { + //不是最后一次直接加 + surveyorData.currentMeasureTime++ + if (surveyorData.currentMeasureTime > MEASURE_TIME_4) { + surveyorData.currentMeasureTime = MEASURE_TIME_4 + } + } + + //存数据库 + viewModelScope.launch(Dispatchers.IO) { + LevelingDb.getInstance().iDetectionRecordDao().save(record) + } + } + + /** + * 找第一个没有数据的 + */ + private fun findMeasureDataAll(): LevelIDetectionSurveyorData? { + val recordList = findUtil.getFindMeasureList(surveyorData.currentIDetectionId) + return findUtil.find(recordList) { + stationRecordMap[it.id] == null + } + } + + /** + * 找第一个没有数据的 + */ + fun switchStation(stationType: Int) { + val recordList = findUtil.getFindMeasureList(surveyorData.currentIDetectionId, stationType) + val find = findUtil.find(recordList) { + stationRecordMap[it.id] == null + } + if (find != null) { + changeCurrentSurveyorData(find) + } else { + val surveyorData = LevelIDetectionSurveyorData("") + surveyorData.currentStationType = stationType + changeCurrentSurveyorData(surveyorData) + } + } + + private fun changeCurrentSurveyorData(surveyorData: LevelIDetectionSurveyorData) { + this.surveyorData.currentStationType = surveyorData.currentStationType + this.surveyorData.currentRulerType = surveyorData.currentRulerType + this.surveyorData.currentMeasureTime = surveyorData.currentMeasureTime + } + + /** + * 找最后一个有数据的 + */ + fun findRollBackData(): LevelIDetectionSurveyorData? { + val recordList = findUtil.getFindMeasureList( + surveyorData.currentIDetectionId, + surveyorData.currentStationType + ).reversed() + return findUtil.find(recordList) { + stationRecordMap[it.id] != null + } + } + + + /** + * 回退删除数据 + * 一次删一个测站的一个尺子的数据 + */ + fun deleteStationRulerData(findRollBackData: LevelIDetectionSurveyorData, success: () -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val deleteIDetectionId = surveyorData.currentIDetectionId + val deleteStationType = findRollBackData.currentStationType + val deleteRulerType = findRollBackData.currentRulerType + + val recordId1 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_0 + ) + val recordId2 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_1 + ) + val recordId3 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_2 + ) + val recordId4 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_3 + ) + val recordId5 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_4 + ) + //删除缓存 + stationRecordMap.remove(recordId1) + stationRecordMap.remove(recordId2) + stationRecordMap.remove(recordId3) + stationRecordMap.remove(recordId4) + stationRecordMap.remove(recordId5) + //删除数据 + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId1) + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId2) + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId3) + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId4) + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId5) + + //确定要测哪个 + findRollBackData.currentMeasureTime = MEASURE_TIME_0 + changeCurrentSurveyorData(findRollBackData) + + withContext(Dispatchers.Main) { + success() + } + } + } + + /** + * 保存测量方式 + */ + fun saveMeasureType(iDetectionId: String, measureType: String) { + viewModelScope.launch(Dispatchers.IO) { + val record = + LevelingDbFactory.instance.iDetectionListDataSource.getById(iDetectionId) + record.measureType = measureType + LevelingDbFactory.instance.iDetectionListDataSource.update(record) + } + } + + /** + * 单位mm + * d1短距 + * d2长距 + */ + fun startResult(d1: Double, d2: Double): String? { + val findMeasureList = findUtil.getFindMeasureList(surveyorData.currentIDetectionId) + for (needCheckItem in findMeasureList) { + val levelIDetectionRecord = stationRecordMap[needCheckItem.id] + if (levelIDetectionRecord == null) { + ToastUtils.showShort(LevelIDetectionConstant.getStationTypeShow(needCheckItem.stationType) + "数据不完整") + return null + } + } + + val iResult = LevelIDetectionCalUtil.getIResult( + surveyorData.currentIDetectionId, + measureType!!, + d1, + d2, + stationRecordMap + ) + + val hint = if (iResult.isFinite()) { + val formatAngle = LevelFormatUtil.formatAngle(iResult) + saveIResult(formatAngle) + if (iResult > 15) { + "i角计算结果:$formatAngle\"\n大于15\",请校正仪器" + } else { + "i角计算结果:$formatAngle\"\n合限" + } + } else { + saveIResult(null) + "i角计算结果:数据异常,请检查" + } + return hint + } + + /** + * 存短长距和测量方法 + * 这些变化快,统一存 + */ + private fun saveIResult(iResult: String?) { + viewModelScope.launch(Dispatchers.IO) { + val iDetectionItem = + LevelingDbFactory.instance.iDetectionListDataSource.getById(surveyorData.currentIDetectionId) + iDetectionItem.iResult = iResult + LevelingDbFactory.instance.iDetectionListDataSource.update(iDetectionItem) + } + } + + /** + * 存短长距和测量方法 + * 这些变化快,统一存 + */ + fun saveShortLongDistanceMeasureType(d1Short: String, d2Long: String) { + viewModelScope.launch(Dispatchers.IO) { + val iDetectionItem = + LevelingDbFactory.instance.iDetectionListDataSource.getById(surveyorData.currentIDetectionId) + iDetectionItem.shortDistance = d1Short + iDetectionItem.longDistance = d2Long + iDetectionItem.measureType = measureType + LevelingDbFactory.instance.iDetectionListDataSource.update(iDetectionItem) + } + } + + fun getGetDadaAuto(iDetectionId: String, callBack: (Boolean) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val record = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + iDetectionId + ) + withContext(Dispatchers.Main) { + if (record == null) { + callBack(true) + } else { + callBack(!record.getDataManually) + } + } + } + } + + fun setGetDataAuto(iDetectionId: String, auto: Boolean) { + viewModelScope.launch(Dispatchers.IO) { + var record = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + iDetectionId + ) + if (record == null) { + record = LevelIDetectionSetting(iDetectionId) + record.getDataManually = !auto + LevelingDbFactory.instance.iDetectionSettingDataSource.save(record) + } else { + record.getDataManually = !auto + LevelingDbFactory.instance.iDetectionSettingDataSource.update(record) + } + } + } + + @WorkerThread + fun updateStationSetting() { + stationSetting = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + surveyorData.currentIDetectionId + ) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/ILevelBackData.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/ILevelBackData.kt new file mode 100644 index 0000000..ade43ba --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/ILevelBackData.kt @@ -0,0 +1,8 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData + +interface ILevelBackData { + fun receive(data: LevelReceiveData) + fun measureError(msg: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequest.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequest.kt new file mode 100644 index 0000000..51978e5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequest.kt @@ -0,0 +1,85 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import blankj.utilcode.util.ToastUtils +import cn.liuyanbing.surveyor.function.level.sendreceive.LevelRequestState +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.controlnetwork.App + +abstract class LevelRequest(protected val backDataI: ILevelBackData) { + + private var requestTime = 0L + private var requestState = LevelRequestState.INIT + + private val receiveDataList = mutableListOf() + + abstract fun doRequest() + abstract fun onStart() + abstract fun onDestroy() + abstract fun sendCommand() + + + fun requeset() { + if (checkRequestNot()) { + return + } + requestState = LevelRequestState.REQUEST_ING + requestTime = System.currentTimeMillis() + + //获取数据 + doRequest() + } + + private fun checkRequestNot(): Boolean { + val intervalTime = System.currentTimeMillis() - requestTime +// if (intervalTime < 600) { +// return true +// } + if (requestState == LevelRequestState.REQUEST_ING) { + ToastUtils.showShort("测量中,请稍后...") + return true + } + + if (requestState == LevelRequestState.REQUEST_ING) { + if (intervalTime > 20000) { + //超过20秒回复默认状态 + requestState = LevelRequestState.INIT + } + } + return false + } + + protected fun resetInit() { + requestTime = 0 + requestState = LevelRequestState.INIT + } + + protected fun addReceiveData(data: LevelReceiveData) { + receiveDataList.add(data) + } + + protected fun clearReceiveDataList() { + receiveDataList.clear() + } + + protected fun isNeedRequestAgain(): Boolean { + val levelSurveyorTime = App.getApp().levelSurveyorTime.toInt() + return receiveDataList.size < levelSurveyorTime + } + + /** + * 获取返回的数据 + */ + protected fun getBackData(): LevelReceiveData { + var height = 0.0 + var distance = 0.0 + for (item in receiveDataList) { + height += item.height + distance += item.distance + } + val size = receiveDataList.size + return LevelReceiveData(height / size, distance / size) + } + + protected fun hasData() = receiveDataList.isNotEmpty() + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestRelease.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestRelease.kt new file mode 100644 index 0000000..c294fb7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestRelease.kt @@ -0,0 +1,60 @@ +package cn.liuyanbing.surveyor.function.level.sendreceive + +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.controlnetwork.func.level.sendreceive.ILevelBackData +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequest +import com.bingce.device.Device +import com.bingce.level.Level +import com.bingce.level.LevelListener + +/** + * 发布版 + */ +class LevelRequestRelease(backDataI: ILevelBackData) : LevelRequest(backDataI), + LevelListener.LevelReadListener { + + override fun doRequest() { + if (!Device.getInstance().isDeviceConnected) { + ToastUtils.showShort("设备未连接,请连接设备") + resetInit() + return + } + ToastUtils.showShort("开始测量") + sendCommand() + } + + override fun onStart() { + //LevelListener + LevelListener.getInstance().addLevelReadListener(this) + } + + override fun onDestroy() { + LevelListener.getInstance().removeLevelReadListener(this) + } + + override fun onReadSuccess(height: Double, distance: Double) { + addReceiveData(LevelReceiveData(height, distance)) + if (isNeedRequestAgain()) { + sendCommand() + return + } + if (hasData()) { + backDataI.receive(getBackData()) + } + clearReceiveDataList() + resetInit() + } + + override fun onReadFailed(errorCode: String?, errorMsg: String?, original: String?) { + val error = errorMsg ?: "" + backDataI.measureError(error) + clearReceiveDataList() + resetInit() + } + + override fun sendCommand() { + Level.getInstance().requestMeasure() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestState.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestState.kt new file mode 100644 index 0000000..47f4504 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestState.kt @@ -0,0 +1,8 @@ +package cn.liuyanbing.surveyor.function.level.sendreceive + +import androidx.annotation.Keep + +@Keep +enum class LevelRequestState { + INIT,REQUEST_ING +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestTest.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestTest.kt new file mode 100644 index 0000000..2e947a1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestTest.kt @@ -0,0 +1,175 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import android.content.res.AssetManager +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.util.Log +import blankj.utilcode.util.ToastUtils +import blankj.utilcode.util.Utils +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.controlapphelper.util.GsonUtil +import com.bingce.path.PathManager +import com.bingce.utils.FileUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import java.io.BufferedReader +import java.io.File +import java.io.IOException +import java.io.InputStreamReader +import java.nio.charset.StandardCharsets +import java.util.regex.Pattern + + +class LevelRequestTest(backDataI: ILevelBackData) : LevelRequest(backDataI) { + private var dataIndex = 0 + private var dataList = emptyList() + + private val handler = object : Handler(Looper.getMainLooper()) { + override fun handleMessage(msg: Message) { + val data = dataList[dataIndex] + addReceiveData(data) + if (isNeedRequestAgain()) { + dataIndex++ + sendCommand() + return + } + + if (hasData()) { + backDataI.receive(getBackData()) + } + + clearReceiveDataList() + resetInit() + } + } + + init { + GlobalScope.launch(Dispatchers.IO) { + dataList = TestData().getData() + } + } + + override fun doRequest() { + if (dataList.lastIndex < dataIndex) { + ToastUtils.showShort("没有数据了") + return + } + ToastUtils.showShort("开始测量") + sendCommand() + } + + override fun onStart() { + + } + + override fun onDestroy() { + + } + + override fun sendCommand() { + handler.sendEmptyMessageDelayed(0, 500) + } + + fun initTestData(position: Int) { + dataList = TestData().getData(position) + } + +} + +class TestData { + private val data11 = + "[{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0}]" + private val dataBFFBNormal = + "[{\"distance\":4.154,\"height\":2.42073},{\"distance\":4.905,\"height\":0.97681},{\"distance\":4.904,\"height\":0.97685},{\"distance\":4.157,\"height\":2.42074},{\"distance\":5.367,\"height\":0.91105},{\"distance\":6.041,\"height\":2.55628},{\"distance\":6.047,\"height\":2.55615},{\"distance\":5.371,\"height\":0.91101},{\"distance\":5.837,\"height\":2.45984},{\"distance\":5.553,\"height\":0.92191},{\"distance\":5.553,\"height\":0.92189},{\"distance\":5.837,\"height\":2.45978},{\"distance\":6.341,\"height\":0.85347},{\"distance\":6.85,\"height\":2.69778},{\"distance\":6.833,\"height\":2.69768},{\"distance\":6.345,\"height\":0.85337},{\"distance\":7.445,\"height\":2.66834},{\"distance\":7.025,\"height\":0.67221},{\"distance\":7.025,\"height\":0.67225},{\"distance\":7.44,\"height\":2.66833},{\"distance\":6.899,\"height\":0.69217},{\"distance\":7.812,\"height\":2.55316},{\"distance\":7.815,\"height\":2.55313},{\"distance\":6.9,\"height\":0.69219},{\"distance\":6.717,\"height\":2.53018},{\"distance\":6.31,\"height\":0.89984},{\"distance\":6.31,\"height\":0.89981},{\"distance\":6.72,\"height\":2.53014},{\"distance\":6.785,\"height\":0.75673},{\"distance\":7.375,\"height\":2.6826},{\"distance\":7.372,\"height\":2.68262},{\"distance\":6.79,\"height\":0.75672},{\"distance\":6.753,\"height\":2.55411},{\"distance\":7.238,\"height\":0.56473}]" + + private val dataBFFBError1 = + "[{\"distance\":4.154,\"height\":2.42073},{\"distance\":4.905,\"height\":0.97681},{\"distance\":5.904,\"height\":1.97685},{\"distance\":5.157,\"height\":3.42074},{\"distance\":5.367,\"height\":0.91105},{\"distance\":6.041,\"height\":2.55628},{\"distance\":6.047,\"height\":2.55615},{\"distance\":5.371,\"height\":0.91101},{\"distance\":5.837,\"height\":2.45984},{\"distance\":5.553,\"height\":0.92191},{\"distance\":5.553,\"height\":0.92189},{\"distance\":5.837,\"height\":2.45978},{\"distance\":6.341,\"height\":0.85347},{\"distance\":6.85,\"height\":2.69778},{\"distance\":6.833,\"height\":2.69768},{\"distance\":6.345,\"height\":0.85337},{\"distance\":7.445,\"height\":2.66834},{\"distance\":7.025,\"height\":0.67221},{\"distance\":7.025,\"height\":0.67225},{\"distance\":7.44,\"height\":2.66833},{\"distance\":6.899,\"height\":0.69217},{\"distance\":7.812,\"height\":2.55316},{\"distance\":7.815,\"height\":2.55313},{\"distance\":6.9,\"height\":0.69219},{\"distance\":6.717,\"height\":2.53018},{\"distance\":6.31,\"height\":0.89984},{\"distance\":6.31,\"height\":0.89981},{\"distance\":6.72,\"height\":2.53014},{\"distance\":6.785,\"height\":0.75673},{\"distance\":7.375,\"height\":2.6826},{\"distance\":7.372,\"height\":2.68262},{\"distance\":6.79,\"height\":0.75672},{\"distance\":6.753,\"height\":2.55411},{\"distance\":7.238,\"height\":0.56473}]" + + private val dataBFFBError2 = + "[{\"distance\":4.154,\"height\":2.42073},{\"distance\":14.905,\"height\":0.97681},{\"distance\":15.904,\"height\":0.97685},{\"distance\":5.157,\"height\":3.42074},{\"distance\":5.367,\"height\":0.91105},{\"distance\":6.041,\"height\":2.55628},{\"distance\":6.047,\"height\":2.55615},{\"distance\":5.371,\"height\":0.91101},{\"distance\":5.837,\"height\":2.45984},{\"distance\":5.553,\"height\":0.92191},{\"distance\":5.553,\"height\":0.92189},{\"distance\":5.837,\"height\":2.45978},{\"distance\":6.341,\"height\":0.85347},{\"distance\":6.85,\"height\":2.69778},{\"distance\":6.833,\"height\":2.69768},{\"distance\":6.345,\"height\":0.85337},{\"distance\":7.445,\"height\":2.66834},{\"distance\":7.025,\"height\":0.67221},{\"distance\":7.025,\"height\":0.67225},{\"distance\":7.44,\"height\":2.66833},{\"distance\":6.899,\"height\":0.69217},{\"distance\":7.812,\"height\":2.55316},{\"distance\":7.815,\"height\":2.55313},{\"distance\":6.9,\"height\":0.69219},{\"distance\":6.717,\"height\":2.53018},{\"distance\":6.31,\"height\":0.89984},{\"distance\":6.31,\"height\":0.89981},{\"distance\":6.72,\"height\":2.53014},{\"distance\":6.785,\"height\":0.75673},{\"distance\":7.375,\"height\":2.6826},{\"distance\":7.372,\"height\":2.68262},{\"distance\":6.79,\"height\":0.75672},{\"distance\":6.753,\"height\":2.55411},{\"distance\":7.238,\"height\":0.56473}]" + + private val dataBFFBError3 = + "[{\"distance\":4.154,\"height\":2.42073},{\"distance\":4.905,\"height\":0.97681},{\"distance\":4.904,\"height\":0.97685},{\"distance\":4.157,\"height\":2.42074},{\"distance\":4.154,\"height\":2.42073},{\"distance\":4.905,\"height\":0.97681},{\"distance\":4.904,\"height\":0.97685},{\"distance\":4.157,\"height\":2.42074}]" + + companion object { + val textShowList = listOf( + "11数据", + "BFFB", + "BFFB异常数据1", + "BFFB异常数据-前后视距差", + "BFFB异常数据-转角差" + ) + } + + fun getData(): List { + return GsonUtil.toAny>(dataBFFBNormal) ?: emptyList() + } + + fun getData(position: Int): List { + return when (position) { + 0 -> GsonUtil.toAny>(data11) ?: emptyList() + 1 -> GsonUtil.toAny>(dataBFFBNormal) ?: emptyList() + 2 -> GsonUtil.toAny>(dataBFFBError1) ?: emptyList() + 3 -> GsonUtil.toAny>(dataBFFBError2) ?: emptyList() + 4 -> GsonUtil.toAny>(dataBFFBError3) ?: emptyList() + else -> emptyList() + } + } + + fun test() { + val processFile = processFile("test666.DAT") + val toJson = GsonUtil.toJson(processFile) + FileUtil.writeString(toJson, File(PathManager.appDocumentFolder(), "test.json")) + Log.d("hwhw", "hwhwhw写入成功") + } + + private fun loadJsonFromAsset(fileName: String): String? { + val json: String = try { + val manager: AssetManager = Utils.getApp().assets + val `is` = manager.open(fileName) + val size = `is`.available() + val buffer = ByteArray(size) + `is`.read(buffer) + `is`.close() + String(buffer, StandardCharsets.UTF_8) + } catch (e: IOException) { + e.printStackTrace() + return null + } + return json + } + + private fun processFile(fileName: String): List { + val result = mutableListOf() + try { + val assetManager: AssetManager = Utils.getApp().assets + val inputStream = assetManager.open(fileName) + val reader = BufferedReader(InputStreamReader(inputStream)) + var line = "" + + // 定义正则表达式 + val regex = "(Rf|Rb)\\s+([\\d.]+)\\s+m" + val regex2 = "HD\\s+([\\d.]+)\\s+m" + val pattern1 = Pattern.compile(regex) + val pattern2 = Pattern.compile(regex2) + + while (reader.readLine()?.also { line = it } != null && !line.contains("#")) { + val matcher = pattern1.matcher(line) + val matcher2 = pattern2.matcher(line) + + if (matcher.find() && matcher2.find()) { + val height = matcher.group(2)?.toDouble() ?: 0.0 + val distance = matcher2.group(1)?.toDouble() ?: 0.0 + result.add(LevelReceiveData(height, distance)) + } + } + inputStream.close() + } catch (e: IOException) { + e.printStackTrace() + } + return result + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelDateUtil.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelDateUtil.java new file mode 100644 index 0000000..f03cb0d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelDateUtil.java @@ -0,0 +1,84 @@ +package com.bingce.controlnetwork.func.level.util; + +import com.bingce.controlnetwork.func.level.util.suntime.SunTimes; + +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.LocalTime; +import java.time.ZonedDateTime; +import java.util.Date; + + + +public class LevelDateUtil { + /** + * 34.757975, 113.665412 + * + * @param lat + * @param lng + */ + public static String getLevelOperateSunTimeHint(double lat, double lng) { + ZonedDateTime now = ZonedDateTime.now(); + SunTimes times = SunTimes.compute() + .on(now.with(LocalTime.MIN)) // set a date + .at(lat, lng) // set a location + .execute(); // get the results + + ZonedDateTime rise = times.getRise(); + ZonedDateTime set = times.getSet(); + if (rise == null || set == null) { + //未计算出日出和日落时间 + return null; + } + // 计算日中时间 + ZonedDateTime noon = rise.plus(Duration.between(rise, set).dividedBy(2)); + + // 计算前后两个小时的时间窗口 + ZonedDateTime startWindow = noon.minusHours(2); + ZonedDateTime endWindow = noon.plusHours(2); + + ZonedDateTime riseAfter2 = rise.plusMinutes(30); + ZonedDateTime setBefore2 = set.minusMinutes(30); + + boolean isWithinTwoHoursOfNoon = !now.isBefore(startWindow) && !now.isAfter(endWindow); + + if (now.isBefore(riseAfter2)) { + //当前时间在日出前2小时内 + return "请在日出后30分钟进行作业"; + } + + if (now.isAfter(setBefore2)) { + //当前时间在日落后2小时 + return "请在日落前30分钟进行作业"; + } + + // 输出结果 + if (isWithinTwoHoursOfNoon) { + //当前时间在日中前后2小时内 + return "请勿在日中前后2小时内进行作业"; + } + + return null; + } + + public static String dateToYearMonthDayHourMin(Date date) { + SimpleDateFormat simple = new SimpleDateFormat("yyyy年MM月dd日HH:mm"); + return simple.format(date); + } + + public static String getLevelHeadDateYearMonthDay(Date date) { + SimpleDateFormat simple = new SimpleDateFormat("yyyy年MM月dd日"); + return simple.format(date); + } + + public static String getLevelHeadDateHourMin(Date date) { + SimpleDateFormat simple = new SimpleDateFormat("HH:mm"); + return simple.format(date); + } + + public static String getHourMinSec(Date date) { + SimpleDateFormat simple = new SimpleDateFormat("HH:mm:ss"); + return simple.format(date); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelExportUtilTj.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelExportUtilTj.kt new file mode 100644 index 0000000..63706ff --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelExportUtilTj.kt @@ -0,0 +1,704 @@ +package com.bingce.controlnetwork.func.level.util + +import android.text.TextUtils +import androidx.annotation.WorkerThread +import blankj.utilcode.util.Utils + +import cn.liuyanbing.surveyor.function.level.export.LevelExportIDetection +import com.bingce.controlnetwork.func.level.export.LevelExportSingalHeight +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.measure.backfront.LevelingMeasureBackFrontRecord +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil +import com.bingce.controlapphelper.model.LevelExportLine +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil +import com.bingce.controlapphelper.model.LevelingStationState +import com.bingce.controlapphelper.model._N +import com.bingce.controlapphelper.surveyor.method.ExportStationMethod +import com.bingce.controlapphelper.surveyor.method.ExportUtils +import com.bingce.controlapphelper.util.DateUtil +import com.bingce.utils.DateUtils +import com.bingce.utils.Util +import java.io.File + + +class LevelExportUtilTj { + + companion object { + const val EXPORT_LEVEL_FOLDER = "Leveling" + + //导出的外层目录 + val exportOutFolder = File(Utils.getApp().externalCacheDir, EXPORT_LEVEL_FOLDER) + } + + private lateinit var exportRouteFolder: File + private lateinit var exportProjectFolder: File + + private var column1Index = 0 + + private var startPointHeight = 0.0 + private var startPointName = "" + private var endPointName = "" + + + private val printSbLev = StringBuilder() + + /** + * 导出路线文件夹下的数据 + */ + @WorkerThread + fun doExportRouteData(projectId: String, routeId: String) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + ?: throw IllegalArgumentException("routeRecord==null") + //路线的基础数据 + confirmRouteCommonData(routeRecord) + //收集路线的具体数据 + collectRouteLevData(projectId, routeRecord) + } + + private fun confirmRouteCommonData(it: LevelRouteRecord) { + val startPoint = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(it.startPointId) + startPointHeight = getPointHeight(startPoint) + startPointName = getPointName(startPoint) + val endPoint = SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(it.endPointId) + endPointName = getPointName(endPoint) + } + + private fun collectRouteLevData(projectId: String, it: LevelRouteRecord) { + val routeId = it.getId() + val routeName = it.routeName + val levelingMeasureOrder = it.levelingMeasureOrder + val isHasTwiceStation = when (levelingMeasureOrder) { + LevelingMeasureOrder.SIM_BF, + LevelingMeasureOrder.SIM_BFFB -> { + true + } + + else -> false + } + + collectRouteLevDataLeftOrRight( + projectId, + routeId, + false, + levelingMeasureOrder + ) + if (isHasTwiceStation) { + collectRouteLevDataLeftOrRight( + projectId, + routeId, + true, + levelingMeasureOrder + ) + } + + if (printSbLev.isNotEmpty()) { + initExportFile(projectId, routeName) + if (::exportRouteFolder.isInitialized) { + saveRouteLevFile(exportRouteFolder, routeName) + saveRouteTxtFile(exportRouteFolder, routeId, routeName) + saveRouteInfoFile(exportRouteFolder, projectId, routeId, routeName) + } + } + } + + /** + * INF 观测记录 + */ + private fun saveRouteInfoFile( + exportFolder: File, + projectId: String, + routeId: String, + routeName: String + ) { + val projectRecord = SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId)!! + val toleranceTetail = + LevelingDbFactory.instance.toleranceDetailDataSource.getRecordSync(projectRecord.toleranceId) + + val startPointNameRoute = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord.startPointId) + .getName() + val endPointNameRoute = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord.endPointId) + .getName() + + //作业单位 + val measureUnit = projectRecord.measureUnit ?: "" + //限差等级 + val exportGrade = toleranceTetail.exportGrade + + //测站数量 单程双转的按照twiceStaion false处理 + val stationCount = + LevelingDbFactory.instance.stationDataSource.getCountByRoute(projectId, routeId, false) + + val stationListLeft = + LevelingDbFactory.instance.stationDataSource.getStationList(projectId, routeId, false) + val stationListRight = + LevelingDbFactory.instance.stationDataSource.getStationList(projectId, routeId, true) + + val remeasureCountAll = + getRemeasureCount(stationListLeft) + getRemeasureCount(stationListRight) + + //8,9,10行 + val routeDistanceHeightInfo = + getRouteDistanceHeightInfo( + stationListLeft?.lastOrNull(), + stationListRight?.lastOrNull() + ) + + val record = LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + record?.let { + val sb = StringBuilder() + //第一行 + sb.append(measureUnit).append(",") + sb.append(exportToString(it.watcher)).append(",") + sb.append(exportToString(it.recorder)).append(",") + sb.append(exportToString(it.examiner)).append("\n") + //第二行 + sb.append(exportGrade).append(",") + sb.append("").append(",")//观测方法:自动采集法 + sb.append(routeRecord.observationDirection).append(",") + sb.append(stationCount).append(",")//测站数 + sb.append(remeasureCountAll).append("\n")//重测数 + //第三行 + sb.append(exportToString(it.instrumentModel)).append(",") + sb.append("No.${exportToString(it.deviceNumber)}").append(",") + sb.append("").append(",")//测微读数精度 + sb.append("").append(",")//视距乘常数 + sb.append("").append("\n")//视距加常数 + //第四行 + sb.append(exportToString(it.rulerType)).append(",") + sb.append("").append(",")//标尺分划 + sb.append(exportToString(it.rulerReceptType)).append("\n")//尺承类型 + //第五行 + sb.append(startPointNameRoute).append(",")//起点 + sb.append(endPointNameRoute).append("\n")//终点 + //第六行 + sb.append(exportToString(it.firstStationBackFootNumber)).append(",") + sb.append(exportToString(it.firstStationFrontFootNumber)).append("\n") + //第七行 + sb.append(exportToString(it.firstStationBackFootNumber2)).append(",") + sb.append(exportToString(it.firstStationFrontFootNumber2)).append("\n") + //第八行 + sb.append(routeDistanceHeightInfo) + + ExportStationMethod.save(sb.toString(), exportFolder, "${routeName}.INF") + } + } + + /** + * INFO文件里的距离和高差 + */ + private fun getRouteDistanceHeightInfo( + leftEndStation: LevelingStationRecord?, + rightEndStation: LevelingStationRecord? + ): String { + val sb = StringBuilder() + if (leftEndStation == null && rightEndStation == null) { + sb.append("").append(",").append("").append(",").append("").append(",").append("") + .append("\n") + .append(",").append("\n") + .append("").append("\n") + .append("").append("\n") + return sb.toString() + } + + val left = + LevelingDbFactory.instance.measureStationDataSource.getRecordSync(leftEndStation?.getId()) + val right = + LevelingDbFactory.instance.measureStationDataSource.getRecordSync(rightEndStation?.getId()) + + val distanceTotalLeft = formatDistance(left?.distanceTotal) + val heightDiffTotalLeft = formatDistance(left?.heightDiffTotal) + val distanceTotalRight = formatDistance(right?.distanceTotal) + val heightDiffTotalRight = formatDistance(right?.heightDiffTotal) + + val heightAverage = if (left?.heightDiffTotal != null && right?.heightDiffTotal != null) { + formatDistance((left.heightDiffTotal + right.heightDiffTotal) / 2) + } else if (left?.heightDiffTotal != null) { + formatDistance(left.heightDiffTotal) + } else { + "" + } + + //测段不符值 右-左 + val rightLeftHeightDiff = + if (left?.heightDiffTotal != null && right?.heightDiffTotal != null) { + formatDistance(right.heightDiffTotal - left.heightDiffTotal) + } else { + "0" + } + + sb.append(distanceTotalLeft).append(",").append(heightDiffTotalLeft).append(",") + .append(distanceTotalRight).append(",").append(heightDiffTotalRight).append("\n") + //第二行 + .append(heightAverage).append("\n") + //第三行 + .append(rightLeftHeightDiff).append("\n") + + return sb.toString() + } + + private fun formatDistance(value: Double?): String { + if (value == null) { + return "" + } + return ExportUtils.formatDistance(value) + } + + private fun exportToString(value: String?) = value ?: "" + + /** + * 通过测站列表获取重测数量 + */ + @WorkerThread + private fun getRemeasureCount(stationList: List): Int { + var count = 0 + for (station in stationList) { + val remeasureCountByStationId = + LevelingDbFactory.instance.measureBackFrontDataSource.getRemeasureCountByStationId( + station.getId() + ) + count += remeasureCountByStationId + } + return count + } + + /** + * TXT 观测条件 + */ + private fun saveRouteTxtFile(exportFolder: File, routeId: String, routeName: String) { +// //起点,终点,照准次序,测站数量,路线总长度(km),路线总高差 +// val routeRecord = TjDbFactory.instance.routeDataSource.getByIdSync(routeId) ?: return +// val startPointName = +// TjDbFactory.instance.pointDataSource.findByIdSync(routeRecord.startPointId).name +// val endPointName = +// TjDbFactory.instance.pointDataSource.findByIdSync(routeRecord.endPointId).name +// val orderText = +// LevelingMeasureOrderUtil.getTextByLevelingMeasureOrder(routeRecord.levelingMeasureOrder) +// +// val stationCount = LevelingDbFactory.instance.stationDataSource.getCountByRoute( +// routeRecord.projectId, +// routeId, +// false +// ) +// +// val stationLatest = LevelingDbFactory.instance.stationDataSource.getStationLatest( +// routeRecord.projectId, +// routeId +// ) +// +// val measureStationList = mutableListOf() +// val measureStationRecordLast = +// LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationLatest.getId()) +// if (stationLatest.twiceStation) { +// val measureStationRecordLeft = +// LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationLatest.lastStationId) +// measureStationList.add(measureStationRecordLeft) +// measureStationList.add(measureStationRecordLast) +// } else { +// measureStationList.add(measureStationRecordLast) +// } +// +// val sb = StringBuilder() +// for (item in measureStationList) { +// sb.append(startPointName).append(",") +// sb.append(endPointName).append(",") +// sb.append(orderText).append(",") +// sb.append(stationCount).append(",") +// +// sb.append(ExportUtilsTj.formatDistance(item.distanceTotal)).append(",") +// sb.append(ExportUtilsTj.formatDistance(item.heightDiffTotal)) +// sb.append("\n") +// } + + //观测条件list + val observationConditionList = + LevelingDbFactory.instance.stationSettingDataSource.getByRouteId(routeId) + + val sb = StringBuilder() + for (item in observationConditionList) { + val station = + LevelingDbFactory.instance.stationDataSource.getRecordSync(item.stationId) + val stationNum = station.stationName.replace("测站", "") + + //第一行 + sb.append(stationNum).append(",") + .append(LevelDateUtil.dateToYearMonthDayHourMin(item.createDate)).append("\n") + //第二行 + sb.append(exportToString(item.temperature)).append(",") + .append(exportToString(item.sunDirection)).append(",") + .append(exportToString(item.imaging)).append(",") + .append(exportToString(item.weather)).append("\n") + //第三行 + sb.append(exportToString(item.windDirection)).append(",") + .append(exportToString(item.windSpeed)).append(",") + .append(exportToString(item.roads)).append(",") + .append(exportToString(item.soil)).append("\n") + } + + ExportStationMethod.save(sb.toString(), exportFolder, "${routeName}.TXT") + } + + private fun removeLastBuilder(sb: StringBuilder) { + if (sb.isNotEmpty()) { + sb.deleteCharAt(sb.lastIndex) + } + } + + private fun saveRouteLevFile(exportFolder: File, routeName: String) { + ExportStationMethod.save(printSbLev.toString(), exportFolder, "${routeName}.LEV") + } + + private fun initExportFile(projectId: String, routeName: String) { + exportProjectFolder = initExportProjectFolder(projectId) + confirmRouteFolder(exportProjectFolder, routeName) + } + + private fun initExportProjectFolder(projectId: String): File { + val exportFolder = File(Utils.getApp().externalCacheDir, EXPORT_LEVEL_FOLDER) + if (!exportFolder.exists()) { + exportFolder.mkdirs() + } + val projectName = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId).projectName + val projectFolder = File(exportFolder, projectName) + if (!projectFolder.exists()) { + projectFolder.mkdir() + } + return projectFolder + } + + /** + * 重名项目或路线文件夹增加_1 + */ + private fun confirmRouteFolder(exportProjectFolder: File, name: String) { + val exportFolderTarget = File(exportProjectFolder, name) + if (!exportFolderTarget.exists()) { + exportFolderTarget.mkdir() + this.exportRouteFolder = exportFolderTarget + return + } + confirmRouteFolder(exportProjectFolder, name + "_1") + } + + /** + * 收集左线或者右线的数据 + */ + private fun collectRouteLevDataLeftOrRight( + projectId: String, + routeId: String, + twiceStation: Boolean, + levelingMeasureOrder: LevelingMeasureOrder + ) { + val orderText = + LevelingMeasureOrderUtil.getTextByLevelingMeasureOrder(levelingMeasureOrder) + + val stationList = LevelingDbFactory.instance.stationDataSource.getStationList( + projectId, + routeId, + twiceStation + ) + + var finishIndex = 0 + for ((index, station) in stationList.withIndex()) { + if (station.stationState != LevelingStationState.FINISH) + break + + if (index == 0) { + appendStartOrEndLine("Start-Line", orderText) + appendRouteStationHead(routeId, station) + appendZ(station.backSightPointId, startPointHeight) + } + + //测量数据 + appendMeasureData(station) + finishIndex = index + column1Index++ + } + + //最后完成测站 + val lastFinishStation = stationList[finishIndex] + val stationHeightDiffTotal = getStationHeightDiffTotal(lastFinishStation) + + //结束点高程 + appendZ( + lastFinishStation.frontSightPointId, + getFrontPointZ(stationHeightDiffTotal) + ) + column1Index++ + //end-line + appendStartOrEndLine("End-Line", "") + } + + private fun getStationHeightDiffTotal(stationRecord: LevelingStationRecord): Double { + //当前站的累积高差 + return LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationRecord.getId()).heightDiffTotal + } + + private fun getFrontPointZ(heightDiffTotal: Double) = startPointHeight + heightDiffTotal + + private fun appendStartOrEndLine(startOrEndLine: String, column2Name3: String) { + val dataFirstLine = LevelExportLine( + LevelExportLine.Column1(column1Index), + LevelExportLine.Column2("TO", startOrEndLine, column2Name3), + LevelExportLine.ColumnHeight("", ""), + LevelExportLine.ColumnDistance(""), + LevelExportLine.ColumnEnd(null, null) + ).getData() + printSbLev.append(dataFirstLine).append(_N) + + column1Index++ + } + + /** + * 路线的首站头 + * 起点,终点等 + */ + private fun appendRouteStationHead(routeId: String, station: LevelingStationRecord) { + val stationSetting = LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + + val measureDataList = + LevelingDbFactory.instance.measureBackFrontDataSource.getMeasureDataList(station.getId()) + val firstRecordDate = measureDataList.first().createDate + val endRecordDate = measureDataList.last().createDate + + val levelHeadDateYearMonthDay = + LevelDateUtil.getLevelHeadDateYearMonthDay(firstRecordDate) + val startHourMin = LevelDateUtil.getLevelHeadDateHourMin(firstRecordDate) + val endHourMin = LevelDateUtil.getLevelHeadDateHourMin(endRecordDate) + + val line1 = getRouteStationHeadLine("startName", startPointName) + printSbLev.append(line1).append(_N) + val line2 = getRouteStationHeadLine("endName", endPointName) + printSbLev.append(line2).append(_N) + val line3 = getRouteStationHeadLine("observationDate", levelHeadDateYearMonthDay) + printSbLev.append(line3).append(_N) + val line4 = getRouteStationHeadLine("observationStartTime", startHourMin) + printSbLev.append(line4).append(_N) + val line5 = getRouteStationHeadLine("observationEndTime", endHourMin) + printSbLev.append(line5).append(_N) + val line6 = getRouteStationHeadLine("weather", stationSetting.weather ?: "") + printSbLev.append(line6).append(_N) + val line7 = getRouteStationHeadLine("imaging", stationSetting.imaging ?: "") + printSbLev.append(line7).append(_N) + + column1Index++ + } + + private fun getRouteStationHeadLine(key: String, value: String): String { + return LevelExportLine( + LevelExportLine.Column1(column1Index), + LevelExportLine.Column2("INF", "", ""), + LevelExportLine.ColumnHeight(key, ""), + LevelExportLine.ColumnDistance(""), + LevelExportLine.ColumnEnd(value, "") + ).getData() + } + + /** + * 测量数据 + */ + private fun appendMeasureData(station: LevelingStationRecord) { + val measureDataList = + LevelingDbFactory.instance.measureBackFrontDataSource.getMeasureDataList(station.getId()) + + val stationHeightDiffTotal = getStationHeightDiffTotal(station) + + val backDataList = mutableListOf() + val frontDataList = mutableListOf() + + for ((index, record) in measureDataList.withIndex()) { + val point = getPoint(record.measurePointId) + val pointName = getPointName(point) + + var rbOrRf: String + if (record.measurePointId == station.backSightPointId) { + rbOrRf = "Rb" + backDataList.add(record) + } else { + rbOrRf = "Rf" + frontDataList.add(record) + } + + val time = DateUtil.formatDateHHmmss(record.createDate) + + val line = LevelExportLine( + LevelExportLine.Column1(column1Index), + LevelExportLine.Column2("KD1", pointName, time), + LevelExportLine.ColumnHeight(rbOrRf, "${record.measureHeightShow} m"), + LevelExportLine.ColumnDistance(record.measureDistanceShow), + LevelExportLine.ColumnEnd(null, null) + ).getData() + printSbLev.append(line).append(_N) + + //最后再增加一行 + if (index == measureDataList.lastIndex) { + //每一站的结果 + column1Index++ + appendZ(point.getId(), getFrontPointZ(stationHeightDiffTotal)) + } + + column1Index++ + } + } + + private fun getPointHeight(point: PointRecord?): Double { + return point?.getZ() ?: 0.0 + } + + private fun getPointName(point: PointRecord?): String { + return point?.getName() ?: "" + } + + private fun getPoint(pointId: String): PointRecord { + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId) + } + + private fun appendZ(pointId: String, height: Double) { + val startPoint = getPoint(pointId) + val z = LevelFormatUtil.formatHeight(height) + val dataSecondLine = LevelExportLine( + LevelExportLine.Column1(column1Index), + LevelExportLine.Column2("KD1", getPointName(startPoint), ""), + LevelExportLine.ColumnHeight("", ""), + LevelExportLine.ColumnDistance(""), + LevelExportLine.ColumnEnd("Z", "$z m") + ).getData() + printSbLev.append(dataSecondLine).append(_N) + column1Index++ + } + + + data class CalTotal(var heightDiffTotal: Double = 0.0, var distanceTotal: Double = 0.0) { + fun addHeightDiffTotal(heightDiffTotal: Double) { + this.heightDiffTotal += heightDiffTotal + } + + fun addDistanceTotal(distanceTotal: Double) { + this.distanceTotal += distanceTotal + } + } + + @WorkerThread + fun exportProjectTxt(projectId: String) { + val projectFolder = initExportProjectFolder(projectId) + val projectRecord = SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + + val text = projectRecord.projectName + + "," + + "" + + "," + + "," + + "," + + "," + + "," + + "," + + "," + + (if (projectRecord == null) "" else projectRecord.getMeasureUnit()) + + "," + + (if (projectRecord == null) "" else DateUtils.toDate(projectRecord.getCreateDate())) + + "\n" + ExportStationMethod.save( + text, + projectFolder, + "project.TXT" + ) + } + + fun exportControlTxt(projectId: String) { + val projectFolder = initExportProjectFolder(projectId) + val knownList = SurveyorDatabaseFactory.instance.pointDataSource.getListByProjectId( + projectId, + PointRecord.TYPE_KNOWN_POINT + ) + val unknownList = SurveyorDatabaseFactory.instance.pointDataSource.getListByProjectId( + projectId, + PointRecord.TYPE_UNKNOWN_POINT + ) + + val stringBuilder = StringBuilder() + appendExportPoint(stringBuilder, knownList) + appendExportPoint(stringBuilder, unknownList) + + ExportStationMethod.save( + stringBuilder.toString(), + projectFolder, + "controlpoint.TXT" + ) + } + + private fun appendExportPoint(sb: StringBuilder, list: List) { + for (pointRecord in list) { + sb + .append(pointRecord.getName()) + .append(",") + .append(pointRecord.getCode()) + .append(",") + .append(getXyzFormat(pointRecord.getX())) + .append(",") + .append(getXyzFormat(pointRecord.getY())) + .append(",") + .append(getXyzFormat(pointRecord.getZ())) + .append(",") +// .append(pointRecord.getLongitude()) + .append(",") +// .append(pointRecord.getLatitude()) + .append(",") + .append("") + .append("\n") + } + } + + private fun getXyzFormat(xyz: Double): String { + return Util.formatDouble2String(xyz, 4) + } + + /** + * 导出i角检测 + */ + @WorkerThread + fun exportIDetection(projectId: String) { + val projectName = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId).projectName + + val iDetectionList = + LevelingDbFactory.instance.iDetectionListDataSource.getListByProjectIdDesc(projectId) + + val sb = StringBuilder() + val levelExportIDetection = LevelExportIDetection() + for (iDetection in iDetectionList) { + val export = levelExportIDetection.export(iDetection) + if (!TextUtils.isEmpty(export)) { + sb.append(export) + } + } + + if (sb.isNotEmpty()) { + val projectFolder = initExportProjectFolder(projectId) + ExportStationMethod.save( + sb.toString(), + projectFolder, + "$projectName.IAC" + ) + } + } + + + /** + * 导出 + */ + fun exportTjSingalHeight(projectId: String) { + val levelExportSingalHeight = LevelExportSingalHeight() + val projectFolder = initExportProjectFolder(projectId) + levelExportSingalHeight.export(projectFolder, projectId) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelPointUtilTj.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelPointUtilTj.kt new file mode 100644 index 0000000..a1fabcb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelPointUtilTj.kt @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.func.level.util + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.util.RegExUtil + +object LevelPointUtilTj { + @WorkerThread + @JvmStatic + fun createFrontPointByBackPointId( + routeId: String, + backPointId: String, + firstStaion: Boolean = false, + endStattion: Boolean = false, + ): PointRecord { + val frontPoint = if (endStattion) { + val route = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(route?.endPointId) + } else if (firstStaion) { + createHidePoint("1") + } else { + val backPoint = SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(backPointId) + val frontPointName = RegExUtil.getPointNameIncrease(backPoint.getName()) + createHidePoint(frontPointName) + } + return frontPoint + } + + private fun createHidePoint(pointName: String): PointRecord { + val point = PointRecord.createHidePoint(pointName) + //存点 + SurveyorDatabaseFactory.instance.pointDataSource.saveSync(point) + return point + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingLastData.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingLastData.kt new file mode 100644 index 0000000..5eec352 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingLastData.kt @@ -0,0 +1,271 @@ +package com.bingce.controlnetwork.func.level.util + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory + +/** + * 水准测站设置上次值 + */ +object LevelStationSettingLastData { + + private const val KEY_WATCHER = "LEVEL_STATION_SETTING_LAST_DATA_WATCHER" + private const val KEY_RECORDER = "LEVEL_STATION_SETTING_LAST_DATA_RECORDER" + private const val KEY_EXAMINER = "LEVEL_STATION_SETTING_LAST_DATA_EXAMINER" + private const val KEY_FRONT_FOOT_NUMBER = "LEVEL_STATION_SETTING_LAST_DATA_FRONT_FOOT_NUMBER" + private const val KEY_BACK_FOOT_NUMBER = "LEVEL_STATION_SETTING_LAST_DATA_BACK_FOOT_NUMBER" + private const val KEY_FRONT_FOOT_NUMBER_2 = + "LEVEL_STATION_SETTING_LAST_DATA_FRONT_FOOT_NUMBER_2" + private const val KEY_BACK_FOOT_NUMBER_2 = "LEVEL_STATION_SETTING_LAST_DATA_BACK_FOOT_NUMBER_2" + private const val KEY_INSTRUMENT_MODEL = "LEVEL_STATION_SETTING_LAST_DATA_INSTRUMENT_MODEL" + private const val KEY_DEVICE_NUMBER = "LEVEL_STATION_SETTING_LAST_DATA_DEVICE_NUMBER" + private const val KEY_STEEL_RULE_PARAM = "LEVEL_STATION_SETTING_LAST_DATA_STEEL_RULE_PARAM" + private const val KEY_RULER_LENGTH_PROVING_TEMPERATURE = + "LEVEL_STATION_SETTING_LAST_DATA_RULER_LENGTH_PROVING_TEMPERATURE" + private const val KEY_TEMPERATURE = "LEVEL_STATION_SETTING_LAST_DATA_TEMPERATURE" + private const val KEY_WEATHER = "LEVEL_STATION_SETTING_LAST_DATA_WEATHER" + private const val KEY_IMAGING = "LEVEL_STATION_SETTING_LAST_DATA_IMAGING" + private const val KEY_SUN_DIRECTION = "LEVEL_STATION_SETTING_LAST_DATA_SUN_DIRECTION" + private const val KEY_WIND_DIRECTION = "LEVEL_STATION_SETTING_LAST_DATA_WIND_DIRECTION" + private const val KEY_WIND_SPEED = "LEVEL_STATION_SETTING_LAST_DATA_WIND_SPEED" + private const val KEY_ROADS = "LEVEL_STATION_SETTING_LAST_DATA_ROADS" + private const val KEY_SOIL = "LEVEL_STATION_SETTING_LAST_DATA_SOIL" + private const val KEY_RULER_TYPE = "LEVEL_STATION_SETTING_LAST_DATA_RULER_TYPE" + private const val KEY_RULER_RECEPT_TYPE = "LEVEL_STATION_SETTING_LAST_DATA_RULER_RECEPT_TYPE" + private const val KEY_RULER_CORRECTION_FACTOR = + "LEVEL_STATION_SETTING_LAST_DATA_RULER_CORRECTION_FACTOR" + + @WorkerThread + fun getExaminer(): String? { + return get(KEY_EXAMINER) + } + + @WorkerThread + fun setExaminer(examiner: String?) { + save(KEY_EXAMINER, examiner) + } + + @WorkerThread + fun getRecorder(): String? { + return get(KEY_RECORDER) + } + + @WorkerThread + fun setRecorder(recorder: String?) { + save(KEY_RECORDER, recorder) + } + + @WorkerThread + fun getWatcher(): String? { + return get(KEY_WATCHER) + } + + @WorkerThread + fun setWatcher(watcher: String?) { + save(KEY_WATCHER, watcher) + } + + @WorkerThread + fun getFrontFootNumber(): String? { + return get(KEY_FRONT_FOOT_NUMBER) + } + + @WorkerThread + fun setFrontFootNumber(watcher: String?) { + save(KEY_FRONT_FOOT_NUMBER, watcher) + } + + @WorkerThread + fun getFrontFootNumber2(): String? { + return get(KEY_FRONT_FOOT_NUMBER_2) + } + + @WorkerThread + fun setFrontFootNumber2(watcher: String?) { + save(KEY_FRONT_FOOT_NUMBER_2, watcher) + } + + @WorkerThread + fun getBackFootNumber(): String? { + return get(KEY_BACK_FOOT_NUMBER) + } + + @WorkerThread + fun setBackFootNumber(watcher: String?) { + save(KEY_BACK_FOOT_NUMBER, watcher) + } + + @WorkerThread + fun getBackFootNumber2(): String? { + return get(KEY_BACK_FOOT_NUMBER_2) + } + + @WorkerThread + fun setBackFootNumber2(watcher: String?) { + save(KEY_BACK_FOOT_NUMBER_2, watcher) + } + + @WorkerThread + fun getInstrumentModel(): String? { + return get(KEY_INSTRUMENT_MODEL) + } + + @WorkerThread + fun setInstrumentModel(watcher: String?) { + save(KEY_INSTRUMENT_MODEL, watcher) + } + + @WorkerThread + fun getDeviceNumber(): String? { + return get(KEY_DEVICE_NUMBER) + } + + @WorkerThread + fun setDeviceNumber(watcher: String?) { + save(KEY_DEVICE_NUMBER, watcher) + } + + @WorkerThread + fun getSteelRuleParam(): String? { + return get(KEY_STEEL_RULE_PARAM) + } + + @WorkerThread + fun setTemperature(watcher: String?) { + save(KEY_TEMPERATURE, watcher) + } + + @WorkerThread + fun getTemperature(): String? { + return get(KEY_TEMPERATURE) + } + + @WorkerThread + fun setWeather(watcher: String?) { + save(KEY_WEATHER, watcher) + } + + @WorkerThread + fun getWeather(): String? { + return get(KEY_WEATHER) + } + + @WorkerThread + fun setImaging(watcher: String?) { + save(KEY_IMAGING, watcher) + } + + @WorkerThread + fun getImaging(): String? { + return get(KEY_IMAGING) + } + + + ///////////// + @WorkerThread + fun setSteelRuleParam(watcher: String?) { + save(KEY_STEEL_RULE_PARAM, watcher) + } + + @WorkerThread + fun getRulerLengthProvingTemperature(): String? { + return get(KEY_RULER_LENGTH_PROVING_TEMPERATURE) + } + + @WorkerThread + fun setRulerLengthProvingTemperature(watcher: String?) { + save(KEY_RULER_LENGTH_PROVING_TEMPERATURE, watcher) + } + + @WorkerThread + fun getSunDirection(): String? { + return get(KEY_SUN_DIRECTION) + } + + @WorkerThread + fun setSunDirection(watcher: String?) { + save(KEY_SUN_DIRECTION, watcher) + } + + @WorkerThread + fun getWindDirection(): String? { + return get(KEY_WIND_DIRECTION) + } + + @WorkerThread + fun setWindDirection(watcher: String?) { + save(KEY_WIND_DIRECTION, watcher) + } + + @WorkerThread + fun getWindSpeed(): String? { + return get(KEY_WIND_SPEED) + } + + @WorkerThread + fun setWindSpeed(watcher: String?) { + save(KEY_WIND_SPEED, watcher) + } + + @WorkerThread + fun getRoads(): String? { + return get(KEY_ROADS) + } + + @WorkerThread + fun setRoads(watcher: String?) { + save(KEY_ROADS, watcher) + } + + @WorkerThread + fun getSoil(): String? { + return get(KEY_SOIL) + } + + @WorkerThread + fun setSoil(watcher: String?) { + save(KEY_SOIL, watcher) + } + + @WorkerThread + fun getRulerType(): String? { + return get(KEY_RULER_TYPE) + } + + @WorkerThread + fun setRulerType(watcher: String?) { + save(KEY_RULER_TYPE, watcher) + } + + @WorkerThread + fun getRulerReceptType(): String? { + return get(KEY_RULER_RECEPT_TYPE) + } + + @WorkerThread + fun setRulerReceptType(watcher: String?) { + save(KEY_RULER_RECEPT_TYPE, watcher) + } + + @WorkerThread + fun getRulerCorrectionFactor(): String? { + return get(KEY_RULER_CORRECTION_FACTOR) + } + + @WorkerThread + fun setRulerCorrectionFactor(watcher: String?) { + save(KEY_RULER_CORRECTION_FACTOR, watcher) + } + + + private fun save(key: String, value: String?) { + SurveyorDatabaseFactory.instance.getConfigDataSource().setSync(key, value) + } + + private fun get(key: String): String? { + val measureUnitRecord = + SurveyorDatabaseFactory.instance.getConfigDataSource() + .getByKeySync(key) + return measureUnitRecord?.getConfigValue() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingUtil.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingUtil.kt new file mode 100644 index 0000000..4c1518d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingUtil.kt @@ -0,0 +1,132 @@ +package com.bingce.controlnetwork.func.level.util + +import android.widget.Spinner +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R + +object LevelStationSettingUtil { + + /** + * 保存测站设置 + */ + fun saveStationSetting( + isSaveEndStationToStationSetting: Boolean, + levelRouteSave: LevelRouteSave + ) { + + var saveEndStation = isSaveEndStationToStationSetting + + val stationSetting = if (levelRouteSave.stationId != null) { + val before = + LevelingDbFactory.instance.stationSettingDataSource.getByStationId(levelRouteSave.stationId) + + if (before != null) { + saveEndStation = before.setEndStationSetting or saveEndStation + } + + before ?: LevelingStationSettingRecord() + } else { + LevelingStationSettingRecord() + } + + //初始化保存的endStation + stationSetting.setEndStationSetting = saveEndStation + + stationSetting.routeId = levelRouteSave.routeId + stationSetting.stationId = levelRouteSave.stationId + stationSetting.watcher = levelRouteSave.watcher + stationSetting.recorder = levelRouteSave.recorder + stationSetting.examiner = levelRouteSave.examiner + stationSetting.firstStationBackFootNumber = levelRouteSave.backFootNumber + stationSetting.firstStationFrontFootNumber = levelRouteSave.frontFootNumber + stationSetting.firstStationBackFootNumber2 = levelRouteSave.backFootNumber2 + stationSetting.firstStationFrontFootNumber2 = levelRouteSave.frontFootNumber2 + stationSetting.instrumentModel = levelRouteSave.instrumentModel + stationSetting.deviceNumber = levelRouteSave.deviceNumber + stationSetting.steelRuleParam = levelRouteSave.steelRuleParam + stationSetting.rulerLengthProvingTemperature = levelRouteSave.rulerLengthProvingTemperature + stationSetting.rulerCorrectionFactor = levelRouteSave.rulerCorrectionFactor + stationSetting.rulerType = levelRouteSave.rulerType + stationSetting.rulerReceptType = levelRouteSave.rulerReceptType + + stationSetting.temperature = levelRouteSave.temperature + stationSetting.weather = levelRouteSave.weather + stationSetting.imaging = levelRouteSave.imaging + stationSetting.sunDirection = levelRouteSave.sunDirection + stationSetting.windDirection = levelRouteSave.windDirection + stationSetting.windSpeed = levelRouteSave.windSpeed + stationSetting.roads = levelRouteSave.roads + stationSetting.soil = levelRouteSave.soil + + LevelingDbFactory.instance.stationSettingDataSource.save(stationSetting) + } + + fun getSpinnerText(spinner: Spinner): String { + val text = spinner.selectedItem.toString() + if (text.contains(Tools.getString(R.string.please_choose))) { + return "" + } + return text + } + + @WorkerThread + fun saveStationSettingLastData(levelRouteSave: LevelRouteSave) { + LevelStationSettingLastData.setWatcher(levelRouteSave.watcher) + LevelStationSettingLastData.setRecorder(levelRouteSave.recorder) + LevelStationSettingLastData.setExaminer(levelRouteSave.examiner) + LevelStationSettingLastData.setBackFootNumber(levelRouteSave.backFootNumber) + LevelStationSettingLastData.setFrontFootNumber(levelRouteSave.frontFootNumber) + LevelStationSettingLastData.setBackFootNumber2(levelRouteSave.backFootNumber2) + LevelStationSettingLastData.setFrontFootNumber2(levelRouteSave.frontFootNumber2) + LevelStationSettingLastData.setInstrumentModel(levelRouteSave.instrumentModel) + LevelStationSettingLastData.setDeviceNumber(levelRouteSave.deviceNumber) + LevelStationSettingLastData.setSteelRuleParam(levelRouteSave.steelRuleParam) + LevelStationSettingLastData.setRulerLengthProvingTemperature(levelRouteSave.rulerLengthProvingTemperature) + LevelStationSettingLastData.setRulerCorrectionFactor(levelRouteSave.rulerCorrectionFactor) + LevelStationSettingLastData.setRulerType(levelRouteSave.rulerType) + LevelStationSettingLastData.setRulerReceptType(levelRouteSave.rulerReceptType) + + LevelStationSettingLastData.setTemperature(levelRouteSave.temperature) + LevelStationSettingLastData.setWeather(levelRouteSave.weather) + LevelStationSettingLastData.setImaging(levelRouteSave.imaging) + LevelStationSettingLastData.setSunDirection(levelRouteSave.sunDirection) + LevelStationSettingLastData.setWindDirection(levelRouteSave.windDirection) + LevelStationSettingLastData.setWindSpeed(levelRouteSave.windSpeed) + LevelStationSettingLastData.setRoads(levelRouteSave.roads) + LevelStationSettingLastData.setSoil(levelRouteSave.soil) + } + + @WorkerThread + fun getStationSettingLastData(): LevelRouteSave { + return LevelRouteSave.createLastData( + LevelStationSettingLastData.getWatcher(), + LevelStationSettingLastData.getRecorder(), + LevelStationSettingLastData.getExaminer(), + LevelStationSettingLastData.getBackFootNumber(), + LevelStationSettingLastData.getFrontFootNumber(), + LevelStationSettingLastData.getBackFootNumber2(), + LevelStationSettingLastData.getFrontFootNumber2(), + LevelStationSettingLastData.getInstrumentModel(), + LevelStationSettingLastData.getDeviceNumber(), + LevelStationSettingLastData.getSteelRuleParam(), + LevelStationSettingLastData.getRulerLengthProvingTemperature(), + LevelStationSettingLastData.getRulerCorrectionFactor(), + LevelStationSettingLastData.getRulerType(), + LevelStationSettingLastData.getRulerReceptType(), + + LevelStationSettingLastData.getTemperature(), + LevelStationSettingLastData.getWeather(), + LevelStationSettingLastData.getImaging(), + LevelStationSettingLastData.getSunDirection(), + LevelStationSettingLastData.getWindDirection(), + LevelStationSettingLastData.getWindSpeed(), + LevelStationSettingLastData.getRoads(), + LevelStationSettingLastData.getSoil() + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationUtilTj.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationUtilTj.kt new file mode 100644 index 0000000..39074ec --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationUtilTj.kt @@ -0,0 +1,237 @@ +package com.bingce.controlnetwork.func.level.util + +import androidx.annotation.WorkerThread +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.measure.station.LevelingMeasureStationRecord +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.StationOddEven +import com.bingce.controlapphelper.util.RegExUtil +import com.bingce.utils.DateUtils + +object LevelStationUtilTj { + @WorkerThread + @JvmStatic + fun createStation( + projectId: String, + routeId: String, + backPointId: String, + firstStation: Boolean = false, + endStation: Boolean = false + ) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + routeRecord?.let { + val levelingMeasureOrder = it.levelingMeasureOrder + + //新建路线的时候创建一个水准测站 + val frontPoint = + LevelPointUtilTj.createFrontPointByBackPointId( + routeId, + backPointId, + firstStation, + endStation + ) + + val stationNamePrefix = "测站" + val lastStationNameIndex = getLastStationNameIndex(projectId, routeId) + + //创建测站的奇偶站 + val createStationOdd = getCreateStationOdd(projectId, routeId) + + when (levelingMeasureOrder) { + LevelingMeasureOrder.SIM_BF, LevelingMeasureOrder.SIM_BFFB -> { + val relationId = DateUtils.genRandomTimeId() + saveOneStationRecord( + projectId, + routeId, + "${stationNamePrefix}${lastStationNameIndex.plus(1)}_L", + backPointId, + frontPoint.getId(), + false, + createStationOdd, + relationId, + endStation = false + ) + saveOneStationRecord( + projectId, + routeId, + "${stationNamePrefix}${lastStationNameIndex.plus(1)}_R", + backPointId, + frontPoint.getId(), + true, + createStationOdd, + relationId, + endStation = endStation + ) + } + + LevelingMeasureOrder.A_BF, LevelingMeasureOrder.A_BFFB, LevelingMeasureOrder.A_FBBF -> { + saveOneStationRecord( + projectId, + routeId, + "${stationNamePrefix}${lastStationNameIndex.plus(1)}", + backPointId, + frontPoint.getId(), + false, + createStationOdd, + endStation = endStation + ) + } + + else -> { + saveOneStationRecord( + projectId, + routeId, + "${stationNamePrefix}${lastStationNameIndex.plus(1)}", + backPointId, + frontPoint.getId(), + false, + createStationOdd, + endStation = endStation + ) + } + } + } + } + + @WorkerThread + private fun getLastStationNameIndex(projectId: String, routeId: String): Int { + val stationLatest = + LevelingDbFactory.instance.stationDataSource.getStationLatest(projectId, routeId) + return stationLatest?.stationName?.let { + val findNum = RegExUtil.findNum(it) + findNum?.toInt() ?: 0 + } ?: 0 + } + + @WorkerThread + private fun getLastStationId(projectId: String, routeId: String): String? { + return getStationLatest(projectId, routeId)?.id + } + + private fun getStationLatest(projectId: String, routeId: String) = + LevelingDbFactory.instance.stationDataSource.getStationLatest(projectId, routeId) + + @WorkerThread + private fun saveOneStationRecord( + projectId: String, + routeId: String, + stationName: String, + backPointId: String, + frontPointId: String, + twiceStation: Boolean, + oddStation: StationOddEven, + relationId: String? = null, + endStation: Boolean = false + ) { + val lastStationId = getLastStationId(projectId, routeId) + + val station = LevelingStationRecord.createStation( + projectId, + routeId, + stationName, + lastStationId, + twiceStation, + backPointId, + frontPointId, + 0, + oddStation, + endStation + ) + station.relationStationId = relationId + LevelingDbFactory.instance.stationDataSource.save(station) + } + + private fun getCreateStationOdd( + projectId: String, + routeId: String + ): StationOddEven { + val stationLatest = getStationLatest(projectId, routeId) + ?: return StationOddEven.ODD_STATION + return if (stationLatest.isOddStation) { + StationOddEven.EVEN_STATION + } else { + StationOddEven.ODD_STATION + } + } + + @JvmStatic + fun checkStationForResult(stationId: String): Boolean { + val stationRecord = LevelingDbFactory.instance.stationDataSource.getRecordSync(stationId) + if (stationRecord.isFinish) { + return true + } else { + if (stationRecord == null || !stationRecord.isFull) { + ToastUtils.showShort("该测站数据不完整!") + } + if (!stationRecord.isFinish) { + ToastUtils.showShort("该测站未通过检测!") + } + return false + } + } + + @JvmStatic + fun getStationFinishCount(projectId: String, routeId: String): Int { + return LevelingDbFactory.instance.stationDataSource.getCountFinish(projectId, routeId) + } + + /** + * 获取要测量的测站列表 + */ + fun getMeasureStationList(projectId: String, routeId: String): List { + val stationLatest = + LevelingDbFactory.instance.stationDataSource.getStationLatest(projectId, routeId) + val returnList = mutableListOf() + if (stationLatest != null) { + if (stationLatest.twiceStation) { + //单程双转点 + val statonList = + LevelingDbFactory.instance.stationDataSource.getStationListByRelationId( + projectId, + routeId, + stationLatest.relationStationId + ) + returnList.addAll(statonList) + } else { + returnList.add(stationLatest) + } + } + return returnList + } + + @WorkerThread + fun getStationRouteResult(stationRecord: LevelingStationRecord): String { + val routeName = + LevelingDbFactory.instance.levelDataSource.getByIdSync(stationRecord.routeId)?.routeName ?: "" + + val sb = StringBuilder() + + if (stationRecord.twiceStation) { + val relationStation = LevelingDbFactory.instance.stationDataSource + .getRelationStation(stationRecord.relationStationId, false) + val twiceStationMeasureRecord = getMeasureStationRecord(relationStation.getId()) + appendMeasureResult(sb, routeName, twiceStationMeasureRecord) + } + + val measureStationRecord = getMeasureStationRecord(stationRecord.getId()) + appendMeasureResult(sb, routeName, measureStationRecord) + + return sb.toString() + } + + private fun appendMeasureResult( + sb: StringBuilder, + routeName: String, + measureStationRecord: LevelingMeasureStationRecord + ) { + sb.append("${routeName}的总高差${measureStationRecord.heightDiffTotalShow},总距离${measureStationRecord.distanceTotalShow}") + .append("\n") + } + + private fun getMeasureStationRecord(stationId: String) = + LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationId) + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonIllumination.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonIllumination.java new file mode 100644 index 0000000..deab2f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonIllumination.java @@ -0,0 +1,225 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static java.lang.Math.PI; +import static java.lang.Math.acos; +import static java.lang.Math.atan2; +import static java.lang.Math.cos; +import static java.lang.Math.signum; +import static java.lang.Math.sin; +import static java.lang.Math.toDegrees; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Moon; +import com.bingce.controlnetwork.func.level.util.suntime.util.Sun; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + + +/** + * Calculates the illumination of the moon. + *

+ * Starting with v3.9, a geolocation can be set optionally. If set, the results will be + * topocentric, relative to the given location. If not set, the result is geocentric, + * which was the standard behavior before v3.9. + */ +public class MoonIllumination { + + private final double fraction; + private final double phase; + private final double angle; + private final double elongation; + private final double radius; + private final double crescentWidth; + + private MoonIllumination(double fraction, double phase, double angle, + double elongation, double radius, double crescentWidth) { + this.fraction = fraction; + this.phase = phase; + this.angle = angle; + this.elongation = elongation; + this.radius = radius; + this.crescentWidth = crescentWidth; + } + + /** + * Starts the computation of {@link MoonIllumination}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new MoonIlluminationBuilder(); + } + + /** + * Collects all parameters for {@link MoonIllumination}. + */ + public interface Parameters extends + GenericParameter, + TimeParameter, + LocationParameter, + Builder { + + /** + * Clears the geolocation, so the result will be geocentric. + * + * @return itself + * @since 3.9 + */ + Parameters geocentric(); + + } + + /** + * Builder for {@link MoonIllumination}. Performs the computations based on the + * parameters, and creates a {@link MoonIllumination} object that holds the result. + */ + private static class MoonIlluminationBuilder extends BaseBuilder implements Parameters { + @Override + public Parameters geocentric() { + clearLocation(); + return this; + } + + @Override + public MoonIllumination execute() { + JulianDate t = getJulianDate(); + Vector s = Sun.position(t); + Vector m = Moon.position(t); + + double phi = PI - acos(m.dot(s) / (m.getR() * s.getR())); + Vector sunMoon = m.cross(s); + double angle = atan2( + cos(s.getTheta()) * sin(s.getPhi() - m.getPhi()), + sin(s.getTheta()) * cos(m.getTheta()) - cos(s.getTheta()) * sin(m.getTheta()) * cos(s.getPhi() - m.getPhi()) + ); + + Vector sTopo, mTopo; + if (hasLocation()) { + sTopo = Sun.positionTopocentric(t, getLatitudeRad(), getLongitudeRad(), getElevation()); + mTopo = Moon.positionTopocentric(t, getLatitudeRad(), getLongitudeRad(), getElevation()); + } else { + sTopo = s; + mTopo = m; + } + + double r = mTopo.subtract(sTopo).norm(); + double re = sTopo.norm(); + double d = mTopo.norm(); + double elongation = acos((d*d + re*re - r*r) / (2.0*d*re)); + double moonRadius = Moon.angularRadius(mTopo.getR()); + double crescentWidth = moonRadius * (1 - cos(elongation)); + + return new MoonIllumination( + (1 + cos(phi)) / 2, + toDegrees(phi * signum(sunMoon.getTheta())), + toDegrees(angle), + toDegrees(elongation), + toDegrees(moonRadius), + toDegrees(crescentWidth)); + } + } + + /** + * Illuminated fraction. {@code 0.0} indicates new moon, {@code 1.0} indicates full + * moon. + */ + public double getFraction() { + return fraction; + } + + /** + * Moon phase. Starts at {@code -180.0} (new moon, waxing), passes {@code 0.0} (full + * moon) and moves toward {@code 180.0} (waning, new moon). + *

+ * Note that for historical reasons, the range of this phase is different to the + * moon phase angle used in {@link MoonPhase}. + */ + public double getPhase() { + return phase; + } + + /** + * The angle of the moon illumination relative to earth. The moon is waxing if the + * angle is negative, and waning if positive. + *

+ * By subtracting {@link MoonPosition#getParallacticAngle()} from {@link #getAngle()}, + * one can get the zenith angle of the moons bright limb (anticlockwise). The zenith + * angle can be used do draw the moon shape from the observer's perspective (e.g. the + * moon lying on its back). + */ + public double getAngle() { + return angle; + } + + /** + * The closest {@link MoonPhase.Phase} that is matching the moon's angle. + * + * @return Closest {@link MoonPhase.Phase} + * @since 3.5 + */ + public MoonPhase.Phase getClosestPhase() { + return MoonPhase.Phase.toPhase(phase + 180.0); + } + + /** + * The elongation, which is the angular distance between the moon and the sun as + * observed from a specific location on earth. + * + * @return Elongation between moon and sun, in degrees. + * @since 3.9 + */ + public double getElongation() { + return elongation; + } + + /** + * The radius of the moon disk, as observed from a specific location on earth. + * + * @return Moon radius, in degrees. + * @since 3.9 + */ + public double getRadius() { + return radius; + } + + /** + * The width of the moon crescent, as observed from a specific location on earth. + * + * @return Crescent width, in degrees. + * @since 3.9 + */ + public double getCrescentWidth() { + return crescentWidth; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("MoonIllumination[fraction=").append(fraction); + sb.append(", phase=").append(phase); + sb.append("°, angle=").append(angle); + sb.append("°, elongation=").append(elongation); + sb.append("°, radius=").append(radius); + sb.append("°, crescentWidth=").append(crescentWidth); + sb.append("°]"); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPhase.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPhase.java new file mode 100644 index 0000000..751a4e4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPhase.java @@ -0,0 +1,322 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2018 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static java.lang.Math.PI; +import static java.lang.Math.toRadians; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Moon; +import com.bingce.controlnetwork.func.level.util.suntime.util.Pegasus; +import com.bingce.controlnetwork.func.level.util.suntime.util.Sun; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + +import java.time.ZonedDateTime; + + + + +/** + * Calculates the date and time when the moon reaches the desired phase. + *

+ * Note: Due to the simplified formulas used in suncalc, the returned time can have an + * error of several minutes. + */ +public class MoonPhase { + + private final ZonedDateTime time; + private final double distance; + + private MoonPhase(ZonedDateTime time, double distance) { + this.time = time; + this.distance = distance; + } + + /** + * Starts the computation of {@link MoonPhase}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new MoonPhaseBuilder(); + } + + /** + * Collects all parameters for {@link MoonPhase}. + */ + public interface Parameters extends + GenericParameter, + TimeParameter, + Builder { + + /** + * Sets the desired {@link Phase}. + *

+ * Defaults to {@link Phase#NEW_MOON}. + * + * @param phase {@link Phase} to be used. + * @return itself + */ + Parameters phase(Phase phase); + + /** + * Sets a free phase to be used. + * + * @param phase Desired phase, in degrees. 0 = new moon, 90 = first quarter, 180 = + * full moon, 270 = third quarter. + * @return itself + */ + Parameters phase(double phase); + } + + /** + * Enumeration of moon phases. + */ + public enum Phase { + + /** + * New moon. + */ + NEW_MOON(0.0), + + /** + * Waxing crescent moon. + * + * @since 3.5 + */ + WAXING_CRESCENT(45.0), + + /** + * Waxing half moon. + */ + FIRST_QUARTER(90.0), + + /** + * Waxing gibbous moon. + * + * @since 3.5 + */ + WAXING_GIBBOUS(135.0), + + /** + * Full moon. + */ + FULL_MOON(180.0), + + /** + * Waning gibbous moon. + * + * @since 3.5 + */ + WANING_GIBBOUS(225.0), + + /** + * Waning half moon. + */ + LAST_QUARTER(270.0), + + /** + * Waning crescent moon. + * + * @since 3.5 + */ + WANING_CRESCENT(315.0); + + /** + * Converts an angle to the closest matching moon phase. + * + * @param angle Moon phase angle, in degrees. 0 = New Moon, 180 = Full Moon. Angles + * outside the [0,360) range are normalized into that range. + * @return Closest Phase that is matching that angle. + * @since 3.5 + */ + public static Phase toPhase(double angle) { + // bring into range 0.0 .. 360.0 + double normalized = angle % 360.0; + if (normalized < 0.0) { + normalized += 360.0; + } + + if (normalized < 22.5) { + return NEW_MOON; + } + if (normalized < 67.5) { + return WAXING_CRESCENT; + } + if (normalized < 112.5) { + return FIRST_QUARTER; + } + if (normalized < 157.5) { + return WAXING_GIBBOUS; + } + if (normalized < 202.5) { + return FULL_MOON; + } + if (normalized < 247.5) { + return WANING_GIBBOUS; + } + if (normalized < 292.5) { + return LAST_QUARTER; + } + if (normalized < 337.5) { + return WANING_CRESCENT; + } + return NEW_MOON; + } + + private final double angle; + private final double angleRad; + + Phase(double angle) { + this.angle = angle; + this.angleRad = toRadians(angle); + } + + /** + * Returns the moons's angle in reference to the sun, in degrees. + */ + public double getAngle() { + return angle; + } + + /** + * Returns the moons's angle in reference to the sun, in radians. + */ + public double getAngleRad() { + return angleRad; + } + } + + /** + * Builder for {@link MoonPhase}. Performs the computations based on the parameters, + * and creates a {@link MoonPhase} object that holds the result. + */ + private static class MoonPhaseBuilder extends BaseBuilder implements Parameters { + private static final double SUN_LIGHT_TIME_TAU = 8.32 / (1440.0 * 36525.0); + + private double phase = Phase.NEW_MOON.getAngleRad(); + + @Override + public Parameters phase(Phase phase) { + this.phase = phase.getAngleRad(); + return this; + } + + @Override + public Parameters phase(double phase) { + this.phase = toRadians(phase); + return this; + } + + @Override + public MoonPhase execute() { + final JulianDate jd = getJulianDate(); + + double dT = 7.0 / 36525.0; // step rate: 1 week + double accuracy = (0.5 / 1440.0) / 36525.0; // accuracy: 30 seconds + + double t0 = jd.getJulianCentury(); + double t1 = t0 + dT; + + double d0 = moonphase(jd, t0); + double d1 = moonphase(jd, t1); + + while (d0 * d1 > 0.0 || d1 < d0) { + t0 = t1; + d0 = d1; + t1 += dT; + d1 = moonphase(jd, t1); + } + + double tphase = Pegasus.calculate(t0, t1, accuracy, x -> moonphase(jd, x)); + JulianDate tjd = jd.atJulianCentury(tphase); + return new MoonPhase(tjd.getDateTime(), Moon.positionEquatorial(tjd).getR()); + } + + /** + * Calculates the position of the moon at the given phase. + * + * @param jd Base Julian date + * @param t Ephemeris time + * @return difference angle of the sun's and moon's position + */ + private double moonphase(JulianDate jd, double t) { + Vector sun = Sun.positionEquatorial(jd.atJulianCentury(t - SUN_LIGHT_TIME_TAU)); + Vector moon = Moon.positionEquatorial(jd.atJulianCentury(t)); + double diff = moon.getPhi() - sun.getPhi() - phase; //NOSONAR: false positive + while (diff < 0.0) { + diff += PI2; + } + return ((diff + PI) % PI2) - PI; + } + + } + + /** + * Date and time of the desired moon phase. The time is rounded to full minutes. + */ + public ZonedDateTime getTime() { + return time; + } + + /** + * Geocentric distance of the moon at the given phase, in kilometers. + * + * @since 3.4 + */ + public double getDistance() { + return distance; + } + + /** + * Checks if the moon is in a SuperMoon position. + *

+ * Note that there is no official definition of supermoon. Suncalc will assume a + * supermoon if the center of the moon is closer than 360,000 km to the center of + * Earth. Usually only full moons or new moons are candidates for supermoons. + * + * @since 3.4 + */ + public boolean isSuperMoon() { + return distance < 360000.0; + } + + /** + * Checks if the moon is in a MicroMoon position. + *

+ * Note that there is no official definition of micromoon. Suncalc will assume a + * micromoon if the center of the moon is farther than 405,000 km from the center of + * Earth. Usually only full moons or new moons are candidates for micromoons. + * + * @since 3.4 + */ + public boolean isMicroMoon() { + return distance > 405000.0; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("MoonPhase[time=").append(time); + sb.append(", distance=").append(distance); + sb.append(" km]"); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPosition.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPosition.java new file mode 100644 index 0000000..d940e9c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPosition.java @@ -0,0 +1,167 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToHorizontal; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.refraction; +import static java.lang.Math.atan2; +import static java.lang.Math.cos; +import static java.lang.Math.sin; +import static java.lang.Math.tan; +import static java.lang.Math.toDegrees; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Moon; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + + +/** + * Calculates the position of the moon. + */ +public class MoonPosition { + + private final double azimuth; + private final double altitude; + private final double trueAltitude; + private final double distance; + private final double parallacticAngle; + + private MoonPosition(double azimuth, double altitude, double trueAltitude, double distance, double parallacticAngle) { + this.azimuth = (toDegrees(azimuth) + 180.0) % 360.0; + this.altitude = toDegrees(altitude); + this.trueAltitude = toDegrees(trueAltitude); + this.distance = distance; + this.parallacticAngle = toDegrees(parallacticAngle); + } + + /** + * Starts the computation of {@link MoonPosition}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new MoonPositionBuilder(); + } + + /** + * Collects all parameters for {@link MoonPosition}. + */ + public interface Parameters extends + GenericParameter, + LocationParameter, + TimeParameter, + Builder { + } + + /** + * Builder for {@link MoonPosition}. Performs the computations based on the + * parameters, and creates a {@link MoonPosition} object that holds the result. + */ + private static class MoonPositionBuilder extends BaseBuilder implements Parameters { + @Override + public MoonPosition execute() { + if (!hasLocation()) { + throw new IllegalArgumentException("Geolocation is missing."); + } + + JulianDate t = getJulianDate(); + + double phi = getLatitudeRad(); + double lambda = getLongitudeRad(); + + Vector mc = Moon.position(t); + double h = t.getGreenwichMeanSiderealTime() + lambda - mc.getPhi(); + + Vector horizontal = equatorialToHorizontal(h, mc.getTheta(), mc.getR(), phi); + + double hRef = refraction(horizontal.getTheta()); + + double pa = atan2(sin(h), tan(phi) * cos(mc.getTheta()) - sin(mc.getTheta()) * cos(h)); + + return new MoonPosition( + horizontal.getPhi(), + horizontal.getTheta() + hRef, + horizontal.getTheta(), + mc.getR(), + pa); + } + } + + /** + * Moon altitude above the horizon, in degrees. + *

+ * {@code 0.0} means the moon's center is at the horizon, {@code 90.0} at the zenith + * (straight over your head). Atmospheric refraction is taken into account. + * + * @see #getTrueAltitude() + */ + public double getAltitude() { + return altitude; + } + + /** + * The true moon altitude above the horizon, in degrees. + *

+ * {@code 0.0} means the moon's center is at the horizon, {@code 90.0} at the zenith + * (straight over your head). + * + * @see #getAltitude() + * @since 3.8 + */ + public double getTrueAltitude() { + return trueAltitude; + } + + /** + * Moon azimuth, in degrees, north-based. + *

+ * This is the direction along the horizon, measured from north to east. For example, + * {@code 0.0} means north, {@code 135.0} means southeast, {@code 270.0} means west. + */ + public double getAzimuth() { + return azimuth; + } + + /** + * Distance to the moon in kilometers. + */ + public double getDistance() { + return distance; + } + + /** + * Parallactic angle of the moon, in degrees. + */ + public double getParallacticAngle() { + return parallacticAngle; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("MoonPosition[azimuth=").append(azimuth); + sb.append("°, altitude=").append(altitude); + sb.append("°, true altitude=").append(trueAltitude); + sb.append("°, distance=").append(distance); + sb.append(" km, parallacticAngle=").append(parallacticAngle); + sb.append("°]"); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonTimes.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonTimes.java new file mode 100644 index 0000000..82f940e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonTimes.java @@ -0,0 +1,255 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.apparentRefraction; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.parallax; +import static java.lang.Math.ceil; + +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Moon; +import com.bingce.controlnetwork.func.level.util.suntime.util.QuadraticInterpolation; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + +import java.time.Duration; +import java.time.ZonedDateTime; + + + +/** + * Calculates the times of the moon. + */ +public final class MoonTimes { + + private final @Nullable ZonedDateTime rise; + private final @Nullable ZonedDateTime set; + private final boolean alwaysUp; + private final boolean alwaysDown; + + private MoonTimes(@Nullable ZonedDateTime rise, @Nullable ZonedDateTime set, + boolean alwaysUp, boolean alwaysDown) { + this.rise = rise; + this.set = set; + this.alwaysUp = alwaysUp; + this.alwaysDown = alwaysDown; + } + + /** + * Starts the computation of {@link MoonTimes}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new MoonTimesBuilder(); + } + + /** + * Collects all parameters for {@link MoonTimes}. + */ + public static interface Parameters extends + GenericParameter, + LocationParameter, + TimeParameter, + Builder { + + /** + * Limits the calculation window to the given {@link Duration}. + * + * @param duration Duration of the calculation window. Must be positive. + * @return itself + * @since 3.1 + */ + Parameters limit(Duration duration); + + /** + * Limits the time window to the next 24 hours. + * + * @return itself + */ + default Parameters oneDay() { + return limit(Duration.ofDays(1L)); + } + + /** + * Computes until all rise and set times are found. + *

+ * This is the default. + * + * @return itself + */ + default Parameters fullCycle() { + return limit(Duration.ofDays(365L)); + } + } + + /** + * Builder for {@link MoonTimes}. Performs the computations based on the parameters, + * and creates a {@link MoonTimes} object that holds the result. + */ + private static class MoonTimesBuilder extends BaseBuilder implements Parameters { + private Duration limit = Duration.ofDays(365L); + private double refraction = apparentRefraction(0.0); + + @Override + public Parameters limit(Duration duration) { + if (duration == null || duration.isNegative()) { + throw new IllegalArgumentException("duration must be positive"); + } + limit = duration; + return this; + } + + @Override + public MoonTimes execute() { + if (!hasLocation()) { + throw new IllegalArgumentException("Geolocation is missing."); + } + + JulianDate jd = getJulianDate(); + + Double rise = null; + Double set = null; + boolean alwaysUp = false; + boolean alwaysDown = false; + double ye; + + int hour = 0; + double limitHours = limit.toMillis() / (60 * 60 * 1000.0); + int maxHours = (int) ceil(limitHours); + + double y_minus = correctedMoonHeight(jd.atHour(hour - 1.0)); + double y_0 = correctedMoonHeight(jd.atHour(hour)); + double y_plus = correctedMoonHeight(jd.atHour(hour + 1.0)); + + if (y_0 > 0.0) { + alwaysUp = true; + } else { + alwaysDown = true; + } + + while (hour <= maxHours) { + QuadraticInterpolation qi = new QuadraticInterpolation(y_minus, y_0, y_plus); + ye = qi.getYe(); + + if (qi.getNumberOfRoots() == 1) { + double rt = qi.getRoot1() + hour; + if (y_minus < 0.0) { + if (rise == null && rt >= 0.0 && rt < limitHours) { + rise = rt; + alwaysDown = false; + } + } else { + if (set == null && rt >= 0.0 && rt < limitHours) { + set = rt; + alwaysUp = false; + } + } + } else if (qi.getNumberOfRoots() == 2) { + if (rise == null) { + double rt = hour + (ye < 0.0 ? qi.getRoot2() : qi.getRoot1()); + if (rt >= 0.0 && rt < limitHours) { + rise = rt; + alwaysDown = false; + } + } + if (set == null) { + double rt = hour + (ye < 0.0 ? qi.getRoot1() : qi.getRoot2()); + if (rt >= 0.0 && rt < limitHours) { + set = rt; + alwaysUp = false; + } + } + } + + if (rise != null && set != null) { + break; + } + + hour++; + y_minus = y_0; + y_0 = y_plus; + y_plus = correctedMoonHeight(jd.atHour(hour + 1.0)); + } + + return new MoonTimes( + rise != null ? jd.atHour(rise).getDateTime() : null, + set != null ? jd.atHour(set).getDateTime() : null, + alwaysUp, + alwaysDown); + } + + /** + * Computes the moon height at the given date and position. + * + * @param jd {@link JulianDate} to use + * @return height, in radians + */ + private double correctedMoonHeight(JulianDate jd) { + Vector pos = Moon.positionHorizontal(jd, getLatitudeRad(), getLongitudeRad()); + double hc = parallax(getElevation(), pos.getR()) + - refraction + - Moon.angularRadius(pos.getR()); + return pos.getTheta() - hc; + } + } + + /** + * Moonrise time. {@code null} if the moon does not rise that day. + */ + @Nullable + public ZonedDateTime getRise() { + return rise; + } + + /** + * Moonset time. {@code null} if the moon does not set that day. + */ + @Nullable + public ZonedDateTime getSet() { + return set; + } + + /** + * {@code true} if the moon never rises/sets, but is always above the horizon. + */ + public boolean isAlwaysUp() { + return alwaysUp; + } + + /** + * {@code true} if the moon never rises/sets, but is always below the horizon. + */ + public boolean isAlwaysDown() { + return alwaysDown; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("MoonTimes[rise=").append(rise); + sb.append(", set=").append(set); + sb.append(", alwaysUp=").append(alwaysUp); + sb.append(", alwaysDown=").append(alwaysDown); + sb.append(']'); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunPosition.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunPosition.java new file mode 100644 index 0000000..5932eaf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunPosition.java @@ -0,0 +1,139 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.refraction; +import static java.lang.Math.toDegrees; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Sun; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + + +/** + * Calculates the position of the sun. + */ +public class SunPosition { + + private final double azimuth; + private final double altitude; + private final double trueAltitude; + private final double distance; + + private SunPosition(double azimuth, double altitude, double trueAltitude, double distance) { + this.azimuth = (toDegrees(azimuth) + 180.0) % 360.0; + this.altitude = toDegrees(altitude); + this.trueAltitude = toDegrees(trueAltitude); + this.distance = distance; + } + + /** + * Starts the computation of {@link SunPosition}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new SunPositionBuilder(); + } + + /** + * Collects all parameters for {@link SunPosition}. + */ + public interface Parameters extends + GenericParameter, + LocationParameter, + TimeParameter, + Builder { + } + + /** + * Builder for {@link SunPosition}. Performs the computations based on the parameters, + * and creates a {@link SunPosition} object that holds the result. + */ + private static class SunPositionBuilder extends BaseBuilder implements Parameters { + @Override + public SunPosition execute() { + if (!hasLocation()) { + throw new IllegalArgumentException("Geolocation is missing."); + } + + JulianDate t = getJulianDate(); + + Vector horizontal = Sun.positionHorizontal(t, getLatitudeRad(), getLongitudeRad()); + double hRef = refraction(horizontal.getTheta()); + + return new SunPosition(horizontal.getPhi(), + horizontal.getTheta() + hRef, + horizontal.getTheta(), + horizontal.getR()); + } + } + + /** + * The visible sun altitude above the horizon, in degrees. + *

+ * {@code 0.0} means the sun's center is at the horizon, {@code 90.0} at the zenith + * (straight over your head). Atmospheric refraction is taken into account. + * + * @see #getTrueAltitude() + */ + public double getAltitude() { + return altitude; + } + + /** + * The true sun altitude above the horizon, in degrees. + *

+ * {@code 0.0} means the sun's center is at the horizon, {@code 90.0} at the zenith + * (straight over your head). + * + * @see #getAltitude() + */ + public double getTrueAltitude() { + return trueAltitude; + } + + /** + * Sun azimuth, in degrees, north-based. + *

+ * This is the direction along the horizon, measured from north to east. For example, + * {@code 0.0} means north, {@code 135.0} means southeast, {@code 270.0} means west. + */ + public double getAzimuth() { + return azimuth; + } + + /** + * Sun's distance, in kilometers. + */ + public double getDistance() { + return distance; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("SunPosition[azimuth=").append(azimuth); + sb.append("°, altitude=").append(altitude); + sb.append("°, true altitude=").append(trueAltitude); + sb.append("°, distance=").append(distance).append(" km]"); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunTimes.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunTimes.java new file mode 100644 index 0000000..bfeb6a8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunTimes.java @@ -0,0 +1,487 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.apparentRefraction; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.parallax; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.readjustMax; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.readjustMin; +import static java.lang.Math.abs; +import static java.lang.Math.ceil; +import static java.lang.Math.toRadians; + +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.QuadraticInterpolation; +import com.bingce.controlnetwork.func.level.util.suntime.util.Sun; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + +import java.time.Duration; +import java.time.ZonedDateTime; + + + +/** + * Calculates the rise and set times of the sun. + */ +public class SunTimes { + + private final @Nullable ZonedDateTime rise; + private final @Nullable ZonedDateTime set; + private final @Nullable ZonedDateTime noon; + private final @Nullable ZonedDateTime nadir; + private final boolean alwaysUp; + private final boolean alwaysDown; + + private SunTimes(@Nullable ZonedDateTime rise, @Nullable ZonedDateTime set, + @Nullable ZonedDateTime noon, @Nullable ZonedDateTime nadir, + boolean alwaysUp, boolean alwaysDown) { + this.rise = rise; + this.set = set; + this.noon = noon; + this.nadir = nadir; + this.alwaysUp = alwaysUp; + this.alwaysDown = alwaysDown; + } + + /** + * Starts the computation of {@link SunTimes}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new SunTimesBuilder(); + } + + /** + * Collects all parameters for {@link SunTimes}. + */ + public interface Parameters extends + GenericParameter, + LocationParameter, + TimeParameter, + Builder { + + /** + * Sets the {@link Twilight} mode. + *

+ * Defaults to {@link Twilight#VISUAL}. + * + * @param twilight {@link Twilight} mode to be used. + * @return itself + */ + Parameters twilight(Twilight twilight); + + /** + * Sets the desired elevation angle of the sun. The sunrise and sunset times are + * referring to the moment when the center of the sun passes this angle. + * + * @param angle Geocentric elevation angle, in degrees. + * @return itself + */ + Parameters twilight(double angle); + + /** + * Limits the calculation window to the given {@link Duration}. + * + * @param duration Duration of the calculation window. Must be positive. + * @return itself + * @since 3.1 + */ + Parameters limit(Duration duration); + + /** + * Limits the time window to the next 24 hours. + * + * @return itself + */ + default Parameters oneDay() { + return limit(Duration.ofDays(1L)); + } + + /** + * Computes until all rise, set, noon, and nadir times are found. + *

+ * This is the default. + * + * @return itself + */ + default Parameters fullCycle() { + return limit(Duration.ofDays(365L)); + } + } + + /** + * Enumeration of predefined twilights. + *

+ * The twilight angles use a geocentric reference, by definition. However, + * {@link #VISUAL} and {@link #VISUAL_LOWER} are topocentric, and take the spectator's + * elevation and the atmospheric refraction into account. + * + * @see Wikipedia: Twilight + */ + public enum Twilight { + + /** + * The moment when the visual upper edge of the sun crosses the horizon. This is + * commonly referred to as "sunrise" and "sunset". Atmospheric refraction is taken + * into account. + *

+ * This is the default. + */ + VISUAL(0.0, 1.0), + + /** + * The moment when the visual lower edge of the sun crosses the horizon. This is + * the ending of the sunrise and the starting of the sunset. Atmospheric + * refraction is taken into account. + */ + VISUAL_LOWER(0.0, -1.0), + + /** + * The moment when the center of the sun crosses the horizon (0°). + */ + HORIZON(0.0), + + /** + * Civil twilight (-6°). + */ + CIVIL(-6.0), + + /** + * Nautical twilight (-12°). + */ + NAUTICAL(-12.0), + + /** + * Astronomical twilight (-18°). + */ + ASTRONOMICAL(-18.0), + + /** + * Golden hour (6°). The Golden hour is between {@link #GOLDEN_HOUR} and + * {@link #BLUE_HOUR}. The Magic hour is between {@link #GOLDEN_HOUR} and + * {@link #CIVIL}. + * + * @see Wikipedia: + * Golden hour + */ + GOLDEN_HOUR(6.0), + + /** + * Blue hour (-4°). The Blue hour is between {@link #NIGHT_HOUR} and + * {@link #BLUE_HOUR}. + * + * @see Wikipedia: Blue hour + */ + BLUE_HOUR(-4.0), + + /** + * End of Blue hour (-8°). + *

+ * "Night Hour" is not an official term, but just a name that is marking the + * beginning/end of the Blue hour. + */ + NIGHT_HOUR(-8.0); + + private final double angle; + private final double angleRad; + private final @Nullable Double position; + + Twilight(double angle) { + this(angle, null); + } + + Twilight(double angle, @Nullable Double position) { + this.angle = angle; + this.angleRad = toRadians(angle); + this.position = position; + } + + /** + * Returns the sun's angle at the twilight position, in degrees. + */ + public double getAngle() { + return angle; + } + + /** + * Returns the sun's angle at the twilight position, in radians. + */ + public double getAngleRad() { + return angleRad; + } + + /** + * Returns {@code true} if this twilight position is topocentric. Then the + * parallax and the atmospheric refraction is taken into account. + */ + public boolean isTopocentric() { + return position != null; + } + + /** + * Returns the angular position. {@code 0.0} means center of the sun. {@code 1.0} + * means upper edge of the sun. {@code -1.0} means lower edge of the sun. + * {@code null} means the angular position is not topocentric. + */ + @Nullable + private Double getAngularPosition() { + return position; + } + } + + /** + * Builder for {@link SunTimes}. Performs the computations based on the parameters, + * and creates a {@link SunTimes} object that holds the result. + */ + private static class SunTimesBuilder extends BaseBuilder implements Parameters { + private double angle = Twilight.VISUAL.getAngleRad(); + private @Nullable Double position = Twilight.VISUAL.getAngularPosition(); + private Duration limit = Duration.ofDays(365L); + + @Override + public Parameters twilight(Twilight twilight) { + this.angle = twilight.getAngleRad(); + this.position = twilight.getAngularPosition(); + return this; + } + + @Override + public Parameters twilight(double angle) { + this.angle = toRadians(angle); + this.position = null; + return this; + } + + @Override + public Parameters limit(Duration duration) { + if (duration == null || duration.isNegative()) { + throw new IllegalArgumentException("duration must be positive"); + } + limit = duration; + return this; + } + + @Override + public SunTimes execute() { + if (!hasLocation()) { + throw new IllegalArgumentException("Geolocation is missing."); + } + + JulianDate jd = getJulianDate(); + + Double rise = null; + Double set = null; + Double noon = null; + Double nadir = null; + boolean alwaysUp = false; + boolean alwaysDown = false; + double ye; + + int hour = 0; + double limitHours = limit.toMillis() / (60 * 60 * 1000.0); + int maxHours = (int) ceil(limitHours); + + double y_minus = correctedSunHeight(jd.atHour(hour - 1.0)); + double y_0 = correctedSunHeight(jd.atHour(hour)); + double y_plus = correctedSunHeight(jd.atHour(hour + 1.0)); + + if (y_0 > 0.0) { + alwaysUp = true; + } else { + alwaysDown = true; + } + + while (hour <= maxHours) { + QuadraticInterpolation qi = new QuadraticInterpolation(y_minus, y_0, y_plus); + ye = qi.getYe(); + + if (qi.getNumberOfRoots() == 1) { + double rt = qi.getRoot1() + hour; + if (y_minus < 0.0) { + if (rise == null && rt >= 0.0 && rt < limitHours) { + rise = rt; + alwaysDown = false; + } + } else { + if (set == null && rt >= 0.0 && rt < limitHours) { + set = rt; + alwaysUp = false; + } + } + } else if (qi.getNumberOfRoots() == 2) { + if (rise == null) { + double rt = hour + (ye < 0.0 ? qi.getRoot2() : qi.getRoot1()); + if (rt >= 0.0 && rt < limitHours) { + rise = rt; + alwaysDown = false; + } + } + if (set == null) { + double rt = hour + (ye < 0.0 ? qi.getRoot1() : qi.getRoot2()); + if (rt >= 0.0 && rt < limitHours) { + set = rt; + alwaysUp = false; + } + } + } + + double xeAbs = abs(qi.getXe()); + if (xeAbs <= 1.0) { + double xeHour = qi.getXe() + hour; + if (xeHour >= 0.0) { + if (qi.isMaximum()) { + if (noon == null) { + noon = xeHour; + } + } else { + if (nadir == null) { + nadir = xeHour; + } + } + } + } + + if (rise != null && set != null && noon != null && nadir != null) { + break; + } + + hour++; + y_minus = y_0; + y_0 = y_plus; + y_plus = correctedSunHeight(jd.atHour(hour + 1.0)); + } + + if (noon != null) { + noon = readjustMax(noon, 2.0, 14, t -> correctedSunHeight(jd.atHour(t))); + if (noon < 0.0 || noon >= limitHours) { + noon = null; + } + } + + if (nadir != null) { + nadir = readjustMin(nadir, 2.0, 14, t -> correctedSunHeight(jd.atHour(t))); + if (nadir < 0.0 || nadir >= limitHours) { + nadir = null; + } + } + + return new SunTimes( + rise != null ? jd.atHour(rise).getDateTime() : null, + set != null ? jd.atHour(set).getDateTime() : null, + noon != null ? jd.atHour(noon).getDateTime() : null, + nadir != null ? jd.atHour(nadir).getDateTime() : null, + alwaysUp, + alwaysDown + ); + } + + /** + * Computes the sun height at the given date and position. + * + * @param jd {@link JulianDate} to use + * @return height, in radians + */ + private double correctedSunHeight(JulianDate jd) { + Vector pos = Sun.positionHorizontal(jd, getLatitudeRad(), getLongitudeRad()); + + double hc = angle; + if (position != null) { + hc -= apparentRefraction(hc); + hc += parallax(getElevation(), pos.getR()); + hc -= position * Sun.angularRadius(pos.getR()); + } + + return pos.getTheta() - hc; + } + } + + /** + * Sunrise time. {@code null} if the sun does not rise that day. + *

+ * Always returns a sunrise time if {@link Parameters#fullCycle()} was set. + */ + @Nullable + public ZonedDateTime getRise() { + return rise; + } + + /** + * Sunset time. {@code null} if the sun does not set that day. + *

+ * Always returns a sunset time if {@link Parameters#fullCycle()} was set. + */ + @Nullable + public ZonedDateTime getSet() { + return set; + } + + /** + * The time when the sun reaches its highest point. + *

+ * Use {@link #isAlwaysDown()} to find out if the highest point is still below the + * twilight angle. + */ + @Nullable + public ZonedDateTime getNoon() { + return noon; + } + + /** + * The time when the sun reaches its lowest point. + *

+ * Use {@link #isAlwaysUp()} to find out if the lowest point is still above the + * twilight angle. + */ + @Nullable + public ZonedDateTime getNadir() { + return nadir; + } + + /** + * {@code true} if the sun never rises/sets, but is always above the twilight angle. + */ + public boolean isAlwaysUp() { + return alwaysUp; + } + + /** + * {@code true} if the sun never rises/sets, but is always below the twilight angle. + */ + public boolean isAlwaysDown() { + return alwaysDown; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("SunTimes[rise=").append(rise); + sb.append(", set=").append(set); + sb.append(", noon=").append(noon); + sb.append(", nadir=").append(nadir); + sb.append(", alwaysUp=").append(alwaysUp); + sb.append(", alwaysDown=").append(alwaysDown); + sb.append(']'); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/Builder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/Builder.java new file mode 100644 index 0000000..f5b49f1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/Builder.java @@ -0,0 +1,34 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.param; + +/** + * An interface for the method that eventually executes the calculation. + * + * @param + * Result type + */ +public interface Builder { + + /** + * Executes the calculation and returns the desired result. + *

+ * The resulting object is immutable. You can change parameters, and then invoke + * {@link #execute()} again, to get a new object with new results. + * + * @return Result of the calculation. + */ + T execute(); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/GenericParameter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/GenericParameter.java new file mode 100644 index 0000000..1118077 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/GenericParameter.java @@ -0,0 +1,29 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2020 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.param; + +/** + * Generic parameters and options. + * + * @param + * Type of the final builder + */ +public interface GenericParameter { + + /** + * Creates a copy of the current parameters. The copy can be changed independently. + */ + T copy(); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/LocationParameter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/LocationParameter.java new file mode 100644 index 0000000..c7535f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/LocationParameter.java @@ -0,0 +1,165 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.param; + + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.dms; + +/** + * Location based parameters. + *

+ * Use them to give information about the geolocation of the observer. If ommitted, the + * coordinates of Null Island are + * used. + * + * @param Type of the final builder + */ +@SuppressWarnings("unchecked") +public interface LocationParameter { + + /** + * Sets the latitude. + * + * @param lat Latitude, in degrees. + * @return itself + */ + T latitude(double lat); + + /** + * Sets the longitude. + * + * @param lng Longitude, in degrees. + * @return itself + */ + T longitude(double lng); + + /** + * Sets the elevation. + * + * @param h Elevation, in meters above sea level. Default: 0.0 m. Negative values + * are silently changed to the acceptable minimum of 0.0 m. + * @return itself + * @see #elevationFt(double) + * @since 3.9 + */ + T elevation(double h); + + /** + * Sets the elevation, in foot. + * + * @param ft Elevation, in foot above sea level. Default: 0.0 ft. Negative values are + * silently changed to the acceptable minimum of 0.0 ft. + * @return itself + * @see #elevation(double) + * @since 3.9 + */ + default T elevationFt(double ft) { + return elevation(ft * 0.3048); + } + + /** + * Sets the height. + * + * @param h Height, in meters above sea level. Default: 0.0 m. Negative values are + * silently changed to the acceptable minimum of 0.0 m. + * @return itself + * @deprecated Use {@link #elevation(double)} instead. + */ + @Deprecated + default T height(double h) { + return elevation(h); + } + + /** + * Sets the height, in foot. + * + * @param ft Height, in foot above sea level. Default: 0.0 ft. Negative values are + * silently changed to the acceptable minimum of 0.0 ft. + * @return itself + * @since 3.8 + * @deprecated Use {@link #elevationFt(double)} instead. + */ + @Deprecated + default T heightFt(double ft) { + return elevationFt(ft); + } + + /** + * Sets the geolocation. + * + * @param lat Latitude, in degrees. + * @param lng Longitude, in degrees. + * @return itself + */ + default T at(double lat, double lng) { + latitude(lat); + longitude(lng); + return (T) this; + } + + /** + * Sets the geolocation. In the given array, index 0 must contain the latitude, and + * index 1 must contain the longitude. An optional index 2 may contain the elevation, + * in meters. + *

+ * This call is meant to be used for coordinates stored in constants. + * + * @param coords Array containing the latitude and longitude, in degrees. + * @return itself + */ + default T at(double[] coords) { + if (coords.length != 2 && coords.length != 3) { + throw new IllegalArgumentException("Array must contain 2 or 3 doubles"); + } + if (coords.length == 3) { + elevation(coords[2]); + } + return at(coords[0], coords[1]); + } + + /** + * Sets the latitude. + * + * @param d Degrees + * @param m Minutes + * @param s Seconds (and fraction of seconds) + * @return itself + */ + default T latitude(int d, int m, double s) { + return latitude(dms(d, m, s)); + } + + /** + * Sets the longitude. + * + * @param d Degrees + * @param m Minutes + * @param s Seconds (and fraction of seconds) + * @return itself + */ + default T longitude(int d, int m, double s) { + return longitude(dms(d, m, s)); + } + + /** + * Uses the same location as given in the {@link LocationParameter} at this moment. + *

+ * Changes to the source parameter will not affect this parameter, though. + * + * @param l {@link LocationParameter} to be used. + * @return itself + */ + T sameLocationAs(LocationParameter l); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/TimeParameter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/TimeParameter.java new file mode 100644 index 0000000..27fd9be --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/TimeParameter.java @@ -0,0 +1,244 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.param; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.Objects; +import java.util.TimeZone; + +/** + * Time based parameters. + *

+ * Use them to give information about the desired time. If ommitted, the current time and + * the system's time zone is used. + * + * @param + * Type of the final builder + */ +@SuppressWarnings("unchecked") +public interface TimeParameter { + + /** + * Sets date and time. Note that also seconds can be passed in for convenience, but + * the results are not that accurate. + * + * @param year + * Year + * @param month + * Month (1 = January, 2 = February, ...) + * @param date + * Day of month + * @param hour + * Hour of day + * @param minute + * Minute + * @param second + * Second + * @return itself + */ + T on(int year, int month, int date, int hour, int minute, int second); + + /** + * Sets midnight of the year, month and date. + * + * @param year + * Year + * @param month + * Month (1 = January, 2 = February, ...) + * @param date + * Day of month + * @return itself + */ + default T on(int year, int month, int date) { + return on(year, month, date, 0, 0, 0); + } + + /** + * Uses the given {@link ZonedDateTime} instance. + * + * @param dateTime + * {@link ZonedDateTime} to be used. + * @return itself + */ + T on(ZonedDateTime dateTime); + + /** + * Uses the given {@link LocalDateTime} instance. + * + * @param dateTime + * {@link LocalDateTime} to be used. + * @return itself + */ + T on(LocalDateTime dateTime); + + /** + * Uses the given {@link LocalDate} instance, and assumes midnight. + * + * @param date + * {@link LocalDate} to be used. + * @return itself + */ + T on(LocalDate date); + + /** + * Uses the given {@link Instant} instance. + * + * @param instant + * {@link Instant} to be used. + * @return itself + */ + T on(Instant instant); + + /** + * Uses the given {@link Date} instance. + * + * @param date + * {@link Date} to be used. + * @return itself + */ + default T on(Date date) { + Objects.requireNonNull(date, "date"); + return on(date.toInstant()); + } + + /** + * Uses the given {@link Calendar} instance. + * + * @param cal + * {@link Calendar} to be used + * @return itself + */ + default T on(Calendar cal) { + Objects.requireNonNull(cal, "cal"); + return on(ZonedDateTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId())); + } + + /** + * Sets the current date and time. This is the default. + * + * @return itself + */ + T now(); + + /** + * Sets the time to the start of the current date ("last midnight"). + * + * @return itself + */ + T midnight(); + + /** + * Adds a number of days to the current date. + * + * @param days + * Number of days to add + * @return itself + */ + T plusDays(int days); + + /** + * Sets today, midnight. + *

+ * It is the same as now().midnight(). + * + * @return itself + */ + default T today() { + now(); + midnight(); + return (T) this; + } + + /** + * Sets tomorrow, midnight. + *

+ * It is the same as now().midnight().plusDays(1). + * + * @return itself + */ + default T tomorrow() { + today(); + plusDays(1); + return (T) this; + } + + /** + * Sets the given {@link ZoneId}. The local time is retained, so the parameter order + * is not important. + * + * @param tz + * {@link ZoneId} to be used. + * @return itself + */ + T timezone(ZoneId tz); + + /** + * Sets the given timezone. This is a convenience method that just invokes + * {@link ZoneId#of(String)}. + * + * @param id + * ID of the time zone. + * @return itself + * @see ZoneId#of(String) + */ + default T timezone(String id) { + return timezone(ZoneId.of(id)); + } + + /** + * Sets the system's timezone. This is the default. + * + * @return itself + */ + default T localTime() { + return timezone(ZoneId.systemDefault()); + } + + /** + * Sets the time zone to UTC. + * + * @return itself + */ + default T utc() { + return timezone("UTC"); + } + + /** + * Sets the {@link TimeZone}. + * + * @param tz {@link TimeZone} to be used + * @return itself + */ + default T timezone(TimeZone tz) { + Objects.requireNonNull(tz, "tz"); + return timezone(tz.toZoneId()); + } + + /** + * Uses the same time as given in the {@link TimeParameter}. + *

+ * Changes to the source parameter will not affect this parameter, though. + * + * @param t {@link TimeParameter} to be used. + * @return itself + */ + T sameTimeAs(TimeParameter t); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/BaseBuilder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/BaseBuilder.java new file mode 100644 index 0000000..b85e092 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/BaseBuilder.java @@ -0,0 +1,236 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.max; +import static java.lang.Math.toRadians; + +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Objects; + + + +/** + * A base implementation of {@link LocationParameter} and {@link TimeParameter}. + *

+ * For internal use only. + * + * @param Type of the final builder + */ +@SuppressWarnings("unchecked") +public class BaseBuilder implements GenericParameter, LocationParameter, + TimeParameter, Cloneable { + + private @Nullable Double lat = null; + private @Nullable Double lng = null; + private double elevation = 0.0; + private ZonedDateTime dateTime = ZonedDateTime.now(); + + @Override + public T on(ZonedDateTime dateTime) { + this.dateTime = Objects.requireNonNull(dateTime, "dateTime"); + return (T) this; + } + + @Override + public T on(LocalDateTime dateTime) { + Objects.requireNonNull(dateTime, "dateTime"); + return on(ZonedDateTime.of(dateTime, this.dateTime.getZone())); + } + + @Override + public T on(LocalDate date) { + Objects.requireNonNull(date, "date"); + return on(ZonedDateTime.of(date, LocalTime.MIDNIGHT, dateTime.getZone())); + } + + @Override + public T on(Instant instant) { + Objects.requireNonNull(instant, "instant"); + return on(ZonedDateTime.ofInstant(instant, dateTime.getZone())); + } + + @Override + public T on(int year, int month, int date, int hour, int minute, int second) { + return on(ZonedDateTime.of(year, month, date, hour, minute, second, 0, dateTime.getZone())); + } + + @Override + public T now() { + return on(ZonedDateTime.now(dateTime.getZone())); + } + + @Override + public T plusDays(int days) { + return on(dateTime.plusDays(days)); + } + + @Override + public T midnight() { + return on(dateTime.truncatedTo(ChronoUnit.DAYS)); + } + + @Override + public T timezone(ZoneId tz) { + Objects.requireNonNull(tz, "tz"); + on(dateTime.withZoneSameLocal(tz)); + return (T) this; + } + + @Override + public T latitude(double lat) { + if (lat < -90.0 || lat > 90.0) { + throw new IllegalArgumentException("Latitude out of range, -90.0 <= " + lat + " <= 90.0"); + } + this.lat = lat; + return (T) this; + } + + @Override + public T longitude(double lng) { + if (lng < -180.0 || lng > 180.0) { + throw new IllegalArgumentException("Longitude out of range, -180.0 <= " + lng + " <= 180.0"); + } + this.lng = lng; + return (T) this; + } + + @Override + public T elevation(double h) { + this.elevation = max(h, 0.0); + return (T) this; + } + + @Override + public T sameTimeAs(TimeParameter t) { + if (!(t instanceof BaseBuilder)) { + throw new IllegalArgumentException("Cannot read the TimeParameter"); + } + this.dateTime = ((BaseBuilder) t).dateTime; + return (T) this; + } + + @Override + public T sameLocationAs(LocationParameter l) { + if (!(l instanceof BaseBuilder)) { + throw new IllegalArgumentException("Cannot read the LocationParameter"); + } + BaseBuilder origin = (BaseBuilder) l; + this.lat = origin.lat; + this.lng = origin.lng; + this.elevation = origin.elevation; + return (T) this; + } + + @Override + public T copy() { + try { + return (T) clone(); + } catch (CloneNotSupportedException ex) { + throw new RuntimeException(ex); // Should never be thrown anyway + } + } + + /** + * Returns the longitude. + * + * @return Longitude, in degrees. + */ + public double getLongitude() { + if (lng == null) { + throw new IllegalStateException("longitude is not set"); + } + return lng; + } + + /** + * Returns the latitude. + * + * @return Latitude, in degrees. + */ + public double getLatitude() { + if (lat == null) { + throw new IllegalStateException("latitude is not set"); + } + return lat; + } + + /** + * Returns the longitude. + * + * @return Longitude, in radians. + */ + public double getLongitudeRad() { + return toRadians(getLongitude()); + } + + /** + * Returns the latitude. + * + * @return Latitude, in radians. + */ + public double getLatitudeRad() { + return toRadians(getLatitude()); + } + + /** + * Returns the elevation, in meters above sea level. + * + * @return Elevation, meters above sea level + */ + public double getElevation() { + return elevation; + } + + /** + * Returns the {@link JulianDate} to be used. + * + * @return {@link JulianDate} + */ + public JulianDate getJulianDate() { + return new JulianDate(dateTime); + } + + /** + * Returns {@code true} if a geolocation has been set. + * + * @since 3.9 + */ + public boolean hasLocation() { + return lat != null && lng != null; + } + + /** + * Unset the geolocation. + * + * @since 3.9 + */ + public void clearLocation() { + lat = null; + lng = null; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/ExtendedMath.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/ExtendedMath.java new file mode 100644 index 0000000..8141fda --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/ExtendedMath.java @@ -0,0 +1,275 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.PI; +import static java.lang.Math.abs; +import static java.lang.Math.acos; +import static java.lang.Math.asin; +import static java.lang.Math.round; +import static java.lang.Math.signum; +import static java.lang.Math.tan; +import static java.lang.Math.toDegrees; +import static java.lang.Math.toRadians; + +import java.util.Comparator; +import java.util.function.Function; + +/** + * Contains constants and mathematical operations that are not available in {@link Math}. + */ +public final class ExtendedMath { + + /** + * PI * 2 + */ + public static final double PI2 = PI * 2.0; + + /** + * Arc-Seconds per Radian. + */ + public static final double ARCS = toDegrees(3600.0); + + /** + * Mean radius of the earth, in kilometers. + */ + public static final double EARTH_MEAN_RADIUS = 6371.0; + + /** + * Refraction at the horizon, in radians. + */ + public static final double REFRACTION_AT_HORIZON = PI / (tan(toRadians(7.31 / 4.4)) * 10800.0); + + private ExtendedMath() { + // utility class without constructor + } + + /** + * Returns the decimal part of a value. + * + * @param a + * Value + * @return Fraction of that value. It has the same sign as the input value. + */ + public static double frac(double a) { + return a % 1.0; + } + + /** + * Performs a safe check if the given double is actually zero (0.0). + *

+ * Note that "almost zero" returns {@code false}, so this method should not be used + * for comparing calculation results to zero. + * + * @param d + * double to check for zero. + * @return {@code true} if the value was zero, or negative zero. + */ + public static boolean isZero(double d) { + // This should keep squid:S1244 silent... + return !Double.isNaN(d) && round(signum(d)) == 0L; + } + + /** + * Converts equatorial coordinates to horizontal coordinates. + * + * @param tau + * Hour angle (radians) + * @param dec + * Declination (radians) + * @param dist + * Distance of the object + * @param lat + * Latitude of the observer (radians) + * @return {@link Vector} containing the horizontal coordinates + */ + public static Vector equatorialToHorizontal(double tau, double dec, double dist, double lat) { + return Matrix.rotateY(PI / 2.0 - lat).multiply(Vector.ofPolar(tau, dec, dist)); + } + + /** + * Creates a rotational {@link Matrix} for converting equatorial to ecliptical + * coordinates. + * + * @param t + * {@link JulianDate} to use + * @return {@link Matrix} for converting equatorial to ecliptical coordinates + */ + public static Matrix equatorialToEcliptical(JulianDate t) { + double jc = t.getJulianCentury(); + double eps = toRadians(23.43929111 - (46.8150 + (0.00059 - 0.001813 * jc) * jc) * jc / 3600.0); + return Matrix.rotateX(eps); + } + + /** + * Returns the parallax for objects at the horizon. + * + * @param elevation + * Observer's elevation, in meters above sea level. Must not be negative. + * @param distance + * Distance of the object, in kilometers. + * @return parallax, in radians + */ + public static double parallax(double elevation, double distance) { + return asin(EARTH_MEAN_RADIUS / distance) + - acos(EARTH_MEAN_RADIUS / (EARTH_MEAN_RADIUS + (elevation / 1000.0))); + } + + /** + * Calculates the atmospheric refraction of an object at the given apparent altitude. + *

+ * The result is only valid for positive altitude angles. If negative, 0.0 is + * returned. + *

+ * Assumes an atmospheric pressure of 1010 hPa and a temperature of 10 °C. + * + * @param ha + * Apparent altitude, in radians. + * @return Refraction at this altitude + * @see Wikipedia: + * Atmospheric Refraction + */ + public static double apparentRefraction(double ha) { + if (ha < 0.0) { + return 0.0; + } + + if (isZero(ha)) { + return REFRACTION_AT_HORIZON; + } + + return PI / (tan(toRadians(ha + (7.31 / (ha + 4.4)))) * 10800.0); + } + + /** + * Calculates the atmospheric refraction of an object at the given altitude. + *

+ * The result is only valid for positive altitude angles. If negative, 0.0 is + * returned. + *

+ * Assumes an atmospheric pressure of 1010 hPa and a temperature of 10 °C. + * + * @param h + * True altitude, in radians. + * @return Refraction at this altitude + * @see Wikipedia: + * Atmospheric Refraction + */ + public static double refraction(double h) { + if (h < 0.0) { + return 0.0; + } + + // refraction formula, converted to radians + return 0.000296706 / tan(h + 0.00312537 / (h + 0.0890118)); + } + + /** + * Converts dms to double. + * + * @param d + * Degrees. Sign is used for result. + * @param m + * Minutes. Sign is ignored. + * @param s + * Seconds and fractions. Sign is ignored. + * @return angle, in degrees + */ + public static double dms(int d, int m, double s) { + double sig = d < 0 ? -1.0 : 1.0; + return sig * ((abs(s) / 60.0 + abs(m)) / 60.0 + abs(d)); + } + + /** + * Locates the true maximum within the given time frame. + * + * @param time + * Base time + * @param frame + * Time frame, which is added to and subtracted from the base time for the + * interval + * @param depth + * Maximum recursion depth. For each recursion, the function is invoked once. + * @param f + * Function to be used for calculation + * @return time of the true maximum + */ + public static double readjustMax(double time, double frame, int depth, Function f) { + double left = time - frame; + double right = time + frame; + double leftY = f.apply(left); + double rightY = f.apply(right); + + return readjustInterval(left, right, leftY, rightY, depth, f, Double::compare); + } + + /** + * Locates the true minimum within the given time frame. + * + * @param time + * Base time + * @param frame + * Time frame, which is added to and subtracted from the base time for the + * interval + * @param depth + * Maximum recursion depth. For each recursion, the function is invoked once. + * @param f + * Function to be used for calculation + * @return time of the true minimum + */ + public static double readjustMin(double time, double frame, int depth, Function f) { + double left = time - frame; + double right = time + frame; + double leftY = f.apply(left); + double rightY = f.apply(right); + + return readjustInterval(left, right, leftY, rightY, depth, f, (yl, yr) -> Double.compare(yr, yl)); + } + + /** + * Recursively find the true maximum/minimum within the given time frame. + * + * @param left + * Left interval border + * @param right + * Right interval border + * @param yl + * Function result at the left interval + * @param yr + * Function result at the right interval + * @param depth + * Maximum recursion depth. For each recursion, the function is invoked once. + * @param f + * Function to invoke + * @param cmp + * Comparator to decide whether the left or right side of the interval half is + * to be used + * @return Position of the approximated minimum/maximum + */ + private static double readjustInterval(double left, double right, double yl, double yr, int depth, + Function f, Comparator cmp) { + if (depth <= 0) { + return (cmp.compare(yl, yr) < 0) ? right : left; + } + + double middle = (left + right) / 2.0; + double ym = f.apply(middle); + if (cmp.compare(yl, yr) < 0) { + return readjustInterval(middle, right, ym, yr, depth - 1, f, cmp); + } else { + return readjustInterval(left, middle, yl, ym, depth - 1, f, cmp); + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/JulianDate.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/JulianDate.java new file mode 100644 index 0000000..989a5f5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/JulianDate.java @@ -0,0 +1,146 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.frac; +import static java.lang.Math.floor; +import static java.lang.Math.round; + + +import java.time.Instant; +import java.time.ZonedDateTime; +import java.util.Objects; + +/** + * This class contains a Julian Date representation of a date. + *

+ * Objects are immutable and threadsafe. + */ +public class JulianDate { + + private final ZonedDateTime dateTime; + private final double mjd; + + /** + * Creates a new {@link JulianDate}. + * + * @param time {@link ZonedDateTime} to use for the date. + */ + public JulianDate(ZonedDateTime time) { + dateTime = Objects.requireNonNull(time, "time"); + mjd = dateTime.toInstant().toEpochMilli() / 86400000.0 + 40587.0; + } + + /** + * Returns a {@link JulianDate} of the current date and the given hour. + * + * @param hour Hour of this date. This is a floating point value. Fractions are used + * for minutes and seconds. + * @return {@link JulianDate} instance. + */ + public JulianDate atHour(double hour) { + return new JulianDate(dateTime.plusSeconds(round(hour * 60.0 * 60.0))); + } + + /** + * Returns a {@link JulianDate} of the given modified Julian date. + * + * @param mjd Modified Julian Date + * @return {@link JulianDate} instance. + */ + public JulianDate atModifiedJulianDate(double mjd) { + Instant mjdi = Instant.ofEpochMilli(Math.round((mjd - 40587.0) * 86400000.0)); + return new JulianDate(ZonedDateTime.ofInstant(mjdi, dateTime.getZone())); + } + + /** + * Returns a {@link JulianDate} of the given Julian century. + * + * @param jc Julian Century + * @return {@link JulianDate} instance. + */ + public JulianDate atJulianCentury(double jc) { + return atModifiedJulianDate(jc * 36525.0 + 51544.5); + } + + /** + * Returns this {@link JulianDate} as {@link ZonedDateTime} object. + * + * @return {@link ZonedDateTime} of this {@link JulianDate}. + */ + public ZonedDateTime getDateTime() { + return dateTime; + } + + /** + * Returns the Modified Julian Date. + * + * @return Modified Julian Date, UTC. + */ + public double getModifiedJulianDate() { + return mjd; + } + + /** + * Returns the Julian Centuries. + * + * @return Julian Centuries, based on J2000 epoch, UTC. + */ + public double getJulianCentury() { + return (mjd - 51544.5) / 36525.0; + } + + /** + * Returns the Greenwich Mean Sidereal Time of this Julian Date. + * + * @return GMST + */ + public double getGreenwichMeanSiderealTime() { + final double secs = 86400.0; + + double mjd0 = floor(mjd); + double ut = (mjd - mjd0) * secs; + double t0 = (mjd0 - 51544.5) / 36525.0; + double t = (mjd - 51544.5) / 36525.0; + + double gmst = 24110.54841 + + 8640184.812866 * t0 + + 1.0027379093 * ut + + (0.093104 - 6.2e-6 * t) * t * t; + + return (PI2 / secs) * (gmst % secs); + } + + /** + * Returns the earth's true anomaly of the current date. + *

+ * A simple approximation is used here. + * + * @return True anomaly, in radians + */ + public double getTrueAnomaly() { + return PI2 * frac((dateTime.getDayOfYear() - 5.0) / 365.256363); + } + + @Override + public String toString() { + return String.format("%dd %02dh %02dm %02ds", + (long) mjd, + (long) (mjd * 24 % 24), + (long) (mjd * 24 * 60 % 60), + (long) (mjd * 24 * 60 * 60 % 60)); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Matrix.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Matrix.java new file mode 100644 index 0000000..c1b80dc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Matrix.java @@ -0,0 +1,287 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.cos; +import static java.lang.Math.sin; + +import java.util.Arrays; + +/** + * A three dimensional matrix. + *

+ * Objects are immutable and threadsafe. + */ +public class Matrix { + + private final double[] mx; + + private Matrix() { + mx = new double[9]; + } + + private Matrix(double... values) { + if (values == null || values.length != 9) { + throw new IllegalArgumentException("requires 9 values"); + } + mx = values; + } + + /** + * Creates an identity matrix. + * + * @return Identity {@link Matrix} + */ + public static Matrix identity() { + return new Matrix( + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0); + } + + /** + * Creates a matrix that rotates a vector by the given angle at the X axis. + * + * @param angle + * angle, in radians + * @return Rotation {@link Matrix} + */ + public static Matrix rotateX(double angle) { + double s = sin(angle); + double c = cos(angle); + return new Matrix( + 1.0, 0.0, 0.0, + 0.0, c, s, + 0.0, -s, c + ); + } + + /** + * Creates a matrix that rotates a vector by the given angle at the Y axis. + * + * @param angle + * angle, in radians + * @return Rotation {@link Matrix} + */ + public static Matrix rotateY(double angle) { + double s = sin(angle); + double c = cos(angle); + return new Matrix( + c, 0.0, -s, + 0.0, 1.0, 0.0, + s, 0.0, c + ); + } + + /** + * Creates a matrix that rotates a vector by the given angle at the Z axis. + * + * @param angle + * angle, in radians + * @return Rotation {@link Matrix} + */ + public static Matrix rotateZ(double angle) { + double s = sin(angle); + double c = cos(angle); + return new Matrix( + c, s, 0.0, + -s, c, 0.0, + 0.0, 0.0, 1.0 + ); + } + + /** + * Transposes this matrix. + * + * @return {@link Matrix} that is a transposition of this matrix. + */ + public Matrix transpose() { + Matrix result = new Matrix(); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + result.set(i, j, get(j, i)); + } + } + return result; + } + + /** + * Negates this matrix. + * + * @return {@link Matrix} that is a negation of this matrix. + */ + public Matrix negate() { + Matrix result = new Matrix(); + for (int i = 0; i < 9; i++) { + result.mx[i] = -mx[i]; + } + return result; + } + + /** + * Adds a matrix to this matrix. + * + * @param right + * {@link Matrix} to add + * @return {@link Matrix} that is a sum of both matrices + */ + public Matrix add(Matrix right) { + Matrix result = new Matrix(); + for (int i = 0; i < 9; i++) { + result.mx[i] = mx[i] + right.mx[i]; + } + return result; + } + + /** + * Subtracts a matrix from this matrix. + * + * @param right + * {@link Matrix} to subtract + * @return {@link Matrix} that is the difference of both matrices + */ + public Matrix subtract(Matrix right) { + Matrix result = new Matrix(); + for (int i = 0; i < 9; i++) { + result.mx[i] = mx[i] - right.mx[i]; + } + return result; + } + + /** + * Multiplies two matrices. + * + * @param right + * {@link Matrix} to multiply with + * @return {@link Matrix} that is the product of both matrices + */ + public Matrix multiply(Matrix right) { + Matrix result = new Matrix(); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + double scalp = 0.0; + for (int k = 0; k < 3; k++) { + scalp += get(i, k) * right.get(k, j); + } + result.set(i, j, scalp); + } + } + return result; + } + + /** + * Performs a scalar multiplication. + * + * @param scalar + * Scalar to multiply with + * @return {@link Matrix} that is the scalar product + */ + public Matrix multiply(double scalar) { + Matrix result = new Matrix(); + for (int i = 0; i < 9; i++) { + result.mx[i] = mx[i] * scalar; + } + return result; + } + + /** + * Applies this matrix to a {@link Vector}. + * + * @param right + * {@link Vector} to multiply with + * @return {@link Vector} that is the product of this matrix and the given vector + */ + public Vector multiply(Vector right) { + double[] vec = new double[] {right.getX(), right.getY(), right.getZ()}; + double[] result = new double[3]; + + for (int i = 0; i < 3; i++) { + double scalp = 0.0; + for (int j = 0; j < 3; j++) { + scalp += get(i, j) * vec[j]; + } + result[i] = scalp; + } + + return new Vector(result); + } + + /** + * Gets a value from the matrix. + * + * @param r + * Row number (0..2) + * @param c + * Column number (0..2) + * @return Value at that position + */ + public double get(int r, int c) { + if (r < 0 || r > 2 || c < 0 || c > 2) { + throw new IllegalArgumentException("row/column out of range: " + r + ":" + c); + } + return mx[r * 3 + c]; + } + + /** + * Changes a value in the matrix. As a {@link Matrix} object is immutable from the + * outside, this method is private. + * + * @param r + * Row number (0..2) + * @param c + * Column number (0..2) + * @param v + * New value + */ + private void set(int r, int c, double v) { + if (r < 0 || r > 2 || c < 0 || c > 2) { + throw new IllegalArgumentException("row/column out of range: " + r + ":" + c); + } + mx[r * 3 + c] = v; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof Matrix)) { + return false; + } + return Arrays.equals(mx, ((Matrix) obj).mx); + } + + @Override + public int hashCode() { + return Arrays.hashCode(mx); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (int ix = 0; ix < 9; ix++) { + if (ix % 3 == 0) { + sb.append('['); + } + sb.append(mx[ix]); + if (ix % 3 == 2) { + sb.append(']'); + } + if (ix < 8) { + sb.append(", "); + } + } + sb.append(']'); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Moon.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Moon.java new file mode 100644 index 0000000..d987162 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Moon.java @@ -0,0 +1,154 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.ARCS; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToEcliptical; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToHorizontal; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.frac; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.parallax; +import static java.lang.Math.asin; +import static java.lang.Math.cos; +import static java.lang.Math.sin; + + +/** + * Calculations and constants for the Moon. + * + * @see "Astronomy on the Personal Computer, 4th edition + * (Oliver Montenbruck, Thomas Pfleger) - + * ISBN 978-3-540-67221-0" + */ +public final class Moon { + + private static final double MOON_MEAN_RADIUS = 1737.1; + + private Moon() { + // Utility class without constructor + } + + /** + * Calculates the equatorial position of the moon. + * + * @param date {@link JulianDate} to be used + * @return {@link Vector} of equatorial moon position + */ + public static Vector positionEquatorial(JulianDate date) { + double T = date.getJulianCentury(); + double L0 = frac(0.606433 + 1336.855225 * T); + double l = PI2 * frac(0.374897 + 1325.552410 * T); + double ls = PI2 * frac(0.993133 + 99.997361 * T); + double D = PI2 * frac(0.827361 + 1236.853086 * T); + double F = PI2 * frac(0.259086 + 1342.227825 * T); + double D2 = 2.0 * D; + double l2 = 2.0 * l; + double F2 = 2.0 * F; + + double dL = 22640.0 * sin(l) + - 4586.0 * sin(l - D2) + + 2370.0 * sin(D2) + + 769.0 * sin(l2) + - 668.0 * sin(ls) + - 412.0 * sin(F2) + - 212.0 * sin(l2 - D2) + - 206.0 * sin(l + ls - D2) + + 192.0 * sin(l + D2) + - 165.0 * sin(ls - D2) + - 125.0 * sin(D) + - 110.0 * sin(l + ls) + + 148.0 * sin(l - ls) + - 55.0 * sin(F2 - D2); + + double S = F + (dL + 412.0 * sin(F2) + 541.0 * sin(ls)) / ARCS; + double h = F - D2; + double N = -526.0 * sin(h) + + 44.0 * sin(l + h) + - 31.0 * sin(-l + h) + - 23.0 * sin(ls + h) + + 11.0 * sin(-ls + h) + - 25.0 * sin(-l2 + F) + + 21.0 * sin(-l + F); + + double l_Moon = PI2 * frac(L0 + dL / 1296.0e3); + double b_Moon = (18520.0 * sin(S) + N) / ARCS; + + double dt = 385000.5584 + - 20905.3550 * cos(l) + - 3699.1109 * cos(D2 - l) + - 2955.9676 * cos(D2) + - 569.9251 * cos(l2); + + return Vector.ofPolar(l_Moon, b_Moon, dt); + } + + /** + * Calculates the geocentric position of the moon. + * + * @param date {@link JulianDate} to be used + * @return {@link Vector} of geocentric moon position + */ + public static Vector position(JulianDate date) { + Matrix rotateMatrix = equatorialToEcliptical(date).transpose(); + return rotateMatrix.multiply(positionEquatorial(date)); + } + + /** + * Calculates the horizontal position of the moon. + * + * @param date {@link JulianDate} to be used + * @param lat Latitude, in radians + * @param lng Longitute, in radians + * @return {@link Vector} of horizontal moon position + */ + public static Vector positionHorizontal(JulianDate date, double lat, double lng) { + Vector mc = position(date); + double h = date.getGreenwichMeanSiderealTime() + lng - mc.getPhi(); + return equatorialToHorizontal(h, mc.getTheta(), mc.getR(), lat); + } + + /** + * Calculates the topocentric position of the moon. + *

+ * Atmospheric refraction is not taken into account. + * + * @param date {@link JulianDate} to be used + * @param lat Latitude, in radians + * @param lng Longitute, in radians + * @param elev Elevation, in meters + * @return {@link Vector} of topocentric moon position + * @since 3.9 + */ + public static Vector positionTopocentric(JulianDate date, double lat, double lng, double elev) { + Vector pos = positionHorizontal(date, lat, lng); + return Vector.ofPolar( + pos.getPhi(), + pos.getTheta() - parallax(elev, pos.getR()), + pos.getR() + ); + } + + /** + * Returns the angular radius of the moon. + * + * @param distance Distance of the moon, in kilometers. + * @return Angular radius of the moon, in radians. + * @see Wikipedia: Angular + * Diameter + */ + public static double angularRadius(double distance) { + return asin(MOON_MEAN_RADIUS / distance); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Pegasus.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Pegasus.java new file mode 100644 index 0000000..c73d401 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Pegasus.java @@ -0,0 +1,76 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2018 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.abs; + +import java.util.function.Function; + +/** + * Finds the root of a function by using the Pegasus method. + * + * @see regula falsi + */ +public class Pegasus { + + private static final int MAX_ITERATIONS = 30; + + /** + * Find the root of the given function within the boundaries. + * + * @param lower Lower boundary + * @param upper Upper boundary + * @param accuracy Desired accuracy + * @param f Function to be used for calculation + * @return root that was found + * @throws ArithmeticException if the root could not be found in the given accuracy within + * {@value #MAX_ITERATIONS} iterations. + */ + public static Double calculate(double lower, double upper, double accuracy, Function f) { + double x1 = lower; + double x2 = upper; + + double f1 = f.apply(x1); + double f2 = f.apply(x2); + + if (f1 * f2 >= 0.0) { + throw new ArithmeticException("No root within the given boundaries"); + } + + int i = MAX_ITERATIONS; + + while (i-- > 0) { + double x3 = x2 - f2 / ((f2 - f1) / (x2 - x1)); + double f3 = f.apply(x3); + + if (f3 * f2 <= 0.0) { + x1 = x2; + f1 = f2; + x2 = x3; + f2 = f3; + } else { + f1 = f1 * f2 / (f2 + f3); + x2 = x3; + f2 = f3; + } + + if (abs(x2 - x1) <= accuracy) { + return abs(f1) < abs(f2) ? x1 : x2; + } + } + + throw new ArithmeticException("Maximum number of iterations exceeded"); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/QuadraticInterpolation.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/QuadraticInterpolation.java new file mode 100644 index 0000000..58db08c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/QuadraticInterpolation.java @@ -0,0 +1,125 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.abs; +import static java.lang.Math.sqrt; + +/** + * Calculates the roots and extremum of a quadratic equation. + */ +public class QuadraticInterpolation { + + private final double xe; + private final double ye; + private final double root1; + private final double root2; + private final int nRoot; + private final boolean maximum; + + /** + * Creates a new quadratic equation. + * + * @param yMinus y at x == -1 + * @param y0 y at x == 0 + * @param yPlus y at x == 1 + */ + public QuadraticInterpolation(double yMinus, double y0, double yPlus) { + double a = 0.5 * (yPlus + yMinus) - y0; + double b = 0.5 * (yPlus - yMinus); + double c = y0; + + xe = -b / (2.0 * a); + ye = (a * xe + b) * xe + c; + maximum = a < 0.0; + double dis = b * b - 4.0 * a * c; + + int rootCount = 0; + + if (dis >= 0.0) { + double dx = 0.5 * sqrt(dis) / abs(a); + root1 = xe - dx; + root2 = xe + dx; + + if (abs(root1) <= 1.0) { + rootCount++; + } + + if (abs(root2) <= 1.0) { + rootCount++; + } + } else { + root1 = Double.NaN; + root2 = Double.NaN; + } + + nRoot = rootCount; + } + + /** + * Returns X of extremum. Can be outside [-1 .. 1]. + * + * @return X + */ + public double getXe() { + return xe; + } + + /** + * Returns the Y value at the extremum. + * + * @return Y + */ + public double getYe() { + return ye; + } + + /** + * Returns the first root that was found. + * + * @return X of first root + */ + public double getRoot1() { + return root1 < -1.0 ? root2 : root1; + } + + /** + * Returns the second root that was found. + * + * @return X of second root + */ + public double getRoot2() { + return root2; + } + + /** + * Returns the number of roots found in [-1 .. 1]. + * + * @return Number of roots + */ + public int getNumberOfRoots() { + return nRoot; + } + + /** + * Returns whether the extremum is a minimum or a maximum. + * + * @return {@code true}: Extremum at xe is a maximum. {@code false}: Extremum at xe is + * a minimum. + */ + public boolean isMaximum() { + return maximum; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Sun.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Sun.java new file mode 100644 index 0000000..640fb55 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Sun.java @@ -0,0 +1,117 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToEcliptical; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToHorizontal; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.frac; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.parallax; +import static java.lang.Math.asin; +import static java.lang.Math.cos; +import static java.lang.Math.sin; + +/** + * Calculations and constants for the Sun. + * + * @see "Astronomy on the Personal Computer, 4th edition + * (Oliver Montenbruck, Thomas Pfleger) - + * ISBN 978-3-540-67221-0" + */ +public final class Sun { + + private static final double SUN_DISTANCE = 149598000.0; + private static final double SUN_MEAN_RADIUS = 695700.0; + + private Sun() { + // Utility class without constructor + } + + /** + * Calculates the equatorial position of the sun. + * + * @param date {@link JulianDate} to be used + * @return {@link Vector} containing the sun position + */ + public static Vector positionEquatorial(JulianDate date) { + double T = date.getJulianCentury(); + double M = PI2 * frac(0.993133 + 99.997361 * T); + double L = PI2 * frac(0.7859453 + M / PI2 + + (6893.0 * sin(M) + 72.0 * sin(2.0 * M) + 6191.2 * T) / 1296.0e3); + + double d = SUN_DISTANCE + * (1 - 0.016718 * cos(date.getTrueAnomaly())); + + return Vector.ofPolar(L, 0.0, d); + } + + /** + * Calculates the geocentric position of the sun. + * + * @param date {@link JulianDate} to be used + * @return {@link Vector} containing the sun position + */ + public static Vector position(JulianDate date) { + Matrix rotateMatrix = equatorialToEcliptical(date).transpose(); + return rotateMatrix.multiply(positionEquatorial(date)); + } + + /** + * Calculates the horizontal position of the sun. + * + * @param date {@link JulianDate} to be used + * @param lat Latitude, in radians + * @param lng Longitute, in radians + * @return {@link Vector} of horizontal sun position + */ + public static Vector positionHorizontal(JulianDate date, double lat, double lng) { + Vector mc = position(date); + double h = date.getGreenwichMeanSiderealTime() + lng - mc.getPhi(); + return equatorialToHorizontal(h, mc.getTheta(), mc.getR(), lat); + } + + /** + * Calculates the topocentric position of the sun. + *

+ * Atmospheric refraction is not taken into account. + * + * @param date {@link JulianDate} to be used + * @param lat Latitude, in radians + * @param lng Longitute, in radians + * @param elev Elevation, in meters + * @return {@link Vector} of topocentric sun position + * @since 3.9 + */ + public static Vector positionTopocentric(JulianDate date, double lat, double lng, double elev) { + Vector pos = positionHorizontal(date, lat, lng); + return Vector.ofPolar( + pos.getPhi(), + pos.getTheta() - parallax(elev, pos.getR()), + pos.getR() + ); + } + + /** + * Returns the angular radius of the sun. + * + * @param distance Distance of the sun, in kilometers. + * @return Angular radius of the sun, in radians. + * @see Wikipedia: Angular + * Diameter + */ + public static double angularRadius(double distance) { + return asin(SUN_MEAN_RADIUS / distance); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Vector.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Vector.java new file mode 100644 index 0000000..eea316e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Vector.java @@ -0,0 +1,330 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.isZero; +import static java.lang.Math.atan2; +import static java.lang.Math.cos; +import static java.lang.Math.sin; +import static java.lang.Math.sqrt; + + +import androidx.annotation.Nullable; + + +/** + * A three dimensional vector. + *

+ * Objects are is immutable and threadsafe. + */ +public class Vector { + + private final double x; + private final double y; + private final double z; + private final Polar polar = new Polar(); + + /** + * Creates a new {@link Vector} of the given cartesian coordinates. + * + * @param x + * X coordinate + * @param y + * Y coordinate + * @param z + * Z coordinate + */ + public Vector(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Creates a new {@link Vector} of the given cartesian coordinates. + * + * @param d + * Array of coordinates, must have 3 elements + */ + public Vector(double[] d) { + if (d.length != 3) { + throw new IllegalArgumentException("invalid vector length"); + } + this.x = d[0]; + this.y = d[1]; + this.z = d[2]; + } + + /** + * Creates a new {@link Vector} of the given polar coordinates, with a radial distance + * of 1. + * + * @param φ + * Azimuthal Angle + * @param θ + * Polar Angle + * @return Created {@link Vector} + */ + public static Vector ofPolar(double φ, double θ) { + return ofPolar(φ, θ, 1.0); + } + + /** + * Creates a new {@link Vector} of the given polar coordinates. + * + * @param φ + * Azimuthal Angle + * @param θ + * Polar Angle + * @param r + * Radial Distance + * @return Created {@link Vector} + */ + public static Vector ofPolar(double φ, double θ, double r) { + double cosθ = cos(θ); + Vector result = new Vector( + r * cos(φ) * cosθ, + r * sin(φ) * cosθ, + r * sin(θ) + ); + result.polar.setPolar(φ, θ, r); + return result; + } + + /** + * Returns the cartesian X coordinate. + */ + public double getX() { + return x; + } + + /** + * Returns the cartesian Y coordinate. + */ + public double getY() { + return y; + } + + /** + * Returns the cartesian Z coordinate. + */ + public double getZ() { + return z; + } + + /** + * Returns the azimuthal angle (φ) in radians. + */ + public double getPhi() { + return polar.getPhi(); + } + + /** + * Returns the polar angle (θ) in radians. + */ + public double getTheta() { + return polar.getTheta(); + } + + /** + * Returns the polar radial distance (r). + */ + public double getR() { + return polar.getR(); + } + + /** + * Returns a {@link Vector} that is the sum of this {@link Vector} and the given + * {@link Vector}. + * + * @param vec + * {@link Vector} to add + * @return Resulting {@link Vector} + */ + public Vector add(Vector vec) { + return new Vector( + x + vec.x, + y + vec.y, + z + vec.z + ); + } + + /** + * Returns a {@link Vector} that is the difference of this {@link Vector} and the + * given {@link Vector}. + * + * @param vec + * {@link Vector} to subtract + * @return Resulting {@link Vector} + */ + public Vector subtract(Vector vec) { + return new Vector( + x - vec.x, + y - vec.y, + z - vec.z + ); + } + + /** + * Returns a {@link Vector} that is the scalar product of this {@link Vector} and the + * given scalar. + * + * @param scalar + * Scalar to multiply + * @return Resulting {@link Vector} + */ + public Vector multiply(double scalar) { + return new Vector( + x * scalar, + y * scalar, + z * scalar + ); + } + + /** + * Returns the negation of this {@link Vector}. + * + * @return Resulting {@link Vector} + */ + public Vector negate() { + return new Vector( + -x, + -y, + -z + ); + } + + /** + * Returns a {@link Vector} that is the cross product of this {@link Vector} and the + * given {@link Vector}. + * + * @param right + * {@link Vector} to multiply + * @return Resulting {@link Vector} + */ + public Vector cross(Vector right) { + return new Vector( + y * right.z - z * right.y, + z * right.x - x * right.z, + x * right.y - y * right.x + ); + } + + /** + * Returns the dot product of this {@link Vector} and the given {@link Vector}. + * + * @param right + * {@link Vector} to multiply + * @return Resulting dot product + */ + public double dot(Vector right) { + return x * right.x + y * right.y + z * right.z; + } + + /** + * Returns the norm of this {@link Vector}. + * + * @return Norm of this vector + */ + public double norm() { + return sqrt(dot(this)); + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof Vector)) { + return false; + } + + Vector vec = (Vector) obj; + return Double.compare(x, vec.x) == 0 + && Double.compare(y, vec.y) == 0 + && Double.compare(z, vec.z) == 0; + } + + @Override + public int hashCode() { + return Double.valueOf(x).hashCode() + ^ Double.valueOf(y).hashCode() + ^ Double.valueOf(z).hashCode(); + } + + @Override + public String toString() { + return "(x=" + x + ", y=" + y + ", z=" + z + ")"; + } + + /** + * Helper class for lazily computing the polar coordinates in an immutable Vector + * object. + */ + private class Polar { + private @Nullable Double φ = null; + private @Nullable Double θ = null; + private @Nullable Double r = null; + + /** + * Sets polar coordinates. + * + * @param φ + * Phi + * @param θ + * Theta + * @param r + * R + */ + public synchronized void setPolar(double φ, double θ, double r) { + this.φ = φ; + this.θ = θ; + this.r = r; + } + + public synchronized double getPhi() { + if (φ == null) { + if (isZero(x) && isZero(y)) { + φ = 0.0; + } else { + φ = atan2(y, x); + } + + if (φ < 0.0) { + φ += PI2; + } + } + return φ; + } + + public synchronized double getTheta() { + if (θ == null) { + double ρSqr = x * x + y * y; + + if (isZero(z) && isZero(ρSqr)) { + θ = 0.0; + } else { + θ = atan2(z, sqrt(ρSqr)); + } + } + return θ; + } + + public synchronized double getR() { + if (r == null) { + r = sqrt(x * x + y * y + z * z); + } + return r; + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelCreateOrEditRouteVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelCreateOrEditRouteVm.kt new file mode 100644 index 0000000..cc300c1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelCreateOrEditRouteVm.kt @@ -0,0 +1,271 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import android.content.Context +import android.text.TextUtils +import androidx.annotation.WorkerThread +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import androidx.room.withTransaction +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.fragment.LevelRouteCreateEditFragment +import com.bingce.controlnetwork.func.level.util.LevelStationUtilTj +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigOperate +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDb +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.dialog.loading.LoadingUtil +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelCreateOrEditRouteVm : ViewModel() { + + fun showCreateOrEditDialog( + context: Context, + projectId: String, + routeId: String? + ) { + val title = if (routeId == null) + Tools.getString(R.string.create_segment_survey) + else Tools.getString(R.string.edit_segment_survey) + + LevelRouteCreateEditFragment.start(context, projectId, routeId, title) +// LevelRouteCreateEditDialog.start(projectId, routeId, childFragmentManager) + } + + /** + * 新建路线 存默认路线 + * 编辑路线 + */ + private fun startSaveRoute( + levelRouteSave: LevelRouteSave, + callBack: (Boolean) -> Unit + ) { + viewModelScope.launch(Dispatchers.IO) { + LevelingDb.getInstance().withTransaction { + try { + if (levelRouteSave.routeId != null) { + editRoute(levelRouteSave) + } else { + createRoute(levelRouteSave) + } + + dismissLoading() + mainBack(callBack, true) + } catch (e: Exception) { + e.printStackTrace() + dismissLoading() + mainBack(callBack, false) + } + } + } + } + + private suspend fun mainBack(callBack: (Boolean) -> Unit, isSuccess: Boolean) { + withContext(Dispatchers.Main) { + callBack(isSuccess) + } + } + + private suspend fun editRoute(levelRouteSave: LevelRouteSave) { + val routeRecord = + LevelingDbFactory.instance.levelDataSource.getById(levelRouteSave.routeId) + routeRecord?.let { + //编辑路线的时候先把路线下的所有测站都删除 + deleteRouteStation(it.getId()) + + it.routeName = levelRouteSave.routeName + it.startPointId = levelRouteSave.startPointId + it.endPointId = levelRouteSave.endPointId + it.observationDirection = levelRouteSave.observationDirection + it.levelingMeasureOrder = levelRouteSave.levelingMeasureOrder + + //更新路线 + LevelingDbFactory.instance.levelDataSource.update(it) + //创建测站 + createRouteStation(it.projectId, it.getId(), levelRouteSave.startPointId) + } + } + + /** + * 删除路线下的所有测站 + */ + private fun deleteRouteStation(routeId: String) { + LevelingDbFactory.instance.stationDataSource.deleteByRouteId(routeId) + } + + @WorkerThread + private suspend fun createRoute( + levelRouteSave: LevelRouteSave + ) { + val routeRecord = + LevelRouteRecord.createRouteRecord( + levelRouteSave.projectId, + levelRouteSave.routeName, + levelRouteSave.startPointId, + levelRouteSave.endPointId, + levelRouteSave.observationDirection, + levelRouteSave.levelingMeasureOrder + ) + //存路线 + LevelingDbFactory.instance.levelDataSource.saveRecord(routeRecord) + + //创建测站 + createRouteStation( + levelRouteSave.projectId, + routeRecord.getId(), + levelRouteSave.startPointId + ) + + ConfigOperate.changeDefaultProjectAndRoute( + levelRouteSave.projectId, + routeRecord.getId() + ) + } + + private fun createRouteStation(projectId: String, routeId: String, startPointId: String) { + //创建测站 + LevelStationUtilTj.createStation(projectId, routeId, startPointId, true) + } + + fun startSave(context: Context, levelRouteSave: LevelRouteSave, callBack: (Boolean) -> Unit) { + showLoading(context) + viewModelScope.launch(Dispatchers.IO) { + val canEdit = checkCanEdit(levelRouteSave.projectId, levelRouteSave.routeId) + if (!canEdit) { + dismissLoading() + ToastUtils.showShort(R.string.route_has_data_not_edit_hint) + return@launch + } + + var startPoint = + SurveyorDatabaseFactory.instance.getPointDataSource() + .findByNameSync(levelRouteSave.startPointName, levelRouteSave.projectId) + if (startPoint == null) { + startPoint = + createPoint(levelRouteSave.projectId, levelRouteSave.startPointName!!, "") + //存数据库 + SurveyorDatabaseFactory.instance.getPointDataSource().saveSync(startPoint) + } + + var endPoint = + SurveyorDatabaseFactory.instance.getPointDataSource() + .findByNameSync(levelRouteSave.endPointName, levelRouteSave.projectId) + if (endPoint == null) { + endPoint = + createPoint(levelRouteSave.projectId, levelRouteSave.endPointName!!, "") + //存数据库 + SurveyorDatabaseFactory.instance.getPointDataSource().saveSync(endPoint) + } + + levelRouteSave.startPointId = startPoint.getId() + levelRouteSave.endPointId = endPoint.getId() + + startSaveRoute( + levelRouteSave, + callBack + ) + } + } + + private fun showLoading(context: Context) { + LoadingUtil.show(context, context.getString(R.string.loading)) + } + + private suspend fun dismissLoading() { + withContext(Dispatchers.Main) { + LoadingUtil.dismiss() + } + } + + /** + * @return + */ + @WorkerThread + private fun checkCanEdit(projectId: String, routeIdParam: String?): Boolean { + //路线有数据时候不能编辑 + val routeId = routeIdParam ?: return true + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getByIdSync(routeId) + if (routeRecord != null) { + val stationList = LevelingDbFactory.instance.getStationDataSource() + .getStationList(projectId, routeRecord.getId(), false) + if (stationList != null && stationList.isNotEmpty()) { + for (stationRecord in stationList) { + val recordCount = LevelingDbFactory.instance.getMeasureBackFrontDataSource() + .getCountByStationId(stationRecord.getId()) + if (recordCount > 0) { + return false + } + } + } + } + return true + } + + @WorkerThread + private fun createPoint(projectId: String, pointName: String, height: String): PointRecord { + return createPointRecord(projectId, pointName, height) + } + + private fun createPointRecord( + projectId: String, + pointText: String, + height: String + ): PointRecord { + val pointType = if (isKnownPoint(height)) { + PointRecord.TYPE_KNOWN_POINT + } else { + PointRecord.TYPE_UNKNOWN_POINT + } + val h: Double = stringToDouble(height) + return PointRecord.point( + projectId, + pointType, + pointText, + "", + 0.0, + 0.0, + 0.0, + "", + -1, + ) + } + + private fun isKnownPoint(height: String): Boolean { + val heightD: Double = stringToDouble(height) + return heightD != 0.0 + } + + private fun stringToDouble(value: String): Double { + return if (TextUtils.isEmpty(value)) { + 0.0 + } else value.toDouble() + } + + fun getEditRouteData(routeId: String, callBack: (LevelRouteSave) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + routeRecord?.let { + val result = LevelRouteSave() + result.observationDirection = it.observationDirection + result.routeName = it.routeName + + val startPoint = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(it.startPointId) + val endPoint = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(it.endPointId) + result.startPointName = startPoint?.name + result.endPointName = endPoint?.name + withContext(Dispatchers.Main) { + callBack(result) + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSelectExportVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSelectExportVm.kt new file mode 100644 index 0000000..6e93e6e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSelectExportVm.kt @@ -0,0 +1,72 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.widget.treeview.TreeNode +import com.bingce.controlnetwork.func.level.util.LevelStationUtilTj +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 水准选择导出 + */ +class LevelSelectExportVm : ViewModel() { + + fun initData(callBack: (TreeNode) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val root = TreeNode.root() + val projectList = + SurveyorDatabaseFactory.instance.projectDataSource.getListByProjectType( + ProjectTypeValue.LEVEL + ) + for (project in projectList) { + val projectNode = TreeNode(TreeNode.Value(project.projectName, project.id), 0) + root.addChild(projectNode) + val routeList = + LevelingDbFactory.instance.levelDataSource.getByProjectIdSync(project.id) + //当项目里没有路线的时候禁止选中 + if (routeList.isEmpty()) { + projectNode.isEnable = false + } + + for (route in routeList) { + + val routeNode = TreeNode(TreeNode.Value(route.routeName, route.id), 1) + projectNode.addChild(routeNode) + + val countFinish = LevelStationUtilTj.getStationFinishCount( + project.id, + route.id + ) + if (countFinish < 1) { + routeNode.isEnable = false + } else { + val isEnable = when (route.levelingMeasureOrder) { + LevelingMeasureOrder.A_BF, + LevelingMeasureOrder.A_BFFB, + LevelingMeasureOrder.A_FBBF, + LevelingMeasureOrder.SIM_BF, + LevelingMeasureOrder.SIM_BFFB -> { + countFinish % 2 == 0 + } + + else -> true + } + routeNode.isEnable = isEnable + } + } + } + + withContext(Dispatchers.Main) { + callBack(root) + } + + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelStationSettingVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelStationSettingVm.kt new file mode 100644 index 0000000..0bfc79b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelStationSettingVm.kt @@ -0,0 +1,151 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelStationSettingVm : ViewModel() { + private lateinit var routeId: String + private lateinit var stationId: String + + private lateinit var needSaveLevelRouteSave: LevelRouteSave + + val editLastDataLiveData = MutableLiveData() + + + fun getEditLastData(stationId: String) { + viewModelScope.launch(Dispatchers.IO) { + val record = + LevelingDbFactory.instance.stationSettingDataSource.getByStationId(stationId) + if (record != null) { + editLastDataLiveData.postValue(recordToLevelSave(record)) + return@launch + } + val stationSettingLastData = LevelStationSettingUtil.getStationSettingLastData() + if (stationSettingLastData.weather != null) { + editLastDataLiveData.postValue(stationSettingLastData) + return@launch + } + editLastDataLiveData.postValue(null) + } + } + + fun getInitCurrentTabPos(callBack: (Int) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val record = + LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + withContext(Dispatchers.Main) { + val pos = if (record?.weather != null) { + 1 + } else { + 0 + } + callBack(pos) + } + } + } + + fun initRouteStationId(routeId: String, stationId: String) { + this.routeId = routeId + this.stationId = stationId + } + + fun initHasTwoRuler(callBack: (Boolean) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val route = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + ?: return@launch + val hasTwoRuler = + route.levelingMeasureOrder == LevelingMeasureOrder.SIM_BF || route.levelingMeasureOrder == LevelingMeasureOrder.SIM_BFFB + withContext(Dispatchers.Main) { + callBack(hasTwoRuler) + } + } + } + + private fun recordToLevelSave(record: LevelingStationSettingRecord): LevelRouteSave { + return LevelRouteSave.createLastData( + record.watcher, + record.recorder, + record.examiner, + record.firstStationBackFootNumber, + record.firstStationFrontFootNumber, + record.firstStationBackFootNumber2, + record.firstStationFrontFootNumber2, + record.instrumentModel, + record.deviceNumber, + record.steelRuleParam, + record.rulerLengthProvingTemperature, + record.rulerCorrectionFactor, + record.rulerType, + record.rulerReceptType, + + record.temperature, + record.weather, + record.imaging, + record.sunDirection, + record.windDirection, + record.windSpeed, + record.roads, + record.soil + ) + } + + fun createNeedSaveLevelRouteSave(routeId: String, stationId: String) { + needSaveLevelRouteSave = LevelRouteSave() + needSaveLevelRouteSave.routeId = routeId + needSaveLevelRouteSave.stationId = stationId + } + + fun addInforDataToLevelRouteSave(needAdd: LevelRouteSave) { + needSaveLevelRouteSave.watcher = needAdd.watcher + needSaveLevelRouteSave.recorder = needAdd.recorder + needSaveLevelRouteSave.examiner = needAdd.examiner + needSaveLevelRouteSave.frontFootNumber = needAdd.frontFootNumber + needSaveLevelRouteSave.backFootNumber = needAdd.backFootNumber + needSaveLevelRouteSave.frontFootNumber2 = needAdd.frontFootNumber2 + needSaveLevelRouteSave.backFootNumber2 = needAdd.backFootNumber2 + needSaveLevelRouteSave.instrumentModel = needAdd.instrumentModel + needSaveLevelRouteSave.deviceNumber = needAdd.deviceNumber + needSaveLevelRouteSave.steelRuleParam = needAdd.steelRuleParam + needSaveLevelRouteSave.rulerLengthProvingTemperature = needAdd.rulerLengthProvingTemperature + needSaveLevelRouteSave.rulerCorrectionFactor = needAdd.rulerCorrectionFactor + needSaveLevelRouteSave.rulerType = needAdd.rulerType + needSaveLevelRouteSave.rulerReceptType = needAdd.rulerReceptType + } + + fun addConditionDataToLevelRouteSave(needAdd: LevelRouteSave) { + needSaveLevelRouteSave.temperature = needAdd.temperature + needSaveLevelRouteSave.weather = needAdd.weather + needSaveLevelRouteSave.imaging = needAdd.imaging + needSaveLevelRouteSave.sunDirection = needAdd.sunDirection + needSaveLevelRouteSave.windDirection = needAdd.windDirection + needSaveLevelRouteSave.windSpeed = needAdd.windSpeed + needSaveLevelRouteSave.roads = needAdd.roads + needSaveLevelRouteSave.soil = needAdd.soil + } + + fun save(isSaveEndStationToStationSetting: Boolean, callBack: () -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + LevelStationSettingUtil.saveStationSetting( + isSaveEndStationToStationSetting, + needSaveLevelRouteSave + ) + + LevelStationSettingUtil.saveStationSettingLastData(needSaveLevelRouteSave) + + withContext(Dispatchers.Main) { + callBack() + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorSubVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorSubVm.kt new file mode 100644 index 0000000..b9e5959 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorSubVm.kt @@ -0,0 +1,335 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import android.widget.TextView +import androidx.annotation.WorkerThread +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import androidx.room.withTransaction +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDb +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.measure.station.LevelingMeasureStationRecord +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord +import com.bingce.controlapphelper.datasource.database.leveling.tolerance.LevelingToleranceDetail +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.leveling.detaction.DetectionController +import com.bingce.controlapphelper.leveling.detaction.IDetectionHint +import com.bingce.controlapphelper.leveling.detaction.INextStation +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.controlapphelper.leveling.detaction.LevelingProcess +import com.bingce.controlapphelper.leveling.detaction.surveyorcache.SurveyorCacheData +import com.bingce.controlapphelper.model.B1 +import com.bingce.controlapphelper.model.B2 +import com.bingce.controlapphelper.model.F1 +import com.bingce.controlapphelper.model.F2 +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil +import com.bingce.controlapphelper.model.StationOddEven +import com.bingce.controlapphelper.util.SpannableStringUtil +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ItemLevelSuveyorSurveyorBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelSuveyorSubVm : ViewModel() { + + var projectId: String? = null//项目id + + val stationLiveData = MutableLiveData() + val surveyorCacheDataLiveData = MutableLiveData() + val measureStationLiveData = MutableLiveData() + + private var detectionHintI: IDetectionHint? = null + private var nextStationI: INextStation? = null + + private var process: LevelingProcess? = null + private var toleranceDetail: LevelingToleranceDetail? = null + + fun initData( + stationId: String, + detectionHintI: IDetectionHint, + nextStationI: INextStation? + ) { + this.detectionHintI = detectionHintI + this.nextStationI = nextStationI + viewModelScope.launch(Dispatchers.IO) { + val station = getStation(stationId) + + val project = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(station.projectId) + projectId = project.getId() + toleranceDetail = + LevelingDbFactory.instance.toleranceDetailDataSource.getRecordSync(project.toleranceId) + + refreshStationProcess(station) + } + } + + @WorkerThread + private fun refreshStationProcess(station: LevelingStationRecord?) { + if (toleranceDetail == null) { + ToastUtils.showShort("限差异常") + return + } + if (station == null) { + ToastUtils.showShort("测站异常") + return + } + + if (station.levelingMeasureOrder == null) { + setStationLevelOrder(station) + } + + process = DetectionController.createProcess( + viewModelScope, + station, + toleranceDetail!!, + detectionHintI, + nextStationI, + stationLiveData, + surveyorCacheDataLiveData, + measureStationLiveData + ) + } + + /** + * 接受数据 + */ + fun recieveData(data: LevelReceiveData) { + process?.receiveData(data) + } + + fun saveMeasureFrontPointId(pointId: String, callBack: () -> Unit) { + val station = stationLiveData.value + if (station != null && !LevelingMeasureOrderUtil.isMeasureBack(station)) { + viewModelScope.launch(Dispatchers.IO) { + station.frontSightPointId = pointId + LevelingDbFactory.instance.stationDataSource.update(station) + withContext(Dispatchers.Main) { + callBack() + } + } + } + } + + fun saveMeasureFrontPoint(point: PointRecord, callBack: () -> Unit) { + val station = stationLiveData.value + if (station != null) { + viewModelScope.launch(Dispatchers.IO) { + LevelingDb.getInstance().withTransaction { + SurveyorDatabaseFactory.instance.pointDataSource.saveSync(point) + station.frontSightPointId = point.getId() + LevelingDbFactory.instance.stationDataSource.update(station) + withContext(Dispatchers.Main) { + callBack() + } + } + } + } + } + + fun getMeasurePointName(station: LevelingStationRecord, callBack: (String) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val measurePointId = LevelingMeasureOrderUtil.getMeasurePointId(station) + val name = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(measurePointId)?.name + withContext(Dispatchers.Main) { + callBack(name ?: "") + } + } + } + + /** + * 回退 + */ + fun startRollBack() { + process?.startRollBack() + } + + fun reMeasureStation() { + process?.dealReMeasureStation() + } + + fun getZ(callBack: (Double) -> Unit) { + stationLiveData.value?.let { stationRecord -> + viewModelScope.launch(Dispatchers.IO) { + val routeRecord = + LevelingDbFactory.instance.levelDataSource.getByIdSync(stationRecord.routeId) + val startPointHeight = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.startPointId) + ?.getZ() + ?: 0.0 + withContext(Dispatchers.Main) { + callBack(startPointHeight) + } + } + } + } + + fun getCurrentOrderText(stationRecord: LevelingStationRecord): CharSequence { + val textByLevelingMeasureOrder = + LevelingMeasureOrderUtil.getTextByLevelingMeasureOrder(stationRecord.levelingMeasureOrder) + val text = textByLevelingMeasureOrder.replaceFirst("(Sim|a])".toRegex(), "") + + return SpannableStringUtil.getSelectedText( + text, + stationRecord.currentPosition + ) + } + + fun getCurrentOrderArray(stationRecord: LevelingStationRecord): Array = + when (stationRecord.levelingMeasureOrder) { + LevelingMeasureOrder.A_BF -> { + getArrayString(stationRecord, "BF", "FB") + } + + LevelingMeasureOrder.A_BFFB -> { + getArrayString(stationRecord, "BFFB", "FBBF") + } + + LevelingMeasureOrder.A_FBBF -> { + getArrayString(stationRecord, "FBBF", "BFFB") + } + + else -> { + val text = + LevelingMeasureOrderUtil.getTextByLevelingMeasureOrder(stationRecord.levelingMeasureOrder) + .replaceFirst("(Sim|a])".toRegex(), "") + getArrayString(stationRecord, text, text) + } + } + + private fun getArrayString( + stationRecord: LevelingStationRecord, + text1: String, + text2: String + ): Array { + return if (stationRecord.oddEvenStation == StationOddEven.ODD_STATION) { + arrayOf( + SpannableStringUtil.getSelectedText(text1, stationRecord.currentPosition), + text2 + ) + } else { + arrayOf( + text1, + SpannableStringUtil.getSelectedText(text2, stationRecord.currentPosition), + ) + } + } + + private fun getStation(stationId: String): LevelingStationRecord { + val station = LevelingDbFactory.instance.stationDataSource.getRecordSync(stationId) + setStationLevelOrder(station) + return station + } + + private fun setStationLevelOrder(station: LevelingStationRecord) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(station.routeId) + station.levelingMeasureOrder = routeRecord?.levelingMeasureOrder + } + + fun isShowOddEvenStation(station: LevelingStationRecord) = + when (station.levelingMeasureOrder) { + LevelingMeasureOrder.A_BF, + LevelingMeasureOrder.A_BFFB, + LevelingMeasureOrder.A_FBBF -> true + + else -> false + } + + fun setMeasureTextColor( + station: LevelingStationRecord, + ilB1: ItemLevelSuveyorSurveyorBinding, + ilB2: ItemLevelSuveyorSurveyorBinding, + ilF1: ItemLevelSuveyorSurveyorBinding, + ilF2: ItemLevelSuveyorSurveyorBinding + ) { + val measureWhichPoint = LevelingMeasureOrderUtil.getMeasureWhichPoint(station) + resetTextColor(ilB1.tvDistanceTitle, ilB1.tvHeightTitle, ilB1.tvDisTance, ilB1.tvHeight) + resetTextColor(ilB2.tvDistanceTitle, ilB2.tvHeightTitle, ilB2.tvDisTance, ilB2.tvHeight) + resetTextColor(ilF1.tvDistanceTitle, ilF1.tvHeightTitle, ilF1.tvDisTance, ilF1.tvHeight) + resetTextColor(ilF2.tvDistanceTitle, ilF2.tvHeightTitle, ilF2.tvDisTance, ilF2.tvHeight) + when (measureWhichPoint) { + B1 -> { + selectTextColor( + ilB1.tvDistanceTitle, + ilB1.tvHeightTitle, + ilB1.tvDisTance, + ilB1.tvHeight + ) + } + + B2 -> { + selectTextColor( + ilB2.tvDistanceTitle, + ilB2.tvHeightTitle, + ilB2.tvDisTance, + ilB2.tvHeight + ) + } + + F1 -> { + selectTextColor( + ilF1.tvDistanceTitle, + ilF1.tvHeightTitle, + ilF1.tvDisTance, + ilF1.tvHeight + ) + } + + F2 -> { + selectTextColor( + ilF2.tvDistanceTitle, + ilF2.tvHeightTitle, + ilF2.tvDisTance, + ilF2.tvHeight + ) + } + } + + } + + private fun resetTextColor( + tvDisTanceTitle: TextView, + tvHeightTitle: TextView, + tvDisTance: TextView, + tvHeight: TextView + ) { + tvDisTanceTitle.setTextColor(Tools.getColor(R.color.color_333333)) + tvHeightTitle.setTextColor(Tools.getColor(R.color.color_333333)) + tvDisTance.setTextColor(Tools.getColor(R.color.color_333333)) + tvHeight.setTextColor(Tools.getColor(R.color.color_333333)) + } + + private fun selectTextColor( + tvDisTanceTitle: TextView, + tvHeightTitle: TextView, + tvDisTance: TextView, + tvHeight: TextView + ) { + tvDisTanceTitle.setTextColor(Tools.getColor(R.color.value_1_selected)) + tvHeightTitle.setTextColor(Tools.getColor(R.color.value_1_selected)) + tvHeight.setTextColor(Tools.getColor(R.color.value_1_selected)) + tvDisTance.setTextColor(Tools.getColor(R.color.value_1_selected)) + } + + fun isEndStation(station: LevelingStationRecord, callBack: (Boolean) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getById(station.routeId) + val endStation = routeRecord?.endPointId == station.frontSightPointId + withContext(Dispatchers.Main) { + callBack(endStation) + } + } + } + + fun nextStation() { + process?.nextStationCheck() + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorVm.kt new file mode 100644 index 0000000..69c6477 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorVm.kt @@ -0,0 +1,280 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import android.text.TextUtils +import androidx.annotation.WorkerThread +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlnetwork.func.level.util.LevelStationUtilTj +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord +import com.bingce.controlapphelper.leveling.detaction.ILevelRefreshBtn +import com.bingce.controlapphelper.leveling.detaction.INextStation +import com.bingce.controlapphelper.leveling.detaction.LevelCheckBtnUtil +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.LevelingStationState +import com.bingce.controlnetwork.func.level.util.LevelDateUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelSuveyorVm : ViewModel() { + var routeId: String? = null + private var levelRefreshBtnI: ILevelRefreshBtn? = null + var currentFragmentPos = 0 + + //测量测站列表 + var measureStationList = emptyList() + + private var initVpCallBack: (() -> Unit)? = null + private var switchPageCallBack: ((Int) -> Unit)? = null + var nextStationI: INextStation? = null + + + fun initDataStationList(projectId: String, routeId: String) { + viewModelScope.launch(Dispatchers.IO) { + getMeasureStationList(projectId, routeId) + } + } + + private suspend fun getMeasureStationList(projectId: String, routeId: String) { + this.routeId = routeId + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + routeRecord?.let { + measureStationList = LevelStationUtilTj.getMeasureStationList(projectId, routeId) + LevelCheckBtnUtil.reset(levelRefreshBtnI) + //初始化按钮状态 + initBtnState(routeRecord.levelingMeasureOrder) + withContext(Dispatchers.Main) { + initVpCallBack?.invoke() + } + } + } + + private fun initBtnState(levelingMeasureOrder: LevelingMeasureOrder) { + for (station in measureStationList) { + station.levelingMeasureOrder = levelingMeasureOrder + refreshBtnActive(station) + } + } + + fun initData( + levelRefreshBtnI: ILevelRefreshBtn, + initVpCallBack: (() -> Unit), + switchPageCallBack: ((Int) -> Unit), + nextStationI: INextStation + ) { + this.levelRefreshBtnI = levelRefreshBtnI + this.initVpCallBack = initVpCallBack + this.switchPageCallBack = switchPageCallBack + this.nextStationI = nextStationI + } + + /** + * 切换页面刷新按钮 + */ + fun switchRefreshBtnEnable() { + levelRefreshBtnI?.refreshMeasureBtn() + levelRefreshBtnI?.refreshNextStationBtn() + levelRefreshBtnI?.refreshRollBackBtn() + levelRefreshBtnI?.refreshReMeasureBtn() + } + + private fun refreshBtnActive(station: LevelingStationRecord) { + LevelCheckBtnUtil.refreshMeasureBtn(station) + LevelCheckBtnUtil.refreshNextStationBtn(station) + LevelCheckBtnUtil.refreshRollBackBtn(station) + LevelCheckBtnUtil.refreshRemeasureStationBtn(station) + } + + fun getCurrentStationId(): String? { + if (measureStationList.size > currentFragmentPos) { + return measureStationList[currentFragmentPos].getId() + } + return null + } + + /** + * 继续观测下一站 + */ + fun contineObserve(station: LevelingStationRecord) { + viewModelScope.launch(Dispatchers.IO) { + startNextStation(station, false) + } + } + + /** + * 间歇 + */ + fun intermittent(station: LevelingStationRecord) { + // TODO: + } + + /** + * 结束测站 + */ + fun endStation(station: LevelingStationRecord) { + viewModelScope.launch(Dispatchers.IO) { + val checkStaionIsFinish = checkStaionIsFinish(station) + if (!checkStaionIsFinish) { + return@launch + } + + station.endStation = true + LevelingDbFactory.instance.stationDataSource.update(station) + + refreshBtnActive(station) + switchRefreshBtnEnable() + } + } + + private suspend fun startNextStation(station: LevelingStationRecord, endStation: Boolean) { + //单程双测 判断测站是否测完 + val checkStaionIsFinish = checkStaionIsFinish(station) + if (!checkStaionIsFinish) { + return + } + + LevelStationUtilTj.createStation( + station.getProjectId(), + station.routeId, + station.frontSightPointId, + endStation = endStation + ) + //重新获取下一站 + getMeasureStationList(station.getProjectId(), station.routeId) + } + + /** + * 回退测站 + */ + fun rollBackStation() { + viewModelScope.launch(Dispatchers.IO) { + var projectId = "" + var routeId = "" + for (station in measureStationList) { + if (TextUtils.isEmpty(projectId)) { + projectId = station.projectId + } + if (TextUtils.isEmpty(routeId)) { + routeId = station.routeId + } + + LevelingDbFactory.instance.stationDataSource.deleteById(station.getId()) + LevelingDbFactory.instance.measureStationDataSource.deleteById(station.getId()) + LevelingDbFactory.instance.measureBackFrontDataSource.deleteByStationId(station.getId()) + } + getMeasureStationList(projectId, routeId) + } + } + + private fun checkStaionIsFinish(station: LevelingStationRecord): Boolean { + //单程双测 判断测站是否测完 + var index = -1 + if (station.relationStationId != null) { + val stationListByRelationId = + LevelingDbFactory.instance.stationDataSource.getStationListByRelationId( + station.getProjectId(), + station.routeId, + station.relationStationId + ) + for ((i, item) in stationListByRelationId.withIndex()) { + if (item.stationState != LevelingStationState.FINISH) { + index = i + break + } + } + } else { + if (station.stationState != LevelingStationState.FINISH) { + index = 0 + } + } + + if (index != -1) { + switchPageCallBack?.invoke(index) + return false + } + return true + } + + fun getCurrentStation(): LevelingStationRecord? { + if (measureStationList.size > currentFragmentPos) { + return measureStationList[currentFragmentPos] + } + return null + } + + fun calLevelRouteResult(callBack: (String) -> Unit) { + getCurrentStation()?.let { + viewModelScope.launch(Dispatchers.IO) { + val success = LevelStationUtilTj.checkStationForResult(it.getId()) + if (!success) { + return@launch + } + val stationRouteResult = LevelStationUtilTj.getStationRouteResult(it) + withContext(Dispatchers.Main) { + callBack(stationRouteResult) + } + } + } + } + + fun getGetDadaAuto(routeId: String, callBack: (Boolean) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val record = LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + withContext(Dispatchers.Main) { + if (record == null) { + callBack(true) + } else { + callBack(!record.getDataManually) + } + } + } + } + + fun setGetDataAuto(routeId: String, auto: Boolean) { + viewModelScope.launch(Dispatchers.IO) { + var record = LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + if (record == null) { + record = LevelingStationSettingRecord() + record.routeId = routeId + record.getDataManually = !auto + LevelingDbFactory.instance.stationSettingDataSource.save(record) + } else { + record.getDataManually = !auto + LevelingDbFactory.instance.stationSettingDataSource.update(record) + } + } + } + + /** + * 是否设置过最后一站的测站设置 + */ + @WorkerThread + fun isHaveSetEndStationSetting(stationId: String): Boolean { + val stationSetting = + LevelingDbFactory.instance.stationSettingDataSource.getByStationId(stationId) + return stationSetting?.setEndStationSetting ?: false + } + + fun checkSunTime(projectId: String, showDialog: (String?) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val projectRecord = SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + val toleranceDetail = + LevelingDbFactory.instance.toleranceDetailDataSource.getRecordSync(projectRecord.toleranceId) + + var hint: String? = null + if (toleranceDetail.isCheckSunTime) { + hint = LevelDateUtil.getLevelOperateSunTimeHint( + projectRecord.latitude.toDouble(), + projectRecord.longitude.toDouble() + ) + } + withContext(Dispatchers.Main) { + showDialog(hint) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/adapter/BaseAdapterNew.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/BaseAdapterNew.java new file mode 100644 index 0000000..11fe598 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/BaseAdapterNew.java @@ -0,0 +1,89 @@ +package com.bingce.controlnetwork.newui.adapter; + +import android.content.Context; +import android.view.ContextMenu; +import android.view.LayoutInflater; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; + +import java.util.List; + +/** + * Created by YanZhenjie on 2017/10/3. + */ +public abstract class BaseAdapterNew extends RecyclerView.Adapter { + private IItemClickListener mItemClickListener; + protected IAdapterContextMenu adapterContextMenu; + + protected List mDataList; + protected Context mContext; + + private final LayoutInflater mInflater; + + public BaseAdapterNew(Context context) { + this.mContext = context; + this.mInflater = LayoutInflater.from(context); + } + + public LayoutInflater getInflater() { + return mInflater; + } + + + @Override + public int getItemCount() { + return mDataList == null ? 0 : mDataList.size(); + } + + public T getBean(int position) { + return mDataList.get(position); + } + + @Override + public void onBindViewHolder(@NonNull VH holder, int position) { + holder.itemView.setOnClickListener(v -> { + if (mItemClickListener != null) { + mItemClickListener.clickItem(mDataList.get(holder.getBindingAdapterPosition())); + } + }); + + holder.itemView.setOnCreateContextMenuListener((menu, v, menuInfo) -> + createMenu(menu, mDataList.get(holder.getBindingAdapterPosition()))); + + onBindViewHolderDo(holder, position); + } + + protected abstract void onBindViewHolderDo(VH holder, int position); + + + protected void createMenu(ContextMenu menu, T bean) { + if (adapterContextMenu == null) return; + menu.clear(); + for (int index = 0; index < adapterContextMenu.menuItemSize(); index++) { + menu.add(0, index, 0, adapterContextMenu.menuItemName(index)); + MenuItem menuItem = menu.getItem(index); + if (menuItem != null) { + menuItem.setOnMenuItemClickListener(item -> + adapterContextMenu.onMenuItemClick(bean, item)); + } + } + } + + public void setAdapterContextMenu(IAdapterContextMenu adapterContextMenu) { + this.adapterContextMenu = adapterContextMenu; + } + + public void setOnItemClickListener(IItemClickListener mItemClickListener) { + this.mItemClickListener = mItemClickListener; + } + + public void refreshData(List dataList) { + this.mDataList = dataList; + notifyDataSetChanged(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/adapter/IItemClickListener.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/IItemClickListener.java new file mode 100644 index 0000000..e4c128b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/IItemClickListener.java @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.newui.adapter; + +public interface IItemClickListener { + void clickItem(T t); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/adapter/ProjectListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/ProjectListAdapter.java new file mode 100644 index 0000000..1a659d2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/ProjectListAdapter.java @@ -0,0 +1,70 @@ +package com.bingce.controlnetwork.newui.adapter; + +import android.content.Context; +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.NewItemProjectListBinding; +import com.bingce.controlnetwork.newui.viewholder.ProjectListViewHolder; + + +public class ProjectListAdapter extends BaseAdapterNew { + + public ProjectListAdapter(Context context) { + super(context); + } + + @NonNull + @Override + public ProjectListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ProjectListViewHolder(NewItemProjectListBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(ProjectListViewHolder holder, int position) { + ProjectRecord bean = mDataList.get(position); + holder.mBinding.tvIndex.setText(String.valueOf(position + 1)); + holder.mBinding.tvProjectName.setText(bean.getProjectName()); + + if (bean.projectType == null || ProjectTypeValue.TRIANGLE.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.triangular_wire)); + } else if (ProjectTypeValue.CONNECTION.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.contact_measurement)); + } else if (ProjectTypeValue.HEIGHT_TRAVERSE.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.elevation_conductor)); + } else if (ProjectTypeValue.LEVEL.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.level)); + } else if (ProjectTypeValue.GNSS.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.gnss)); + } else { + holder.mBinding.tvProjectType.setText(""); + } + + holder.mBinding.tvTolerance.setText(bean.getToleranceName()); + } + + @Override + protected void createMenu(ContextMenu menu, ProjectRecord bean) { + if (adapterContextMenu == null) return; + menu.clear(); + int menuSize = 2; + if (ProjectTypeValue.GNSS.equals(bean.projectType)) { + menuSize = 3; + } + for (int index = 0; index < menuSize; index++) { + menu.add(0, index, 0, adapterContextMenu.menuItemName(index)); + MenuItem menuItem = menu.getItem(index); + if (menuItem != null) { + menuItem.setOnMenuItemClickListener(item -> + adapterContextMenu.onMenuItemClick(bean, item)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseBindingActivity.kt b/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseBindingActivity.kt new file mode 100644 index 0000000..7167151 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseBindingActivity.kt @@ -0,0 +1,99 @@ +package com.bingce.controlnetwork.newui.base + +import android.os.Bundle +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.widget.LinearLayout +import androidx.annotation.StringRes +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.app.AppCompatDelegate +import androidx.appcompat.widget.Toolbar +import androidx.core.content.ContextCompat +import androidx.viewbinding.ViewBinding +import blankj.utilcode.util.Utils +import com.bingce.controlnetwork.App +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityBaseBindingBinding + +import org.polaric.colorful.Colorful + +abstract class BaseBindingActivity : AppCompatActivity() { + protected val mBinding get() = _binding!! + private var _binding: VB? = null + + private lateinit var toolBar: Toolbar + + + abstract fun getBinding(): VB + abstract fun initView() + abstract fun initData() + + override fun onCreate(savedInstanceState: Bundle?) { + initTheme() + super.onCreate(savedInstanceState) + setContentView(getContentView()) + initToolBar() + initView() + initData() + } + + private fun initTheme() { + setTheme(Colorful.getThemeDelegate().styleResBase) + getTheme().applyStyle(Colorful.getThemeDelegate().styleResPrimary, true) + getTheme().applyStyle(Colorful.getThemeDelegate().styleResAccent, true) + val app = Utils.getApp() as App + if (app.isThemeDark) { + delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES + } else { + delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_NO + } + window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + + private fun getContentView(): View { + val baseBinding = ActivityBaseBindingBinding.inflate(layoutInflater) + val layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + _binding = getBinding() + baseBinding.llParent.addView(mBinding.root, layoutParams) + baseBinding.llParent.setBackgroundColor( + ContextCompat.getColor( + this, + R.color.bg_content_new + ) + ) + + toolBar = baseBinding.ilToolBar.toolbar + return baseBinding.root + } + + protected open fun initToolBar() { + setSupportActionBar(toolBar) + if (supportActionBar != null) supportActionBar!!.setDisplayHomeAsUpEnabled(true) + } + + protected fun setToolbarTitle(text: String?) { + toolBar.setTitle(text) + } + + protected fun setToolbarTitle(@StringRes text: Int) { + toolBar.setTitle(text) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == android.R.id.home) { + if (isFinishAtOnce()) + finish() + } + return super.onOptionsItemSelected(item) + } + + protected open fun isFinishAtOnce(): Boolean { + return true + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseFragmentBinding.java b/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseFragmentBinding.java new file mode 100644 index 0000000..2cbde91 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseFragmentBinding.java @@ -0,0 +1,59 @@ +package com.bingce.controlnetwork.newui.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.viewbinding.ViewBinding; + +import com.bingce.controlnetwork.fragment.base.BaseFragment; + +public abstract class BaseFragmentBinding extends BaseFragment { + protected VB mBinding; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = getViewBinding(inflater, container); + return mBinding.getRoot(); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initView(); + initData(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + protected abstract VB getViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container); + + protected abstract void initView(); + + protected abstract void initData(); + + protected String getArgumentString(String key) { + Bundle bundle = getArguments(); + if (bundle != null) { + return bundle.getString(key); + } + return null; + } + + protected int getArgumentInt(String key) { + Bundle bundle = getArguments(); + if (bundle != null) { + return bundle.getInt(key); + } + return -1; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/ConfigFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/ConfigFragment.kt new file mode 100644 index 0000000..01540be --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/ConfigFragment.kt @@ -0,0 +1,111 @@ +package com.bingce.controlnetwork.newui.configfragment + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.LifecycleOwner +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentConfigBinding +import com.bingce.controlnetwork.fragment.PrismManageFragment +import com.bingce.controlnetwork.fragment.SelectExportHeightTraverseFragment +import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordFragment +import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordWireFileFragment +import com.bingce.controlnetwork.fragment.ToleranceManageFragment +import com.bingce.controlnetwork.func.level.fragment.LevelSelectExportFragment +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.util.SelectDeviceTypeUtil +import com.bingce.data.database.deformationmonitor.util.GsonUtils + + +class ConfigFragment : BaseFragmentBinding() { + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentConfigBinding { + return NewFragmentConfigBinding.inflate(inflater, container, false) + } + + override fun initView() { + //管理 + mBinding.ilInstrumentManagement.iv.setImageResource(R.mipmap.icon_ts_connecting) + mBinding.ilInstrumentManagement.tv.setText(R.string.instrument_management) + mBinding.ilPrismManagement.iv.setImageResource(R.mipmap.icon_prism_manager) + mBinding.ilPrismManagement.tv.setText(R.string.prism_manager) + mBinding.ilCustomTolerance.iv.setImageResource(R.mipmap.ic_tolerance_24) + mBinding.ilCustomTolerance.tv.setText("自定义限差") + //三角导线联系测量 + mBinding.ilExportMeasure.iv.setImageResource(R.mipmap.ic_export) + mBinding.ilExportMeasure.tv.setText(R.string.export) + mBinding.ilExportWire.iv.setImageResource(R.mipmap.ic_export_wire) + mBinding.ilExportWire.tv.setText(R.string.export_wire_file) + //水准 + mBinding.ilExportLevel.iv.setImageResource(R.mipmap.ic_export) + mBinding.ilExportLevel.tv.setText(R.string.level_export) + //高程导线 + //高程导线数据导出 + mBinding.ilExportHeightTraverse.iv.setImageResource(R.mipmap.ic_export) + mBinding.ilExportHeightTraverse.tv.setText(R.string.export_height_traverse) + + initListener() + } + + private fun initListener() { + mBinding.ilInstrumentManagement.root.setOnClickListener { + //仪器管理 +// val intent = Intent(activity, ConnectTSActivity::class.java) +// intent.putExtra("customChannel", AppChannel.customChannel) +// startActivity(intent) + SelectDeviceTypeUtil.showDeviceTypeDialog() + } + mBinding.ilPrismManagement.root.setOnClickListener { + //棱镜管理 + PrismManageFragment.start(activity) + } + mBinding.ilCustomTolerance.root.setOnClickListener { + //自定义限差 + ToleranceManageFragment.start(activity, null) + } + mBinding.ilExportMeasure.root.setOnClickListener { + //观测数据导出 先选导出类型 + startExportMeasureData(requireContext(), childFragmentManager, viewLifecycleOwner) + } + mBinding.ilExportWire.root.setOnClickListener { + //导线文件导出 + SelectExportSurveyorRecordWireFileFragment.start(context) + } + mBinding.ilExportLevel.root.setOnClickListener { + //水准数据导出 + LevelSelectExportFragment.start(activity) + } + mBinding.ilExportHeightTraverse.root.setOnClickListener { + //高程导线导出 + SelectExportHeightTraverseFragment.start(requireContext()) + } + } + + override fun initData() { + } + + /** + * 测院导出观测前先选择导出文件类型 + * + * @param context + * @param fragmentManager + * @param lifecycleOwner + */ + private fun startExportMeasureData( + context: Context, fragmentManager: FragmentManager, + lifecycleOwner: LifecycleOwner + ) { + SelectMeasureDataExportTypeFragment.start(fragmentManager, lifecycleOwner) { beanList -> + val json = + GsonUtils.toJson(beanList) + + + SelectExportSurveyorRecordFragment.start(context) + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectMeasureDataExportTypeFragment.java b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectMeasureDataExportTypeFragment.java similarity index 97% rename from app/src/main/java/com/bingce/controlnetwork/fragment/SelectMeasureDataExportTypeFragment.java rename to app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectMeasureDataExportTypeFragment.java index 365e374..6ab7c45 100644 --- a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectMeasureDataExportTypeFragment.java +++ b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectMeasureDataExportTypeFragment.java @@ -1,13 +1,11 @@ -package com.bingce.controlnetwork.fragment; +package com.bingce.controlnetwork.newui.configfragment; -import android.app.Dialog; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; +import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentManager; @@ -178,6 +176,7 @@ public class SelectMeasureDataExportTypeFragment extends BottomSheetDialogFragme } } + @Keep public static class Bean { private final String name; private final String type; diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/mefragment/MeFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/mefragment/MeFragment.kt new file mode 100644 index 0000000..bb80d49 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/mefragment/MeFragment.kt @@ -0,0 +1,123 @@ +package com.bingce.controlnetwork.newui.mefragment + +import android.content.Intent +import android.os.Process +import android.util.Log +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.ViewGroup +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import blankj.utilcode.util.Utils +import cn.leancloud.LCUser +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.AboutActivity +import com.bingce.controlnetwork.activity.SettingsActivity +import com.bingce.controlnetwork.activity.backup.BackupExportActivity +import com.bingce.controlnetwork.activity.backup.launch.BackupImportHelper +import com.bingce.controlnetwork.activity.user.LoginActivity +import com.bingce.controlnetwork.activity.user.UserInfoActivity +import com.bingce.controlnetwork.databinding.NewFragmentMeBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.viewmodel.MainActivityViewModel +import com.bingce.surveyor.agentweb.AgentWebActivity +import com.bumptech.glide.Glide + +/** + * 我的页面 + */ +class MeFragment : BaseFragmentBinding() { + private val backupImportUtil = BackupImportHelper(this) + + private val mainActivityVm by activityViewModels() + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentMeBinding { + return NewFragmentMeBinding.inflate(inflater, container, false) + } + + override fun initView() { + setHasOptionsMenu(true) + initListener() + initObserver() + } + + private fun initObserver() { + mainActivityVm.refreshLoginUserLiveData.observe(this) { + Log.d("hwhw", " mainActivityVm.refreshLoginUserLiveData.=" + it.userName) + mBinding.tvNickName.text = it?.nickName ?: "请登录" + mBinding.tvPhoneOrEmail.text = it?.userName + it?.avator?.let { avator -> + Glide.with(this).load(avator).into(mBinding.ivAvatar) + } + } + } + + override fun initData() { + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_measure_debug, menu) + super.onCreateOptionsMenu(menu, inflater) + } + + private fun initListener() { + mBinding.llSetting.setOnClickListener { + //设置 + startActivity(Intent(requireContext(), SettingsActivity::class.java)) + } + mBinding.llDataBackup.setOnClickListener { + //数据备份 + BackupExportActivity.start(requireContext(), BackupExportActivity::class.java) + } + mBinding.llDataImport.setOnClickListener { + //数据导入 + backupImportUtil.doImport(requireContext()) { success -> + if (success) { + restartApplication() + } + } + } + mBinding.llViewException.setOnClickListener { + //技术支持 + AgentWebActivity.navigation2( + requireContext(), + "android_url_tech_support" + ) + } + mBinding.llAbout.setOnClickListener { + //关于 + startActivity(Intent(requireContext(), AboutActivity::class.java)) + } + mBinding.llUser.setOnClickListener { + if (LCUser.getCurrentUser() != null) { + startActivity(Intent(requireContext(), UserInfoActivity::class.java)) + } else { + val intent = Intent(Utils.getApp(), LoginActivity::class.java) + intent.putExtra("finishTo", UserInfoActivity::class.java.name) + startActivity(intent) + } + } + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.measureDebug) { + Utils.isTest = !Utils.isTest + if (Utils.isTest) { + ToastUtils.showShort(R.string.debug_on) + } else { + ToastUtils.showShort(R.string.debug_off) + } + } + return super.onOptionsItemSelected(item) + } + + private fun restartApplication() { + Process.killProcess(Process.myPid()) + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/IProjectCreateEditOperate.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/IProjectCreateEditOperate.kt new file mode 100644 index 0000000..f82435b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/IProjectCreateEditOperate.kt @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.newui.projectedit + +interface IProjectCreateEditOperate { + fun save(success: () -> Unit) +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditActivity.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditActivity.kt new file mode 100644 index 0000000..b1d1633 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditActivity.kt @@ -0,0 +1,90 @@ +package com.bingce.controlnetwork.newui.projectedit + +import android.content.Context +import android.content.Intent +import android.view.Menu +import android.view.MenuItem +import androidx.activity.viewModels +import androidx.fragment.app.Fragment + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewActivityProjectCreateEidtBinding +import com.bingce.controlnetwork.newui.base.BaseBindingActivity + +class ProjectCreateEditActivity : BaseBindingActivity() { + private val projectCreateEditVm by viewModels() + + private var currentFragment: Fragment? = null + + companion object { + @JvmStatic + fun launch(context: Context, projectType: String?, projectId: String? = null) { + context.startActivity(Intent(context, ProjectCreateEditActivity::class.java).apply { + putExtra(BundleConstants.KEY_PROJECT_ID, projectId) + putExtra(BundleConstants.KEY_PROJECT_TYPE, projectType) + }) + } + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_save, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.menuSave) { + val iProjectCreateEditOperate = currentFragment as? IProjectCreateEditOperate + iProjectCreateEditOperate?.save { + finish() + } + } + return super.onOptionsItemSelected(item) + } + + override fun getBinding(): NewActivityProjectCreateEidtBinding { + return NewActivityProjectCreateEidtBinding.inflate(layoutInflater) + } + + override fun initView() { + projectCreateEditVm.projectId = getProjectId() + projectCreateEditVm.projectType = getProjectType() + + startFragment() + } + + private fun startFragment() { + when (val projectType = getProjectType()) { + ProjectTypeValue.CONNECTION -> { +// currentFragment = ProjectCreateEditConnectionFragment() + } + + ProjectTypeValue.LEVEL -> { + currentFragment = ProjectCreateEditLevelFragment() + } + + ProjectTypeValue.TRIANGLE -> { +// currentFragment = ProjectCreateEditTriangleFragment() + } + + else -> { + if (projectType == null) { +// currentFragment = ProjectCreateEditTriangleFragment() + } + } + } + + if (currentFragment != null) { + supportFragmentManager.beginTransaction() + .replace(R.id.container, currentFragment!!) + .commitNow() + } + } + + override fun initData() { + } + + private fun getProjectType() = intent.getStringExtra(BundleConstants.KEY_PROJECT_TYPE) + private fun getProjectId() = intent.getStringExtra(BundleConstants.KEY_PROJECT_ID) +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditLevelFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditLevelFragment.kt new file mode 100644 index 0000000..fad467d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditLevelFragment.kt @@ -0,0 +1,298 @@ +package com.bingce.controlnetwork.newui.projectedit + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.EditText +import androidx.annotation.WorkerThread +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import cn.liuyanbing.surveyor.function.level.constant.LevelConstant + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigOperate +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil +import com.bingce.controlapphelper.util.CheckLocationUtil +import com.bingce.controlapphelper.util.GetLocationUtil +import com.bingce.controlapphelper.util.ToleranceUtil.completedToleranceName +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentProjectCreateEditLevelBinding +import com.bingce.controlnetwork.fragment.ToleranceSelectFragment +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil.getOperate +import com.bingce.utils.DateUtils +import com.bingce.utils.ThreadPoolUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.util.Date + +/** + * 新建编辑项目-水准 + */ +class ProjectCreateEditLevelFragment : + BaseFragmentBinding(), IProjectCreateEditOperate { + + private val projectCreateEditVm by activityViewModels() + + private var toleranceId: String? = null //回显,选择 + + private val getLocation by lazy { + GetLocationUtil() + } + + + private val activityResultLauncher = ToleranceSelectFragment + .createActivityLauncher( + this + ) { id: String -> + this.dealSelectTolerance(id) + } + + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentProjectCreateEditLevelBinding { + return NewFragmentProjectCreateEditLevelBinding.inflate(inflater, container, false) + } + + override fun initView() { + lifecycle.addObserver(getLocation) + initListener() + } + + private fun initListener() { + mBinding.llSelectTolerance.setOnClickListener { + //选择限差方案 + ToleranceSelectFragment.start( + context, + toleranceId, + ProjectTypeValue.LEVEL, + activityResultLauncher + ) + } + mBinding.ivGetLocation.setOnClickListener { + getLocation { + setLocation(mBinding.etLongitude, mBinding.etLatitude, it) + } + } + } + + override fun initData() { + if (projectCreateEditVm.isEdit()) { + setAlreadyData() + } else { + mBinding.etProjectName.setText(DateUtils.ymdWithCharacter(Date())) + initCreateMeasureUnitData() + setDefaultLocation() + val iToleranceDetail = getIToleranceDetail(null) + updateTolerance(iToleranceDetail) + } + } + + private fun initCreateMeasureUnitData() { + lifecycleScope.launch(Dispatchers.IO) { + val measureUnit = ProjectLastData.getMeasureUnit() + withContext(Dispatchers.Main) { + mBinding.etMeasurementUnit.setText(measureUnit) + } + } + } + + private fun setAlreadyData() { + ThreadPoolUtil.execute { + val projectRecord = SurveyorDatabaseFactory.instance + .getProjectDataSource() + .getRecord(projectCreateEditVm.projectId) ?: return@execute + //设置项目名称 + mBinding.etProjectName.setText(projectRecord.getProjectName()) + //设置测量单位 + mBinding.etMeasurementUnit.setText(projectRecord.getMeasureUnit()) + //经纬度 + if (isEmpty(projectRecord.longitude) || isEmpty(projectRecord.latitude)) { + setDefaultLocation() + } else { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + projectRecord.longitude, + projectRecord.latitude + ) + } + + //更新限差 + val iToleranceDetail = getIToleranceDetail(projectRecord.toleranceId) + updateTolerance(iToleranceDetail) + } + } + + private fun getIToleranceDetail(toleranceId: String?) = if (toleranceId != null) { + //编辑情况 + getOperate(toleranceId)?.getIToleranceDetail(toleranceId) + } else { + //新建情况走默认的限差 + ToleranceLoadUtil.getToleranceLoad(ProjectTypeValue.LEVEL) + .getNewDefaultTolerance(ProjectTypeValue.LEVEL) + } + + override fun save(success: () -> Unit) { + view ?: return + //判断项目名称是否为空 + val projectName = mBinding.etProjectName.text.toString().trim() + if (TextUtils.isEmpty(projectName)) { + ToastUtils.showShort(R.string.tips_need_select_input_project_name) + return + } + //判断限差参数 + if (TextUtils.isEmpty(toleranceId)) { + ToastUtils.showShort(R.string.tips_need_select_project_tolerance) + return + } + //经度 + val longitude = mBinding.etLongitude.getText().toString().trim() + if (TextUtils.isEmpty(longitude)) { + ToastUtils.showShort(R.string.please_input_longitude) + return + } + //纬度 + val latitude = mBinding.etLatitude.getText().toString().trim() + if (TextUtils.isEmpty(latitude)) { + ToastUtils.showShort(R.string.please_input_latitude) + return + } + + val measurementUnit = mBinding.etMeasurementUnit.text.toString().trim() + + ThreadPoolUtil.execute { + if (projectCreateEditVm.isEdit()) { + val projectRecord = + SurveyorDatabaseFactory.instance + .getProjectDataSource() + .getRecord(projectCreateEditVm.projectId) + projectRecord.setProjectName(projectName) + projectRecord.setToleranceId(toleranceId) + projectRecord.measureUnit = measurementUnit + projectRecord.longitude = longitude + projectRecord.latitude = latitude + //存储 + SurveyorDatabaseFactory.instance + .getProjectDataSource() + .saveRecordSync(projectRecord) + } else { + val projectRecord = ProjectRecord(projectName) + projectRecord.measureUnit = measurementUnit + projectRecord.setToleranceId(toleranceId) + projectRecord.projectType = ProjectTypeValue.LEVEL + projectRecord.isShowSlopDistance = true + projectRecord.longitude = longitude + projectRecord.latitude = latitude + //存储 + SurveyorDatabaseFactory.instance + .getProjectDataSource() + .saveRecordSync(projectRecord) + + ConfigOperate.changeDefaultProjectAndCycle(projectRecord.getId(), "") + + ProjectLastData.setMeasureUnit(measurementUnit) + //经纬度 + ProjectLastData.setLongitude(longitude) + ProjectLastData.setLatitude(latitude) + } + } + + success() + } + + /** + * 处理选择返回的限差id + * + * @param id + */ + private fun dealSelectTolerance(id: String) { + ThreadPoolUtil.execute { + val operate: IToleranceOperate = getOperate(id) + ?: return@execute + val toleranceDetail: IToleranceDetail? = operate.getIToleranceDetail(id) + //存限差数据 + operate.saveToleranceDetail(toleranceDetail) + val view: android.view.View? = view + if (view != null) { + updateTolerance(toleranceDetail) + } + } + } + + @WorkerThread + private fun updateTolerance(iToleranceDetail: IToleranceDetail?) { + if (iToleranceDetail == null) { + return + } + toleranceId = iToleranceDetail.getId() + val operate = getOperate(toleranceId) ?: return + val group = operate.getGroup(iToleranceDetail) + val level = operate.getLevel(iToleranceDetail) + runOnUI { + val toleranceShowName = + completedToleranceName(group, level, iToleranceDetail) + mBinding.btnSelectTolerance.text = toleranceShowName + } + } + + private fun getLocation(resultListener: GetLocationUtil.IResultListener) { + CheckLocationUtil.check(requireContext()) { + getLocation.getResult(resultListener) + } + } + + private fun setLocation( + etLongitude: EditText, + etLatitude: EditText, + result: GetLocationUtil.Result? + ) { + setLocation(etLongitude, etLatitude, result?.longitude, result?.latitude) + } + + private fun setLocation( + etLongitude: EditText, + etLatitude: EditText, + longitude: String?, + latitude: String? + ) { + etLongitude.setText(longitude) + etLatitude.setText(latitude) + } + + private fun setDefaultLocation() { + lifecycleScope.launch(Dispatchers.IO) { + val longitude = ProjectLastData.getLongitude() + val latitude = ProjectLastData.getLatitude() + withContext(Dispatchers.Main) { + if (isEmpty(longitude) || isEmpty(latitude)) { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + LevelConstant.LONGITUDE_DEFAULT.toString(), + LevelConstant.LATITUDE_DEFAULT.toString() + ) + } else { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + longitude, + latitude + ) + } + } + } + + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditViewModel.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditViewModel.kt new file mode 100644 index 0000000..1b72c07 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditViewModel.kt @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.newui.projectedit + +import androidx.lifecycle.ViewModel + +class ProjectCreateEditViewModel : ViewModel() { + var projectId: String? = null + var projectType: String? = null + fun isEdit() = projectId != null +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectLastData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectLastData.kt new file mode 100644 index 0000000..c8e7af5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectLastData.kt @@ -0,0 +1,65 @@ +package com.bingce.controlnetwork.newui.projectedit + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants + + +/** + * 创建项目的保存的上次值 + */ +object ProjectLastData { + + /** + * 测量单位 + */ + @WorkerThread + fun getMeasureUnit(): String? { + val measureUnitRecord = + SurveyorDatabaseFactory.instance.getConfigDataSource() + .getByKeySync(ConfigConstants.KEY_LAST_MEASURE_UNIT) + return measureUnitRecord?.getConfigValue() + } + + @WorkerThread + fun setMeasureUnit(measureUnit: String?) { + SurveyorDatabaseFactory.instance.getConfigDataSource() + .setSync(ConfigConstants.KEY_LAST_MEASURE_UNIT, measureUnit) + } + + /** + * 经度 + */ + @WorkerThread + fun getLongitude(): String? { + val measureUnitRecord = + SurveyorDatabaseFactory.instance.getConfigDataSource() + .getByKeySync(ConfigConstants.KEY_LAST_LONGITUDE) + return measureUnitRecord?.getConfigValue() + } + + @WorkerThread + fun setLongitude(longitude: String?) { + SurveyorDatabaseFactory.instance.getConfigDataSource() + .setSync(ConfigConstants.KEY_LAST_LONGITUDE, longitude) + } + + /** + * 纬度 + */ + @WorkerThread + fun getLatitude(): String? { + val measureUnitRecord = + SurveyorDatabaseFactory.instance.getConfigDataSource() + .getByKeySync(ConfigConstants.KEY_LAST_LATITUDE) + return measureUnitRecord?.getConfigValue() + } + + @WorkerThread + fun setLatitude(latitude: String?) { + SurveyorDatabaseFactory.instance.getConfigDataSource() + .setSync(ConfigConstants.KEY_LAST_LATITUDE, latitude) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/IStationSettingOperate.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/IStationSettingOperate.kt new file mode 100644 index 0000000..2372f0d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/IStationSettingOperate.kt @@ -0,0 +1,6 @@ +package com.bingce.controlnetwork.newui.stationsetting + +interface IStationSettingOperate { + fun checkSaveNot(): Boolean + fun setDataToStation() +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingEnvironmentFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingEnvironmentFragment.kt new file mode 100644 index 0000000..beb3ca4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingEnvironmentFragment.kt @@ -0,0 +1,99 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentStationSettingEnvironmentBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding + +/** + * 测站设置-环境信息 + */ +class StationSettingEnvironmentFragment : + BaseFragmentBinding(), IStationSettingOperate { + + private val viewModel by activityViewModels() + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentStationSettingEnvironmentBinding { + return NewFragmentStationSettingEnvironmentBinding.inflate(inflater, container, false) + } + + override fun initView() { + mBinding.ilTemperature.tvTitle.text = "温度(℃)" + mBinding.ilHumidity.tvTitle.text = "湿度(%)" + mBinding.ilAirPressure.tvTitle.text = "气压(hPa)" + + initListener() + } + + private fun initListener() { + mBinding.tvLastData.setOnClickListener { + useLastData() + } + mBinding.tvStandardData.setOnClickListener { + useStandardData() + } + } + + private fun useLastData() { + viewModel.getLastEnvironmentData { + setEnvironmentData() + } + } + + private fun useStandardData() { + viewModel.getDefaultEnvironmentData() + setEnvironmentData() + } + + private fun setEnvironmentData() { + mBinding.ilTemperature.editText.setText(viewModel.environmentData.temperature) + mBinding.ilHumidity.editText.setText(viewModel.environmentData.humidity) + mBinding.ilAirPressure.editText.setText(viewModel.environmentData.airPress) + } + + + override fun initData() { + viewModel.getEnvironmentData { + setEnvironmentData() + } + } + + override fun checkSaveNot(): Boolean { + val temperature = mBinding.ilTemperature.editText.text + if (TextUtils.isEmpty(temperature)) { + ToastUtils.showShort(R.string.temperature_hint) + return true + } + val humidity = mBinding.ilHumidity.editText.text + if (TextUtils.isEmpty(humidity)) { + ToastUtils.showShort(R.string.humidity_hint) + return true + } + val airPressure = mBinding.ilAirPressure.editText.text + if (TextUtils.isEmpty(airPressure)) { + ToastUtils.showShort(R.string.air_pressure_hint) + return true + } + return false + } + + private fun getTemperature() = mBinding.ilTemperature.editText.text.toString().trim() + private fun getHumidity() = mBinding.ilHumidity.editText.text.toString().trim() + private fun getAirPressure() = mBinding.ilAirPressure.editText.text.toString().trim() + + override fun setDataToStation() { + viewModel.setEnvironmentDataToStation( + getTemperature(), + getHumidity(), + getAirPressure() + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingHeightFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingHeightFragment.kt new file mode 100644 index 0000000..6583bbf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingHeightFragment.kt @@ -0,0 +1,108 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import android.view.ViewGroup.MarginLayoutParams +import android.widget.EditText +import android.widget.TextView +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentStationSettingHeightBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding + +import com.bingce.utils.ScreenUtil + +/** + * 测站设置-仪高镜高 + */ +class StationSettingHeightFragment : BaseFragmentBinding(), + IStationSettingOperate { + + private val viewModel by activityViewModels() + + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentStationSettingHeightBinding { + return NewFragmentStationSettingHeightBinding.inflate(inflater, container, false) + } + + override fun initView() { + mBinding.ilInstrumentHeight.tvTitle.text = "仪器高(m)" + } + + override fun initData() { + //获取点 加载布局 + viewModel.getStationRecord { + //设置仪器高 + mBinding.ilInstrumentHeight.editText.setText(viewModel.heightData.getInstrumentHeight()) + + for (point in viewModel.heightData.pointList) { + val itemView = + layoutInflater.inflate(R.layout.new_item_station_setting_point_height, null) + val params = MarginLayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ScreenUtil.dp2px(requireContext(), 48f) + ) + + val tvPoint = itemView.findViewById(R.id.tvPoint) + val etHeight = itemView.findViewById(R.id.etHeight) + + setItemEtData( + tvPoint, etHeight, + viewModel.heightData.getPointName(point.originalPointId), + viewModel.heightData.getPointHeight(point.originalPointId) + ) + + mBinding.llPoints.addView(itemView, params) + } + } + } + + private fun setItemEtData( + tvPoint: TextView, + etHeight: EditText, + pointName: String?, + pointHeight: String + ) { + tvPoint.text = pointName + etHeight.setText(pointHeight) + } + + + override fun checkSaveNot(): Boolean { + val instrumentHeight = getInstrumentHeight() + if (TextUtils.isEmpty(instrumentHeight)) { + ToastUtils.showShort(R.string.instrument_height_hint) + return true + } + for (i in 0 until mBinding.llPoints.childCount) { + val itemView = mBinding.llPoints.getChildAt(i) + val pointHeight = itemView.findViewById(R.id.etHeight).text.toString().trim() + val pointName = itemView.findViewById(R.id.tvPoint).text.toString().trim() + if (TextUtils.isEmpty(pointHeight)) { + ToastUtils.showShort("请输入测点" + pointName + "高度") + return true + } + } + return false + } + + private fun getInstrumentHeight() = mBinding.ilInstrumentHeight.editText.text.toString().trim() + + override fun setDataToStation() { + viewModel.setStationHeightToStation(getInstrumentHeight()) + for (i in 0 until mBinding.llPoints.childCount) { + val itemView = mBinding.llPoints.getChildAt(i) + val etPointHeight = itemView.findViewById(R.id.etHeight) + val pointHeight = etPointHeight.text.toString().trim() + + viewModel.setPointDataToStation(i, pointHeight) + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingSettingFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingSettingFragment.kt new file mode 100644 index 0000000..1a54fdb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingSettingFragment.kt @@ -0,0 +1,180 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter +import android.widget.Spinner +import android.widget.TextView +import androidx.appcompat.widget.SwitchCompat +import androidx.fragment.app.activityViewModels +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint + +import com.bingce.controlapphelper.util.StationUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentStationSettingSettingBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.util.SurveyorOpenAtrUtil +import com.bingce.utils.ScreenUtil + +/** + * 测站设置-测站设置 + */ +class StationSettingSettingFragment : + BaseFragmentBinding(), IStationSettingOperate { + + private val viewModel by activityViewModels() + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentStationSettingSettingBinding { + return NewFragmentStationSettingSettingBinding.inflate(inflater, container, false) + } + + override fun initView() { + + } + + override fun initData() { + viewModel.getStationRecord { + val pointSize = viewModel.getStationSurveyorPointSize() - 1 + if (StationUtil.isCanLeftOrRightSurveyor(pointSize)) { + mBinding.scLeftRight.visibility = View.VISIBLE + } else { + mBinding.scLeftRight.visibility = View.GONE + } + if (StationUtil.isCanZeroSurveyor(pointSize)) { + mBinding.scZero.visibility = View.VISIBLE + } else { + mBinding.scZero.visibility = View.GONE + } + mBinding.scLeftRight.isChecked = viewModel.getStationLeftRight() + mBinding.scZero.isChecked = viewModel.getStationZero() + //显示斜距还是平距 + mBinding.showSlopSwitch.isChecked = viewModel.getShowSlop() + + setDisEnableByHasData(mBinding.scLeftRight, mBinding.scZero) + + refreshEveryPointUi() + } + } + + private fun refreshEveryPointUi() { + mBinding.llPoints.removeAllViews() + for (point in viewModel.settingData.pointList) { + val itemView = + layoutInflater.inflate(R.layout.new_item_station_setting_point_setting, null) + val params = ViewGroup.MarginLayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + + val tvPoint = itemView.findViewById(R.id.tvPoint) + val scAloneMeasureDistance = + itemView.findViewById(R.id.scAloneMeasureDistance) + val scOpenAtr = itemView.findViewById(R.id.scOpenAtr) + val spinnerPrismType = itemView.findViewById(R.id.spinnerPrismType) + + tvPoint.text = viewModel.settingData.getPointName(point.originalPointId) + //单独测距 + scAloneMeasureDistance.isChecked = point.isAloneDistance + + setDisEnableByHasData(scAloneMeasureDistance) + + setItemSpinnerData(spinnerPrismType, scOpenAtr, point) + + params.topMargin = ScreenUtil.dp2px(requireContext(), 12f) + mBinding.llPoints.addView(itemView, params) + } + } + + override fun checkSaveNot(): Boolean { + return false + } + + private fun setItemSpinnerData( + spinner: Spinner, + scOpenAtr: SwitchCompat, + point: SurveyorPoint + ) { + spinner.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + viewModel.settingData.getAllPrismNameList() + ) + spinner.setSelection(viewModel.settingData.getPointPrismSelection(point.originalPointId)) + spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, + view: View?, + position: Int, + id: Long + ) { + val prismRecord = viewModel.settingData.getPrismRecord(position) + setItemOpenAtr(scOpenAtr, prismRecord, point) + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + } + + } + } + + private fun setItemOpenAtr( + scOpenAtr: SwitchCompat, + selectPrismRecord: PrismRecord, + point: SurveyorPoint + ) { + val openAtrEnable = SurveyorOpenAtrUtil.isOpenAtr( + selectPrismRecord.prismType, + selectPrismRecord.prismTypeLarge + ) + val openAtrSurveyorPoint = SurveyorOpenAtrUtil.isOpenAtr(point) + val openAtr = openAtrEnable && openAtrSurveyorPoint + scOpenAtr.isChecked = openAtr + scOpenAtr.isEnabled = openAtrEnable + } + + override fun setDataToStation() { + if (mBinding.scLeftRight.visibility == View.VISIBLE) { + viewModel.setStationLeftRightToStation(mBinding.scLeftRight.isChecked) + } + if (mBinding.scZero.visibility == View.VISIBLE) { + viewModel.setStationZeroToStation(mBinding.scZero.isChecked) + } + //显示斜距还是平距 + viewModel.setStationShowSlop(mBinding.showSlopSwitch.isChecked) + + //更新测点 + for (i in 0 until mBinding.llPoints.childCount) { + val itemView = mBinding.llPoints.getChildAt(i) + val scAloneMeasureDistance = + itemView.findViewById(R.id.scAloneMeasureDistance) + val spinnerPrismType = itemView.findViewById(R.id.spinnerPrismType) + val scOpenAtr = itemView.findViewById(R.id.scOpenAtr) + + viewModel.setPointSettingToStation( + i, + scAloneMeasureDistance.isChecked, + spinnerPrismType.selectedItemPosition, + !scOpenAtr.isChecked + ) + } + + //更新测站的单独测距状态 +// viewModel.updateSeparetionToStation() + + } + + private fun setDisEnableByHasData(vararg ets: View) { + if (viewModel.hasSurveyorData) { + for (item in ets) { + item.isEnabled = false + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingVm.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingVm.kt new file mode 100644 index 0000000..27342fb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingVm.kt @@ -0,0 +1,223 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import androidx.room.withTransaction +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.util.StationUtil +import com.bingce.controlnetwork.newui.stationsetting.model.StationSettingEnvironmentData +import com.bingce.controlnetwork.newui.stationsetting.model.StationSettingHeightData +import com.bingce.controlnetwork.newui.stationsetting.model.StationSettingSettingData + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class StationSettingVm : ViewModel() { + + val environmentData = StationSettingEnvironmentData() + val heightData = StationSettingHeightData() + val settingData = StationSettingSettingData() + + private lateinit var stationId: String + var stationRecord: SurveyorStationRecord? = null + + //默认有测量数据 + var hasSurveyorData = true + + + fun getLastEnvironmentData(callBack: () -> Unit) { + viewModelScope.launch { + withContext(Dispatchers.IO) { + environmentData.getLastData() + } + if (isHasNotEnvironmentData()) { + ToastUtils.showShort("没有上次数据") + return@launch + } + callBack() + } + } + + /** + * 获取默认的环境数据 + */ + fun getDefaultEnvironmentData() { + environmentData.getStandardData() + } + + fun getEnvironmentData(callBack: () -> Unit) { + viewModelScope.launch { + withContext(Dispatchers.IO) { + environmentData.getLastData() + } + if (isHasNotEnvironmentData()) { + getDefaultEnvironmentData() + } + callBack() + } + } + + //没有环境数据(只判断温度就够了) + private fun isHasNotEnvironmentData() = environmentData.temperature == null + + + fun initStationId(stationId: String, callBack: () -> Unit) { + this.stationId = stationId + viewModelScope.launch(Dispatchers.IO) { + hasSurveyorData = StationUtil.hasSurveyorData(stationId) + withContext(Dispatchers.Main) { + callBack() + } + } + } + + /** + * 获取测站相关数据的入口 + */ + fun getStationRecord(callBack: () -> Unit) { + if (stationRecord != null) { + callBack() + return + } + synchronized(this) { + viewModelScope.launch(Dispatchers.IO) { + if (stationRecord == null) { + stationRecord = SurveyorDatabaseFactory.instance.getSurveyorStation() + .getRecordSync(stationId) + //初始化高度信息 + heightData.initData(stationRecord) + //初始化测站设置信息 + settingData.initData(stationRecord) + } + + if (stationRecord != null) { + withContext(Dispatchers.Main) { + callBack() + } + } + } + } + } + + fun setEnvironmentDataToStation( + temperature: String, + humidity: String, + airPressure: String, + ) { + stationRecord?.let { + it.temperature = temperature + it.humidity = humidity + it.airPressure = airPressure + } + } + + fun setPointDataToStation(pointIndex: Int, pointHeight: String) { + stationRecord?.let { + heightData.updatePointData(pointIndex, pointHeight) + } + } + + /** + * 更新测点的状态 + * 当有一个点是单独测距这个测站就是单独测距 + */ + fun setPointSettingToStation( + pointIndex: Int, + aloneMeasureDistance: Boolean, + selectionPrismType: Int, + isOpenAtrNot:Boolean + ) { + stationRecord?.let { + settingData.updatePointSettingData( + pointIndex, + aloneMeasureDistance, + selectionPrismType, + isOpenAtrNot + ) + } + } + + fun setStationHeightToStation(instrumentHeight: String) { + stationRecord?.let { + it.instrumentHeight = instrumentHeight + } + } + + fun setStationLeftRightToStation(leftRight: Boolean) { + stationRecord?.let { + it.isLeftAndRightSurveyor = leftRight + } + } + + fun getStationLeftRight() = stationRecord?.leftAndRightSurveyor ?: false + fun getShowSlop() = stationRecord?.showSlopDistance ?: true + fun setStationShowSlop(showSlopDistance: Boolean) { + stationRecord?.let { + it.showSlopDistance = showSlopDistance + } + } + + fun setStationZeroToStation(zero: Boolean) { + stationRecord?.let { + it.autoClose = zero + } + } + + fun getStationZero() = stationRecord?.autoClose ?: false + + fun getStationSurveyorPointSize() = stationRecord?.items?.size ?: 0 + + /** + * 存储数据库 + */ + fun saveToDataBase(callBack: () -> Unit) { + if (stationRecord == null) return + viewModelScope.launch { + withContext(Dispatchers.IO){ + saveLastConfigData() + SurveyorDatabaseFactory.instance.surveyorStation.update(stationRecord) + } + callBack() + } + } + + private fun saveLastConfigData() { + val configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource() + //环境信息 + configDataSource.setSync( + ConfigConstants.KEY_LAST_TEMPERATURE, + stationRecord!!.getTemperature() + ) + configDataSource.setSync( + ConfigConstants.KEY_LAST_AIR_PRESSURE, + stationRecord!!.getAirPressure() + ) + configDataSource.setSync( + ConfigConstants.KEY_LAST_HUMIDITY, + stationRecord!!.getHumidity() + ) + } + +// /** +// * 当测点的状态更新完再调用这个方法 +// */ +// fun updateSeparetionToStation() { +// stationRecord?.let { +// var aloneDistance = false +// for (item in it.items) { +// if (item.isAloneDistance) { +// aloneDistance = true +// break +// } +// } +// it.aloneMeasureDistance = aloneDistance +// } +// } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingsActivity.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingsActivity.kt new file mode 100644 index 0000000..a519b54 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingsActivity.kt @@ -0,0 +1,153 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import android.content.Context +import android.content.Intent +import android.view.Menu +import android.view.MenuItem +import androidx.activity.viewModels +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.viewpager.widget.ViewPager.OnPageChangeListener +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.FastClickUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewActivityStationSettingBinding +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import com.bingce.controlnetwork.util.KeyboardUtil +import org.greenrobot.eventbus.EventBus + +class StationSettingsActivity : BaseBindingActivity() { + + private val viewModel by viewModels() + + + private val fragments = mutableListOf() + private val fragmentTitleList = listOf("仪高镜高", "环境信息", "测站设置") + + companion object { + @JvmStatic + fun start(context: Context, stationId: String?) { + if (stationId == null) { + return + } + context.startActivity(Intent(context, StationSettingsActivity::class.java).apply { + putExtra(BundleConstants.KEY_SURVEYOR_STATION_ID, stationId) + }) + } + } + + override fun getBinding(): NewActivityStationSettingBinding { + return NewActivityStationSettingBinding.inflate(layoutInflater) + } + + override fun initView() { + viewModel.initStationId(getStationId()) { + initViewPager() + } + } + + override fun initData() { + + } + + private fun initViewPager() { + fragments.add(StationSettingHeightFragment()) + fragments.add(StationSettingEnvironmentFragment()) + fragments.add(StationSettingSettingFragment()) + + mBinding.vp.offscreenPageLimit = 3 + mBinding.vp.adapter = MyPagerAdapter(supportFragmentManager) + mBinding.tabLayout.setViewPager(mBinding.vp) + mBinding.vp.addOnPageChangeListener(object : OnPageChangeListener { + override fun onPageScrolled( + position: Int, + positionOffset: Float, + positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + + } + + override fun onPageScrollStateChanged(state: Int) { + + } + }) + +// //设置当前tab为仪高镜高 +// mBinding.vp.currentItem = 1 + } + + + private inner class MyPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { + override fun getCount(): Int { + return fragments.size + } + + override fun getPageTitle(position: Int): CharSequence { + return fragmentTitleList[position] + } + + override fun getItem(position: Int): Fragment { + return fragments[position] + } + + override fun getItemPosition(`object`: Any): Int { + return POSITION_NONE + } + } + + private fun getStationId(): String { + return intent.getStringExtra(BundleConstants.KEY_SURVEYOR_STATION_ID)!! + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_save, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.menuSave) { + FastClickUtil.click { + KeyboardUtil.hideSoftInput() + startSave() + } + } + return super.onOptionsItemSelected(item) + } + + private fun startSave() { + //检查未完成的选项 + for (fragment in fragments) { + val operate = fragment as IStationSettingOperate + if (operate.checkSaveNot()) { + val fragmentNotFinishPos = fragments.indexOf(fragment) + if (mBinding.vp.currentItem != fragmentNotFinishPos) { + mBinding.tabLayout.currentTab = fragmentNotFinishPos + } + return + } + } + //赋值 + for (fragment in fragments) { + val operate = fragment as IStationSettingOperate + operate.setDataToStation() + } + + viewModel.saveToDataBase { +// EventBus.getDefault().post(ReplaceSurveyorFragmentEvent()) + ToastUtils.showShort(R.string.save_success) + } + + } + + override fun onBackPressed() { + if (isFinishAtOnce()) { + super.onBackPressed() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingEnvironmentData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingEnvironmentData.kt new file mode 100644 index 0000000..b2839f5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingEnvironmentData.kt @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.newui.stationsetting.model + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.surveyor.method.model.MeasureConstant + +class StationSettingEnvironmentData { + var temperature: String? = null + var humidity: String? = null + var airPress: String? = null + + + /** + * 获取上次数据 + */ + @WorkerThread + fun getLastData() { + val configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource() + val temperature = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_TEMPERATURE) + val humidity = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_HUMIDITY) + val airPress = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_AIR_PRESSURE) + + this.temperature = temperature?.configValue + this.humidity = humidity?.configValue + this.airPress = airPress?.configValue + } + + /** + * 获取标准气象数据 + */ + fun getStandardData() { + this.temperature = MeasureConstant.DEFAULT_TEMPERATURE + this.humidity = MeasureConstant.DEFAULT_HUMIDITY + this.airPress = MeasureConstant.DEFAULT_AIR_PRESSURE + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingHeightData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingHeightData.kt new file mode 100644 index 0000000..e49a96b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingHeightData.kt @@ -0,0 +1,58 @@ +package com.bingce.controlnetwork.newui.stationsetting.model + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint + + +/** + * 高度tab相关数据 + */ +class StationSettingHeightData { + + private var instrumentHeight: String? = null + val pointList = mutableListOf() + + private val pointNameMap = hashMapOf() + private val pointHeightMap = hashMapOf() + + @WorkerThread + fun initData(stationRecord: SurveyorStationRecord?) { + if (stationRecord?.items == null) return + instrumentHeight = stationRecord.instrumentHeight + + for (point in stationRecord.items) { + if (point.type == SurveyorPoint.TYPE_STATION || point.isWellSteel) { + //忽略站点和钢丝点 + continue + } + pointList.add(point) + val pointRecord = + SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(point.originalPointId) + pointNameMap[point.originalPointId] = pointRecord.name + pointHeightMap[point.originalPointId] = point.prismHeight + } + } + + fun getPointName(pointId: String) = pointNameMap[pointId] + fun getPointHeight(pointId: String): String { + return pointHeightMap[pointId] ?: "0" + } + + fun getInstrumentHeight(): String { + return instrumentHeight ?: "0" + } + + /** + * 保存时 + */ + fun updatePointData(pointIndex: Int, pointHeight: String) { + val surveyorPoint = pointList[pointIndex] + //点高 + surveyorPoint.prismHeight = pointHeight + } + +} + + diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingSettingData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingSettingData.kt new file mode 100644 index 0000000..2289daa --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingSettingData.kt @@ -0,0 +1,88 @@ +package com.bingce.controlnetwork.newui.stationsetting.model + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint + + +class StationSettingSettingData { + + val pointList = mutableListOf() + private val pointNameMap = hashMapOf() + + private val pointPrismMap = hashMapOf() + private lateinit var prismAllList: List + private val prismAllTypeNameList = mutableListOf() + + + @WorkerThread + fun initData(stationRecord: SurveyorStationRecord?) { + if (stationRecord?.items == null) return + + prismAllList = SurveyorDatabaseFactory.instance.getPrismManagerDataSource().allRecordSync + for (prism in prismAllList) { + prismAllTypeNameList.add(prism.prismTypeName) + } + + for (point in stationRecord.items) { + if (point.type == SurveyorPoint.TYPE_STATION || point.isWellSteel) { + //忽略站点 + continue + } + pointList.add(point) + val pointRecord = + SurveyorDatabaseFactory.instance.getPointDataSource() + .findByIdSync(point.originalPointId) + pointNameMap[point.originalPointId] = pointRecord.name + + pointPrismMap[point.originalPointId] = PrismRecord().apply { + prismType = point.prismType + prismTypeName = point.prismTypeName + prismTypeConstant = point.prismTypeConstant + } + } + } + + fun getPointName(pointId: String) = pointNameMap[pointId] + + fun getPointPrismSelection(pointId: String): Int { + val prismRecord = pointPrismMap[pointId] + for ((index, record) in prismAllList.withIndex()) { + if (record.prismTypeName.equals(prismRecord?.prismTypeName)) { + return index + } + } + return -1 + } + + fun getAllPrismNameList(): List { + return prismAllTypeNameList + } + + /** + * 保存时 + */ + fun updatePointSettingData( + pointIndex: Int, + aloneMeasureDistance: Boolean, + selectionPosPrismType: Int, + isOpenAtrNot: Boolean + ) { + val surveyorPoint = pointList[pointIndex] + surveyorPoint.isAloneDistance = aloneMeasureDistance + //棱镜类型相关 + val prismRecord = getPrismRecord(selectionPosPrismType) + surveyorPoint.prismType = prismRecord.prismType + surveyorPoint.prismTypeLarge = prismRecord.prismTypeLarge + surveyorPoint.prismTypeConstant = prismRecord.prismTypeConstant + surveyorPoint.prismTypeName = prismRecord.prismTypeName + //openAtr + surveyorPoint.isOpenAtrNot = isOpenAtrNot + } + + fun getPrismRecord(selectionPosPrismType: Int) = prismAllList[selectionPosPrismType] + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/ProjectListViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/ProjectListViewHolder.java new file mode 100644 index 0000000..f0c4b29 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/ProjectListViewHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.newui.viewholder; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.NewItemProjectListBinding; + + +public class ProjectListViewHolder extends RecyclerView.ViewHolder { + public final NewItemProjectListBinding mBinding; + + public ProjectListViewHolder(NewItemProjectListBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/BaseSelectItemFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/BaseSelectItemFragment.kt new file mode 100644 index 0000000..ffa39cd --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/BaseSelectItemFragment.kt @@ -0,0 +1,179 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.ViewGroup.MarginLayoutParams +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.LifecycleOwner +import androidx.recyclerview.widget.RecyclerView + +import com.bingce.controlapphelper.model.IUniversalListItem +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentBaseSelectItemBinding +import com.bingce.controlnetwork.databinding.NewItemSelectItemBinding +import com.bingce.utils.ScreenUtil + + +/** + * 类似选择项目类型的底部弹框 + */ +abstract class BaseSelectItemFragment : DialogFragment() { + + private var _binding: NewFragmentBaseSelectItemBinding? = null + private val mBinding get() = _binding!! + + private val dataList = mutableListOf>() + + + companion object { + private const val KEY_REQUEST_SELECT = "__SELECT__" + private const val KEY_TYPE = "__SELECT_TYPE__" + + @JvmStatic + fun select( + fragment: BaseSelectItemFragment, + fragmentManager: FragmentManager, + lifecycleOwner: LifecycleOwner, + callback: ISelectItem + ) { + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner + ) { requestKey: String, result: Bundle -> + if (KEY_REQUEST_SELECT == requestKey) { + callback.onBack(result.getString(KEY_TYPE)!!) + } + } + fragment.show(fragmentManager, null) + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = NewFragmentBaseSelectItemBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) +// addMargin(view) + mBinding.tvTitle.text = getTitle() + initAdapter() + initListener() + } + + private fun initListener() { + mBinding.cancel.setOnClickListener { + dismissDialog() + } + } + + private fun dismissDialog() { + dismissAllowingStateLoss() + } + + override fun onStart() { + super.onStart() + dialog?.window?.run { + setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + val params = attributes + params.gravity = Gravity.BOTTOM + params.width = ScreenUtil.getScreenWidth(requireContext()) - ScreenUtil.dp2px( + requireContext(), + 24f + ) + params.y = ScreenUtil.dp2px( + requireContext(), + 12f + ) + + setWindowAnimations(R.style.BottomDialogAnimation) + //最后设置参数 + attributes = params + } + + } + + private fun addMargin(view: View) { + val layoutParams = view.layoutParams as MarginLayoutParams + val margin = ScreenUtil.dp2px(requireContext(), 16f) + layoutParams.setMargins(margin, margin, margin, margin) + view.setLayoutParams(layoutParams) + view.requestLayout() + } + + private fun initAdapter() { + dataList.addAll(getDataList()) + mBinding.recyclerView.addItemDecoration( + HorDividerDecoration(requireContext()) + ) + mBinding.recyclerView.adapter = Adapter() + } + + abstract fun getDataList(): List> + + abstract fun getTitle(): String + + + private inner class Adapter : RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + NewItemSelectItemBinding.inflate( + layoutInflater, + parent, + false + ) + ) + } + + override fun getItemCount(): Int { + return dataList.size + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val item = dataList[position] + holder.binding.tv.text = item.name + + holder.itemView.setOnClickListener { + backData(item.value) + } + } + + } + + private class ViewHolder(val binding: NewItemSelectItemBinding) : + RecyclerView.ViewHolder(binding.root) + + private fun backData(value: String) { + val args = Bundle() + args.putString(KEY_TYPE, value) + getParentFragmentManager().setFragmentResult( + KEY_REQUEST_SELECT, + args + ) + dismissDialog() + } + + + interface ISelectItem { + fun onBack(value: String) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/HorDividerDecoration.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/HorDividerDecoration.kt new file mode 100644 index 0000000..d28b37e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/HorDividerDecoration.kt @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import android.content.Context +import androidx.core.content.ContextCompat +import com.bingce.controlnetwork.R +import com.bingce.controlapphelper.widget.swiperecyclerview.widget.DefaultItemDecoration + +class HorDividerDecoration(context: Context) : DefaultItemDecoration( + ContextCompat.getColor(context, R.color.hor_line), + 1, 1 +) \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationFragment.kt new file mode 100644 index 0000000..7ba1286 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationFragment.kt @@ -0,0 +1,42 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.STATION_TYPE_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.STATION_TYPE_1 +import com.bingce.controlapphelper.model.IUniversalListItem + +class SelectIDetectionStationFragment : BaseSelectItemFragment() { + override fun getDataList(): List> { + return listOf( + Bean( + LevelIDetectionConstant.getStationTypeShow(STATION_TYPE_0), + STATION_TYPE_0.toString() + ), + Bean( + LevelIDetectionConstant.getStationTypeShow(STATION_TYPE_1), + STATION_TYPE_1.toString() + ), + ) + } + + override fun getTitle(): String { + return "选择测站" + } + + class Bean(private val name: String, private val type: String) : + IUniversalListItem { + override fun getName(): String { + return name + } + + override fun getId(): String { + return "" + } + + override fun getValue(): String { + return type + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationMeasureTypeFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationMeasureTypeFragment.kt new file mode 100644 index 0000000..f7009ed --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationMeasureTypeFragment.kt @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.A_I_B_I +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.A_I_I_B +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.I_A_B_I +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.getMeasureTypeShowLong +import com.bingce.controlapphelper.model.IUniversalListItem + +class SelectIDetectionStationMeasureTypeFragment : BaseSelectItemFragment() { + override fun getDataList(): List> { + return listOf( + Bean(getMeasureTypeShowLong(I_A_B_I), I_A_B_I), + Bean(getMeasureTypeShowLong(A_I_I_B), A_I_I_B), + Bean(getMeasureTypeShowLong(A_I_B_I), A_I_B_I), + ) + } + + override fun getTitle(): String { + return "选择检测方法" + } + + class Bean(private val name: String, private val type: String) : + IUniversalListItem { + override fun getName(): String { + return name + } + + override fun getId(): String { + return "" + } + + override fun getValue(): String { + return type + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectProjectTypeFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectProjectTypeFragment.kt new file mode 100644 index 0000000..de08a4b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectProjectTypeFragment.kt @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.model.IUniversalListItem +import com.bingce.controlnetwork.R + +class SelectProjectTypeFragment : BaseSelectItemFragment() { + override fun getDataList(): List> { + return listOf( + Bean(getString(R.string.triangular_wire), ProjectTypeValue.TRIANGLE), +// Bean(getString(R.string.contact_measurement), ProjectTypeValue.CONNECTION), + Bean(getString(R.string.elevation_wire_trial), ProjectTypeValue.HEIGHT_TRAVERSE), + Bean(getString(R.string.level), ProjectTypeValue.LEVEL) + ) + } + + override fun getTitle(): String { + return getString(R.string.new_project) + } + + + class Bean(private val projectTypeName: String, private val projectType: String) : + IUniversalListItem { + override fun getName(): String { + return projectTypeName + } + + override fun getId(): String { + return "" + } + + override fun getValue(): String { + return projectType + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuDelete.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuDelete.kt new file mode 100644 index 0000000..3f5f31e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuDelete.kt @@ -0,0 +1,42 @@ +package com.bingce.controlnetwork.newui.widget.swipemenu + +import android.content.Context +import android.view.ViewGroup +import com.bingce.controlapphelper.util.Tools + +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenu +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenuCreator +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenuItem +import com.bingce.controlnetwork.R +import com.bingce.utils.ScreenUtil + +class SwipeMenuDelete(val context: Context) : SwipeMenuCreator { + + companion object { + @JvmStatic + fun isDeleteMenu(menuPos: Int) = menuPos == 0 + } + + override fun onCreateMenu(leftMenu: SwipeMenu, rightMenu: SwipeMenu, position: Int) { + val width = ScreenUtil.dp2px(context, 70f) + + // 1. MATCH_PARENT 自适应高度,保持和Item一样高; + // 2. 指定具体的高,比如80; + // 3. WRAP_CONTENT,自身高度,不推荐; + val height = ViewGroup.LayoutParams.MATCH_PARENT + + // 添加右侧的,如果不添加,则右侧不会出现菜单。 + val deleteItem: SwipeMenuItem = + SwipeMenuItem(context) + .setWidth(width) + .setHeight(height) + .setBackgroundColor(Tools.getColor(R.color.md_red_400)) + .setText("删除") + .setTextSize(14) + .setTextColorResource(R.color.white) + //添加右侧菜单 + rightMenu.addMenuItem(deleteItem) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuEditDelete.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuEditDelete.kt new file mode 100644 index 0000000..727ac62 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuEditDelete.kt @@ -0,0 +1,54 @@ +package com.bingce.controlnetwork.newui.widget.swipemenu + +import android.content.Context +import android.view.ViewGroup +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenu +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenuCreator +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenuItem +import com.bingce.controlnetwork.R +import com.bingce.utils.ScreenUtil + +class SwipeMenuEditDelete(val context: Context) : SwipeMenuCreator { + + companion object { + @JvmStatic + fun isEditMenu(menuPos: Int) = menuPos == 0 + + @JvmStatic + fun isDeleteMenu(menuPos: Int) = menuPos == 1 + } + + override fun onCreateMenu(leftMenu: SwipeMenu, rightMenu: SwipeMenu, position: Int) { + val width = ScreenUtil.dp2px(context, 70f) + + // 1. MATCH_PARENT 自适应高度,保持和Item一样高; + // 2. 指定具体的高,比如80; + // 3. WRAP_CONTENT,自身高度,不推荐; + val height = ViewGroup.LayoutParams.MATCH_PARENT + + // 添加右侧的,如果不添加,则右侧不会出现菜单。 + val eidtItem: SwipeMenuItem = + SwipeMenuItem(context) + .setWidth(width) + .setHeight(height) + .setBackgroundColor(Tools.getColor(R.color.md_blue_400)) + .setText("编辑") + .setTextSize(14) + .setTextColorResource(R.color.white) + + val deleteItem: SwipeMenuItem = + SwipeMenuItem(context) + .setWidth(width) + .setHeight(height) + .setBackgroundColor(Tools.getColor(R.color.md_red_400)) + .setText("删除") + .setTextSize(14) + .setTextColorResource(R.color.white) + //添加右侧菜单 + rightMenu.addMenuItem(eidtItem) + rightMenu.addMenuItem(deleteItem) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/switchtext/SwitchWithText.java b/app/src/main/java/com/bingce/controlnetwork/newui/widget/switchtext/SwitchWithText.java new file mode 100644 index 0000000..71e1436 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/switchtext/SwitchWithText.java @@ -0,0 +1,97 @@ +package com.bingce.controlnetwork.newui.widget.switchtext; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; + +import com.bingce.controlnetwork.R; + + +public class SwitchWithText extends LinearLayout { + + private String name; + private String onText; + private String offText; + private boolean checked; + private SwitchCompat switchButton; + private TextView tvDesc; + + public SwitchWithText(Context context) { + super(context); + init(context, null); + } + + public SwitchWithText(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public SwitchWithText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + LayoutInflater inflater = LayoutInflater.from(context); + inflater.inflate(R.layout.new_switch_with_layout, this); + + switchButton = findViewById(R.id.switchButton); + tvDesc = findViewById(R.id.tvDesc); + + //获取属性 + if (attrs != null) { + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SwitchWithText); + name = a.getString(R.styleable.SwitchWithText_name); + onText = a.getString(R.styleable.SwitchWithText_onText); + offText = a.getString(R.styleable.SwitchWithText_offText); + checked = a.getBoolean(R.styleable.SwitchWithText_onChecked, false); + a.recycle(); + } + + switchButton.setChecked(checked); + switchButton.setText(name); + refreshDescText(); + + switchButton.setOnCheckedChangeListener((buttonView, isChecked) -> { + checked = isChecked; + refreshDescText(); + if (checkChangeListener != null) { + checkChangeListener.onCheck(isChecked); + } + }); + + } + + public void setChecked(boolean checked) { + switchButton.setChecked(checked); + } + + public boolean isChecked() { + return switchButton.isChecked(); + } + + private void refreshDescText() { + if (checked) { + tvDesc.setText(onText); + } else { + tvDesc.setText(offText); + } + } + + private ICheckChangeListener checkChangeListener; + + public void setOnCheckChangeListener(ICheckChangeListener checkChangeListener) { + this.checkChangeListener = checkChangeListener; + } + + public interface ICheckChangeListener { + void onCheck(boolean checked); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/StateManagerAloneDistance.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/StateManagerAloneDistance.java index f03b45f..1d05490 100644 --- a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/StateManagerAloneDistance.java +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/StateManagerAloneDistance.java @@ -361,7 +361,7 @@ public class StateManagerAloneDistance implements IAutoModeSwitcher, ISurveyStat boolean supportAuto = Test.DEBUG; //App.isDebug() if (isSupportAutoMode && - (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProProLevel())) { + (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProLevel())) { supportAuto = true; } StateManagerAloneDistance manager = new StateManagerAloneDistance(supportAuto, diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoSurveyorState.java index 7cdd659..d02be7c 100644 --- a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoSurveyorState.java +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoSurveyorState.java @@ -13,6 +13,7 @@ import com.bingce.controlapphelper.surveyor.state.StateType; import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParam; +import com.bingce.controlapphelper.util.DebugMsgUtil; import com.bingce.controlapphelper.util.Tools; import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.surveyor.state.StateConstants; @@ -120,6 +121,9 @@ class _DoSurveyorState extends __BaseState implements ISurveyorListener, ISurvey onCompleted(RESULT_FAILURE_EXCEED_MAX, Tools.getString(R.string.many_measure_failed_1)); } else { //再次尝试 + DebugMsgUtil.canWrite("仪器返回错误信息:" + errorMsg); + DebugMsgUtil.canWrite("开始再次测量"); + sendSurveyRequest(); ToastUtils.showShort(R.string.receive_data_time_out); } diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/StateManager.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/StateManager.java index 2b474e0..4ecd238 100644 --- a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/StateManager.java +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/StateManager.java @@ -44,6 +44,8 @@ import com.bingce.controlnetwork.fragment.TipsFragment; import com.bingce.controlnetwork.surveyor.state.AutoModeType; import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; import com.bingce.controlnetwork.surveyor.state.StateConstants; +import com.bingce.controlnetwork.surveyor.util.checkadjust.AngleDistanceCheckAdjust; +import com.bingce.controlnetwork.surveyor.util.checkadjust.IStationCheck; import com.bingce.coordlib.model.Coordinate; import com.bingce.totalstation.ControlSurveyData; import com.bingce.totalstation.ControlSurveyResult; @@ -86,6 +88,8 @@ public class StateManager implements IAutoModeSwitcher, ISurveyState, IStateType private final PointRecord stationPointRecord; final boolean supportAutoSurvey; + private final IStationCheck stationCheck = new AngleDistanceCheckAdjust(); + private StateManager(final boolean supportAutoSurvey,//是否支持自动测量 final @NonNull RequestSurveyorParamAuto requestSurveyorParamAuto, final @NonNull SurveyorStationRecord stationRecord, @@ -267,7 +271,7 @@ public class StateManager implements IAutoModeSwitcher, ISurveyState, IStateType } public String stationCheckOnly() { - return _CheckStationState._stationCheck(stationId(), toleranceRecord, cachedData); + return stationCheck.check(stationId(), toleranceRecord, cachedData); } public void stationAdjustOnly(String showType) { @@ -404,7 +408,7 @@ public class StateManager implements IAutoModeSwitcher, ISurveyState, IStateType boolean supportAuto = Test.DEBUG; //AppUtils.isAppDebug() if (isSupportAutoMode && - (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProProLevel())) { + (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProLevel())) { supportAuto = true; } StateManager manager = new StateManager(supportAuto, diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationState.java index b741368..75e2aaa 100644 --- a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationState.java +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationState.java @@ -13,25 +13,16 @@ import com.bingce.controlapphelper.datasource.database.schedule.SurveyorSchedule import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; -import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; -import com.bingce.controlapphelper.model.LeftOrRight; import com.bingce.controlapphelper.surveyor.data.ICachedData; import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; import com.bingce.controlapphelper.surveyor.data.ISurveyorData; -import com.bingce.controlapphelper.surveyor.method.AverageValueMethod; -import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod; -import com.bingce.controlapphelper.surveyor.method.RadianMethod; -import com.bingce.controlapphelper.surveyor.method.ValueOf2cMethod; -import com.bingce.controlapphelper.surveyor.method.model.CacheResult; -import com.bingce.controlapphelper.surveyor.method.model.SdAngleValueType; import com.bingce.controlapphelper.surveyor.state.StateType; -import com.bingce.controlapphelper.util.IdUtil; -import com.bingce.controlapphelper.util.SurveyorCycleUtil; import com.bingce.controlapphelper.util.Tools; import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.fragment.SelectReSurveyorPointFragment; +import com.bingce.controlnetwork.surveyor.util.checkadjust.AngleDistanceCheckAdjust; +import com.bingce.controlnetwork.surveyor.util.checkadjust.IStationCheck; import com.bingce.utils.ThreadPoolUtil; -import com.bingce.utils.Util; import java.util.ArrayList; import java.util.List; @@ -44,6 +35,8 @@ import java.util.List; */ class _CheckStationState extends __BaseState { + private final IStationCheck stationCheck = new AngleDistanceCheckAdjust(); + public _CheckStationState(StateManager stateManager) { super(StateType.checkStation, stateManager); } @@ -51,7 +44,7 @@ class _CheckStationState extends __BaseState { @Override public void enter(Bundle args) { //执行测站检测 - String error = _stationCheck(stationId(), getToleranceRecord(), getCachedData()); + String error = stationCheck.check(stationId(), getToleranceRecord(), getCachedData()); if (error == null || error.isEmpty()) { //进入finish状态 navigation2(StateType.stationCheckedSuccess); @@ -177,239 +170,4 @@ class _CheckStationState extends __BaseState { () -> state.enterIdleAndClearSurveyStateAndResetAutoMode(true));//3.如果用户忽略,则停留在当前位置 } - - //检测合法性 - - /** - * 检测所有测回数据 - *

- * 在「无自动闭合」情况下,为了兼容「左右角」测量结果,根据pointId将所有测量数据存入map中 - * 根据「左角」测量来检测「测回间同方向值互差」,所有测回的归零值使用「左角」第一个point来做0点 - *

- * 如果是「自动闭合」情况,则忽略「左右角」测量,直接按照itemIndex依次计算,第个测回的归零值, - * 使用每次循环的itemIndex=0做0点 - * - * @param toleranceRecord 限差 - * @param cachedDataSource 缓存的测量数据 - * @return 错误信息,如果为null或空,说明没有错误 - */ - public static String _stationCheck(final String stationId, - final ToleranceDetailRecord toleranceRecord, - final ICachedData cachedDataSource) { - final int cycleCount = toleranceRecord.getCycleCount(); - final int surveyorCount = toleranceRecord.getSurveyorCount(); - - //*****测回间同方向值互差(水平角) - double horCyclesDirectValueDifference = toleranceRecord.getHorCyclesDirectValueDifference()/*horCyclesDirectValueDifference*/; - List<_ErrorItem> horValueError = new ArrayList<>(); - //*****测回间垂直角互差(垂直角) - double verCyclesAngleDifference = toleranceRecord.getVerCyclesAngleDifference()/*verCyclesAngleDifference*/; - List<_ErrorItem> verValueError = new ArrayList<>(); - - //执行计算 - for (int cycleI = 0; cycleI < cycleCount; cycleI++) { - List valuesI = - DeviationValueOfRadianMethod.zeroValueOfSingleCycleInLeftOrientation(stationId, cycleI, surveyorCount, cachedDataSource); - for (int cycleJ = cycleI + 1; cycleJ < cycleCount; cycleJ++) { - List valuesJ = - DeviationValueOfRadianMethod.zeroValueOfSingleCycleInLeftOrientation(stationId, cycleJ, surveyorCount, cachedDataSource); - if (valuesI.size() != valuesJ.size()) { - return Tools.getString(R.string.please_complete_all_retest_data); - } - int size = valuesI.size(); - for (int index = 0; index < size; index++) { - - double diff = Math.abs( - DeviationValueOfRadianMethod - .similarRadianDiff( - valuesI.get(index).horRadian, - valuesJ.get(index).horRadian)); - if (horCyclesDirectValueDifference < RadianMethod.radian2S(diff)) { - horValueError.add(new _ErrorItem(valuesI.get(index).pointName, - cycleI, cycleJ, RadianMethod.radian2S(diff))); - } - - diff = Math.abs(DeviationValueOfRadianMethod - .similarRadianDiff(valuesI.get(index).verRadian, valuesJ.get(index).verRadian)); - if (verCyclesAngleDifference < RadianMethod.radian2S(diff)) { - verValueError.add(new _ErrorItem(valuesI.get(index).pointName, - cycleI, cycleJ, RadianMethod.radian2S(diff))); - } - } - } - } - //*****测回间垂直角I互差(垂直角) - double verCyclesIDifference = toleranceRecord.getVerCyclesIDifference()/*verCyclesIDifference*/; - List<_ErrorItem> verIError = new ArrayList<>(); - //*****测回间斜距互差(距离) - double distCyclesDifference = toleranceRecord.getSlopeCycleDistanceDifference()/*slopeCycleDistanceDifference*/; - List<_ErrorItem> distError = new ArrayList<>(); - - List<_Point> pointArrayList = new ArrayList<>(); - //遍历第一测回,收集所有待测点id - for (int index = 0; index < cachedDataSource.pointCount(); index++) { - if (cachedDataSource.isPointAbandon(0, index)) { - continue; - } - pointArrayList.add(new _Point(cachedDataSource.pointId(0, index), - cachedDataSource.pointName(0, index), - cachedDataSource.isAloneDistance(0, index))); - } - //检测所有待测点i互差 - for (_Point point : pointArrayList) { - for (int cycleI = 0; cycleI < cycleCount; cycleI++) { - String leftRecordId_I = IdUtil.createSurveyorRecordId(stationId, cycleI, point.pointId, LeftOrRight.left); - String rightRecordId_I = IdUtil.createSurveyorRecordId(stationId, cycleI, point.pointId, LeftOrRight.right); - CacheResult value2C_I = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, leftRecordId_I, rightRecordId_I, - toleranceRecord.getSurveyorCount(), cachedDataSource); - CacheResult distanceLeftAndRightAverageValue_I = AverageValueMethod.leftAndRightValue(SdAngleValueType.distance, - leftRecordId_I, - rightRecordId_I, surveyorCount, cachedDataSource); - for (int cycleJ = cycleI + 1; cycleJ < cycleCount; cycleJ++) { - String leftRecordId_J = IdUtil.createSurveyorRecordId(stationId, cycleJ, point.pointId, LeftOrRight.left); - String rightRecordId_J = IdUtil.createSurveyorRecordId(stationId, cycleJ, point.pointId, LeftOrRight.right); - CacheResult value2C_J = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, leftRecordId_J, rightRecordId_J, - toleranceRecord.getSurveyorCount(), cachedDataSource); - CacheResult distanceLeftAndRightAverageValue_J = AverageValueMethod.leftAndRightValue(SdAngleValueType.distance, - leftRecordId_J, - rightRecordId_J, surveyorCount, cachedDataSource); - double verI = Math.abs(value2C_I.value - value2C_J.value); - if (verCyclesIDifference < verI) { - verIError.add(new _ErrorItem(point.pointName, cycleI, cycleJ, verI)); - } - - if (!point.aloneDistance) { - double distance = Math.abs(distanceLeftAndRightAverageValue_I.value - distanceLeftAndRightAverageValue_J.value); - if (distCyclesDifference < distance * 1000) { - distError.add(new _ErrorItem(point.pointName, cycleI, cycleJ, distance * 1000)); - } - } - - } - } - } - - return _errorString(horCyclesDirectValueDifference, verCyclesAngleDifference, verCyclesIDifference, distCyclesDifference, - horValueError, verValueError, verIError, distError); - } - - /** - * 根据超限信息生成错误描述 - * - * @param horValueError 水平角同方向值互差 - * @param verValueError 垂直角同方向值互差 - */ - private static String _errorString(double horLimit, double verLimit, double verILimit, double distLimit, - List<_ErrorItem> horValueError, List<_ErrorItem> verValueError, List<_ErrorItem> verIError, List<_ErrorItem> distError) { - if (horValueError.isEmpty() && verValueError.isEmpty()) { - return null; - } - StringBuilder stringBuilder = new StringBuilder(); - if (!horValueError.isEmpty()) { - stringBuilder.append(Tools.getString(R.string.cycle_between_same_direction_value_limit)) - .append(Util.formatDouble2String(horLimit, 1)) - .append("'')"); - for (_ErrorItem item : horValueError) { - stringBuilder - .append("\n ") - .append(item.pointName) - .append(":\n") - .append(" |") - .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) - .append("-") - .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) - .append("| = ") - .append(Util.formatDouble2String(item.difference, 1)) - .append("'')"); - } - } - - if (!verValueError.isEmpty()) { - stringBuilder.append("\n").append(Tools.getString(R.string.cycle_between_ver_angle_limit)) - .append(Util.formatDouble2String(verLimit, 1)) - .append("'')"); - for (_ErrorItem item : verValueError) { - stringBuilder - .append("\n ") - .append(item.pointName) - .append(":\n") - .append(" |") - .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) - .append("-") - .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) - .append("| = ") - .append(Util.formatDouble2String(item.difference, 1)) - .append("'')"); - } - } - - if (!verIError.isEmpty()) { - stringBuilder.append("\n").append(Tools.getString(R.string.ver_angle_i_same_direction_each_cycle)) - .append(Util.formatDouble2String(verILimit, 1)) - .append("'')"); - for (_ErrorItem item : verIError) { - stringBuilder - .append("\n ") - .append(item.pointName) - .append(":\n") - .append(" |") - .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) - .append("-") - .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) - .append("| = ") - .append(Util.formatDouble2String(item.difference, 1)) - .append("'')"); - } - } - - if (!distError.isEmpty()) { - stringBuilder.append("\n").append(Tools.getString(R.string.cycle_between_distance_limit_brackets)) - .append(Util.formatDouble2String(distLimit, 1)) - .append("'')"); - for (_ErrorItem item : distError) { - stringBuilder - .append("\n ") - .append(item.pointName) - .append(":\n") - .append(" |") - .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) - .append("-") - .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) - .append("| = ") - .append(Util.formatDouble2String(item.difference, 1)) - .append("'')"); - } - } - - return stringBuilder.toString(); - } - - /** - * 存储错误信息的item - */ - private static class _ErrorItem { - final String pointName; - final int cycleIndex1; - final int cycleIndex2; - final double difference; - - public _ErrorItem(String pointName, int cycleIndex1, int cycleIndex2, double difference) { - this.pointName = pointName; - this.cycleIndex1 = cycleIndex1; - this.cycleIndex2 = cycleIndex2; - this.difference = difference; - } - } - - private static class _Point { - final String pointId; - final String pointName; - final boolean aloneDistance; - - _Point(String pointId, String pointName, boolean aloneDistance) { - this.pointId = pointId; - this.pointName = pointName; - this.aloneDistance = aloneDistance; - } - } } diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoSurveyorState.java index d0eb34f..a04047a 100644 --- a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoSurveyorState.java +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoSurveyorState.java @@ -17,6 +17,7 @@ import com.bingce.controlapphelper.surveyor.state.StateType; import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParam; +import com.bingce.controlapphelper.util.DebugMsgUtil; import com.bingce.controlapphelper.util.IdUtil; import com.bingce.controlapphelper.util.SettingValueUtil; import com.bingce.controlapphelper.util.SurveyorCycleUtil; @@ -174,6 +175,9 @@ class _DoSurveyorState extends __BaseState implements ISurveyorListener, ISurvey onCompleted(RESULT_FAILURE_EXCEED_MAX, Tools.getString(R.string.many_measure_failed_1)); } else { //再次尝试 + DebugMsgUtil.canWrite("仪器返回错误信息:" + errorMsg); + DebugMsgUtil.canWrite("开始再次测量"); + sendSurveyRequest(); ToastUtils.showShort(R.string.receive_data_time_out); } diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/StateManagerHeightTraverse.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/StateManagerHeightTraverse.java index ff14250..4704a51 100644 --- a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/StateManagerHeightTraverse.java +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/StateManagerHeightTraverse.java @@ -246,11 +246,16 @@ public class StateManagerHeightTraverse implements IAutoModeSwitcher, ISurveySta enter(StateType.doDeleteAllCycle, _DoDeleteAllCycleState.args(stationId())); } - public void deleteCurrentStationSurveyorData(int cycleIndex) { + /** + * 删除当前测回记录(删除后视或前视的所有记录) + * + * @param cycleIndex + */ + public void deleteCurrentStationSurveyorData(int positionFragment) { if (isInValidate()) { return; } - enter(StateType.doDeleteCurrentCycle, _DoDeleteCurrentCycleState.args(stationId(), cycleIndex)); + enter(StateType.doDeleteCurrentCycle, _DoDeleteCurrentCycleState.args(stationId(), positionFragment)); } public void stationCheck() { @@ -322,7 +327,7 @@ public class StateManagerHeightTraverse implements IAutoModeSwitcher, ISurveySta //检测当前状态是否支持从外界主动改变状态 //如果是空闲或者是测站通过检测是有效的状态 - private boolean isInValidate() { + public boolean isInValidate() { return currentStateType != StateType.idle && StateType.stationCheckedSuccess != currentStateType && !isRotationReadyState(); @@ -343,7 +348,7 @@ public class StateManagerHeightTraverse implements IAutoModeSwitcher, ISurveySta private boolean _live = true; - boolean isDead() { + public boolean isDead() { return !_live; } @@ -403,7 +408,7 @@ public class StateManagerHeightTraverse implements IAutoModeSwitcher, ISurveySta } boolean supportAuto = Test.DEBUG; if (isSupportAutoMode && - (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProProLevel())) { + (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProLevel())) { supportAuto = true; } return new StateManagerHeightTraverse( diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteAllCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteAllCycleState.java index b84f3e3..af296b3 100644 --- a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteAllCycleState.java +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteAllCycleState.java @@ -2,6 +2,8 @@ package com.bingce.controlnetwork.surveyor.state.heighttraverse; import android.os.Bundle; +import androidx.annotation.WorkerThread; + import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; @@ -10,8 +12,6 @@ import com.bingce.controlapphelper.surveyor.data.ICachedData; import com.bingce.controlapphelper.surveyor.state.StateType; import com.bingce.utils.ThreadPoolUtil; -import com.bingce.controlnetwork.R; - /* * 删除本测站所有测回数据 * */ @@ -33,37 +33,40 @@ class _DoDeleteAllCycleState extends __BaseState { public void enter(Bundle args) { String stationId = args.getString(KEY_STATION_ID); - optionTipsWithStandStill(getContext().getString(R.string.tips_delete_station_all_surveyor_records), - () -> deleteAllCycleData(stationId)); + ThreadPoolUtil.execute(() -> deleteAllCycleData(stationId)); +// optionTipsWithStandStill(getContext().getString(R.string.tips_delete_station_all_surveyor_records), +// () -> deleteAllCycleData(stationId)); } + @WorkerThread private void deleteAllCycleData(String stationId) { - ThreadPoolUtil.execute(() -> { - //删除数据 - ICachedData cachedData = getCachedData(); - cachedData.deleteSurveyorRecord(stationId); - - //清除已经提示测站可以检测标识 - IConfigDataSource configDataSource = - SurveyorDatabaseFactory.instance.getConfigDataSource(); - String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; - configDataSource.setSync(key, ConfigConstants.VALUE_NO); - - //重置进度 - setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); - for (int cycleIndex = 0; cycleIndex < getToleranceRecord().getCycleCount(); cycleIndex++) { - setSingleCycleScheduleSync(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); - } - - //重置学习测量的标志 - resetLearnDataTag(); - - //从第一测回开始 - setCurrentCycleSync(0); - - //重新测量,并刷新 - findTargetFromBeginInCurrentCycle(true, 0); - }); + //删除数据 + ICachedData cachedData = getCachedData(); + cachedData.deleteSurveyorRecord(stationId); + + //清除已经提示测站可以检测标识 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; + configDataSource.setSync(key, ConfigConstants.VALUE_NO); + + //重置进度 + setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + for (int cycleIndex = 0; cycleIndex < getToleranceRecord().getCycleCount(); cycleIndex++) { + setSingleCycleScheduleSync(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + + //重置学习测量的标志 + resetLearnDataTag(); + + //从第一测回开始 + setCurrentCycleSync(0); + + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true, 0); + + refreshUI(); + } diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteCurrentCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteCurrentCycleState.java index 1f50f3e..559c32b 100644 --- a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteCurrentCycleState.java +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteCurrentCycleState.java @@ -2,26 +2,22 @@ package com.bingce.controlnetwork.surveyor.state.heighttraverse; import android.os.Bundle; -import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; -import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; -import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.LeftOrRight; import com.bingce.controlapphelper.surveyor.data.ICachedData; -import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse.MeasureHeightTraverseFragment; import com.bingce.utils.ThreadPoolUtil; -import com.bingce.controlnetwork.R; - class _DoDeleteCurrentCycleState extends __BaseState { private static final String KEY_STATION_ID = "__station_id"; - private static final String KEY_PERIOD_INDEX = "__period_index__"; + private static final String KEY_POSITION_FRAGMENT_INDEX = "__period_index__"; static Bundle args(String stationId, int periodIndex) { Bundle args = new Bundle(); args.putString(KEY_STATION_ID, stationId); - args.putInt(KEY_PERIOD_INDEX, periodIndex); + args.putInt(KEY_POSITION_FRAGMENT_INDEX, periodIndex); return args; } @@ -32,51 +28,77 @@ class _DoDeleteCurrentCycleState extends __BaseState { @Override public void enter(Bundle args) { String stationId = args.getString(KEY_STATION_ID); - int cycleIndex = args.getInt(KEY_PERIOD_INDEX); - - optionTipsWithStandStill(getContext().getString(R.string.tips_delete_current_cycle_surveyor_record), - () -> deleteSingleCycle(stationId, cycleIndex)); + int positionFragment = args.getInt(KEY_POSITION_FRAGMENT_INDEX); + String msg; + if (positionFragment == MeasureHeightTraverseFragment.POSITION_BACK_PAGE) { + msg = "是否确定删除后视的所有测回数据?"; + } else { + msg = "是否确定删除前视的所有测回数据?"; + } + optionTipsWithStandStill(msg, + () -> deleteSingleCycle(stationId, positionFragment)); } - private void deleteSingleCycle(String stationId, int cycleIndex) { + private void deleteSingleCycle(String stationId, int positionFragment) { ThreadPoolUtil.execute(() -> { ICachedData cachedData = getCachedData(); - int pointIndex = getCurrentIndex(); - - FindTargetMethod.Target target = _DoMove2NextValidateState.getTargetAscOrDesc(stationId, pointIndex, cachedData, - false, dataCategory -> !dataCategory.isEmptyData()); + int cycleCount = getToleranceRecord().cycleCount; - if (target == null) { - navigation2(StateType.idle); - return; - } - - int deleteCycleIndex = target.cycleIndex; - //删除数据 - ICachedData stationSurveyorDataSource = getCachedData(); - stationSurveyorDataSource.deleteSurveyorRecordSync(stationId, deleteCycleIndex); - - //清除已经提示测站可以检测标识 - IConfigDataSource configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource(); - String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; - configDataSource.setSync(key, ConfigConstants.VALUE_NO); - - if (deleteCycleIndex == 0) { - //当第一测回 - //重置学习测量的标志 - resetLearnDataTag(); + for (int cycleIndex = 0; cycleIndex < cycleCount; cycleIndex++) { + cachedData.deleteSurveyorRecord(stationId, cycleIndex, 0, LeftOrRight.left); + cachedData.deleteSurveyorRecord(stationId, cycleIndex, 0, LeftOrRight.right); } + //重置学习测量的标志 + resetLearnDataTag(); //重置所有测回和当次测回进度 setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); - setSingleCycleScheduleSync(deleteCycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); - //设置当前测回 - setCurrentCycleSync(deleteCycleIndex); + setCurrentCycleSync(0); //重新测量,并刷新 findTargetFromBeginInCurrentCycle(true, 0); + + refreshUI(); + +// +// int pointIndex = getCurrentIndex(); +// +// +// FindTargetMethod.Target target = _DoMove2NextValidateState.getTargetAscOrDesc(stationId, pointIndex, cachedData, +// false, dataCategory -> !dataCategory.isEmptyData()); +// +// if (target == null) { +// navigation2(StateType.idle); +// return; +// } +// +// int deleteCycleIndex = target.cycleIndex; +// //删除数据 +// ICachedData stationSurveyorDataSource = getCachedData(); +// stationSurveyorDataSource.deleteSurveyorRecordSync(stationId, deleteCycleIndex); +// +// //清除已经提示测站可以检测标识 +// IConfigDataSource configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource(); +// String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; +// configDataSource.setSync(key, ConfigConstants.VALUE_NO); +// +// if (deleteCycleIndex == 0) { +// //当第一测回 +// //重置学习测量的标志 +// resetLearnDataTag(); +// } +// +// //重置所有测回和当次测回进度 +// setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); +// setSingleCycleScheduleSync(deleteCycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); +// +// //设置当前测回 +// setCurrentCycleSync(deleteCycleIndex); +// +// //重新测量,并刷新 +// findTargetFromBeginInCurrentCycle(true, 0); }); } diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoSurveyorState.java index db91136..44a28cb 100644 --- a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoSurveyorState.java +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoSurveyorState.java @@ -15,6 +15,7 @@ import com.bingce.controlapphelper.surveyor.state.StateType; import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParam; +import com.bingce.controlapphelper.util.DebugMsgUtil; import com.bingce.controlapphelper.util.SettingValueUtil; import com.bingce.controlapphelper.util.Tools; import com.bingce.controlnetwork.R; @@ -123,6 +124,8 @@ class _DoSurveyorState extends __BaseState implements ISurveyorListener, ISurvey onCompleted(RESULT_FAILURE_EXCEED_MAX, Tools.getString(R.string.many_measure_failed_1)); } else { //再次尝试 + DebugMsgUtil.canWrite("仪器返回错误信息:" + errorMsg); + DebugMsgUtil.canWrite("开始再次测量"); sendSurveyRequest(); ToastUtils.showShort(Tools.getString(R.string.receive_data_time_out)); } diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/AngleDistanceCheckAdjust.kt b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/AngleDistanceCheckAdjust.kt new file mode 100644 index 0000000..2315ed8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/AngleDistanceCheckAdjust.kt @@ -0,0 +1,320 @@ +package com.bingce.controlnetwork.surveyor.util.checkadjust + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord +import com.bingce.controlapphelper.model.LeftOrRight +import com.bingce.controlapphelper.surveyor.data.ICachedData +import com.bingce.controlapphelper.surveyor.data.IMeasureCache +import com.bingce.controlapphelper.surveyor.method.AverageValueMethod +import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod +import com.bingce.controlapphelper.surveyor.method.RadianMethod +import com.bingce.controlapphelper.surveyor.method.ValueOf2cMethod +import com.bingce.controlapphelper.surveyor.method.model.SdAngleValueType +import com.bingce.controlapphelper.util.IdUtil +import com.bingce.controlapphelper.util.SurveyorCycleUtil +import com.bingce.utils.Util +import kotlin.math.abs + +/** + * 常规三角导线测站检测 + * 检测所有测回数据 + *

+ * 在「无自动闭合」情况下,为了兼容「左右角」测量结果,根据pointId将所有测量数据存入map中 + * 根据「左角」测量来检测「测回间同方向值互差」,所有测回的归零值使用「左角」第一个point来做0点 + *

+ * 如果是「自动闭合」情况,则忽略「左右角」测量,直接按照itemIndex依次计算,第个测回的归零值, + * 使用每次循环的itemIndex=0做0点 + * + * @param toleranceRecord 限差 + * @param cachedDataSource 缓存的测量数据 + * @return 错误信息,如果为null或空,说明没有错误 + */ +class AngleDistanceCheckAdjust : IStationCheck { + override fun check( + stationId: String, + toleranceRecord: ToleranceDetailRecord, + measureCache: IMeasureCache + ): String? { + val cacheData = measureCache as ICachedData + + val cycleCount = toleranceRecord.getCycleCount() + val surveyorCount = toleranceRecord.surveyorCount + + //*****测回间同方向值互差(水平角) + val horCyclesDirectValueDifference = + toleranceRecord.getHorCyclesDirectValueDifference() /*horCyclesDirectValueDifference*/ + val horValueError: MutableList<_ErrorItem> = ArrayList() + + //*****测回间垂直角互差(垂直角) + val verCyclesAngleDifference = + toleranceRecord.getVerCyclesAngleDifference() /*verCyclesAngleDifference*/ + val verValueError: MutableList<_ErrorItem> = ArrayList() + + + //执行计算 + for (cycleI in 0 until cycleCount) { + val valuesI = + DeviationValueOfRadianMethod.zeroValueOfSingleCycleInLeftOrientation( + stationId, + cycleI, + surveyorCount, + cacheData + ) + for (cycleJ in cycleI + 1 until cycleCount) { + val valuesJ = + DeviationValueOfRadianMethod.zeroValueOfSingleCycleInLeftOrientation( + stationId, + cycleJ, + surveyorCount, + cacheData + ) + if (valuesI.size != valuesJ.size) { + return "请完成所有重测后再检测测站数据!" + } + val size = valuesI.size + for (index in 0 until size) { + var diff = abs( + DeviationValueOfRadianMethod + .similarRadianDiff( + valuesI[index].horRadian, + valuesJ[index].horRadian + ) + ) + if (horCyclesDirectValueDifference < RadianMethod.radian2S(diff)) { + horValueError.add( + _ErrorItem( + valuesI[index].pointName, + cycleI, cycleJ, RadianMethod.radian2S(diff) + ) + ) + } + + diff = abs( + DeviationValueOfRadianMethod + .similarRadianDiff(valuesI[index].verRadian, valuesJ[index].verRadian) + ) + if (verCyclesAngleDifference < RadianMethod.radian2S(diff)) { + verValueError.add( + _ErrorItem( + valuesI[index].pointName, + cycleI, cycleJ, RadianMethod.radian2S(diff) + ) + ) + } + } + } + } + + //*****测回间垂直角I互差(垂直角) + val verCyclesIDifference = + toleranceRecord.getVerCyclesIDifference() /*verCyclesIDifference*/ + val verIError: MutableList<_ErrorItem> = ArrayList() + + //*****测回间斜距互差(距离) + val distCyclesDifference = + toleranceRecord.getSlopeCycleDistanceDifference() /*slopeCycleDistanceDifference*/ + val distError: MutableList<_ErrorItem> = ArrayList() + + val pointArrayList: MutableList<_Point> = ArrayList() + + //遍历第一测回,收集所有待测点id + for (index in 0 until cacheData.pointCount()) { + if (cacheData.isPointAbandon(0, index)) { + continue + } + pointArrayList.add( + _Point( + cacheData.pointId(0, index), + cacheData.pointName(0, index), + cacheData.isAloneDistance(0, index) + ) + ) + } + + //检测所有待测点i互差 + for (point in pointArrayList) { + for (cycleI in 0 until cycleCount) { + val leftRecordId_I = IdUtil.createSurveyorRecordId( + stationId, + cycleI, + point.pointId, + LeftOrRight.left + ) + val rightRecordId_I = IdUtil.createSurveyorRecordId( + stationId, + cycleI, + point.pointId, + LeftOrRight.right + ) + val value2C_I = ValueOf2cMethod.valueOf2C( + SdAngleValueType.verAngle, leftRecordId_I, rightRecordId_I, + toleranceRecord.surveyorCount, cacheData + ) + val distanceLeftAndRightAverageValue_I = AverageValueMethod.leftAndRightValue( + SdAngleValueType.distance, + leftRecordId_I, + rightRecordId_I, surveyorCount, cacheData + ) + for (cycleJ in cycleI + 1 until cycleCount) { + val leftRecordId_J = IdUtil.createSurveyorRecordId( + stationId, + cycleJ, + point.pointId, + LeftOrRight.left + ) + val rightRecordId_J = IdUtil.createSurveyorRecordId( + stationId, + cycleJ, + point.pointId, + LeftOrRight.right + ) + val value2C_J = ValueOf2cMethod.valueOf2C( + SdAngleValueType.verAngle, leftRecordId_J, rightRecordId_J, + toleranceRecord.surveyorCount, cacheData + ) + val distanceLeftAndRightAverageValue_J = AverageValueMethod.leftAndRightValue( + SdAngleValueType.distance, + leftRecordId_J, + rightRecordId_J, surveyorCount, cacheData + ) + val verI = abs(value2C_I.value - value2C_J.value) + if (verCyclesIDifference < verI) { + verIError.add( + _ErrorItem( + point.pointName, + cycleI, + cycleJ, + verI + ) + ) + } + + if (!point.aloneDistance) { + val distance = + abs(distanceLeftAndRightAverageValue_I.value - distanceLeftAndRightAverageValue_J.value) + if (distCyclesDifference < distance * 1000) { + distError.add( + _ErrorItem( + point.pointName, + cycleI, + cycleJ, + distance * 1000 + ) + ) + } + } + } + } + } + + return _errorString( + horCyclesDirectValueDifference, + verCyclesAngleDifference, + verCyclesIDifference, + distCyclesDifference, + horValueError, + verValueError, + verIError, + distError + ) + + } + + /** + * 根据超限信息生成错误描述 + * + * @param horValueError 水平角同方向值互差 + * @param verValueError 垂直角同方向值互差 + */ + private fun _errorString( + horLimit: Double, + verLimit: Double, + verILimit: Double, + distLimit: Double, + horValueError: List<_ErrorItem>, + verValueError: List<_ErrorItem>, + verIError: List<_ErrorItem>, + distError: List<_ErrorItem> + ): String? { + if (horValueError.isEmpty() && verValueError.isEmpty()) { + return null + } + val stringBuilder = StringBuilder() + if (horValueError.isNotEmpty()) { + stringBuilder.append("测回间同方向值互差超限(限差:") + .append(Util.formatDouble2String(horLimit, 1)) + .append("'')") + for (item in horValueError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')") + } + } + + if (verValueError.isNotEmpty()) { + stringBuilder.append("\n测回间垂直角互差超限(限差:") + .append(Util.formatDouble2String(verLimit, 1)) + .append("'')") + for (item in verValueError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')") + } + } + + if (verIError.isNotEmpty()) { + stringBuilder.append("\n垂直角i指标同方向各测回较差超限(限差:") + .append(Util.formatDouble2String(verILimit, 1)) + .append("'')") + for (item in verIError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')") + } + } + + if (distError.isNotEmpty()) { + stringBuilder.append("\n测回间距离较差超限(限差:") + .append(Util.formatDouble2String(distLimit, 1)) + .append("'')") + for (item in distError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')") + } + } + + return stringBuilder.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/CheckAdjustBean.kt b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/CheckAdjustBean.kt new file mode 100644 index 0000000..0fb3424 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/CheckAdjustBean.kt @@ -0,0 +1,17 @@ +package com.bingce.controlnetwork.surveyor.util.checkadjust + +/** + * 存储错误信息的item + */ +class _ErrorItem( + val pointName: String, + val cycleIndex1: Int, + val cycleIndex2: Int, + val difference: Double +) + +class _Point( + val pointId: String, + val pointName: String, + val aloneDistance: Boolean +) \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/IStationCheck.kt b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/IStationCheck.kt new file mode 100644 index 0000000..3651bbb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/IStationCheck.kt @@ -0,0 +1,12 @@ +package com.bingce.controlnetwork.surveyor.util.checkadjust + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord +import com.bingce.controlapphelper.surveyor.data.IMeasureCache + +interface IStationCheck { + fun check( + stationId: String, + toleranceRecord: ToleranceDetailRecord, + measureCache: IMeasureCache + ): String? +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/SwipeDraggableRecyclerViewUtil.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/SwipeDraggableRecyclerViewUtil.java index 8d8f7c0..2a8f8b4 100644 --- a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/SwipeDraggableRecyclerViewUtil.java +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/SwipeDraggableRecyclerViewUtil.java @@ -9,7 +9,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; -import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; public class SwipeDraggableRecyclerViewUtil { public static void setup(AbstractDraggableRecycleViewAdapter adapter, @@ -27,12 +26,12 @@ public class SwipeDraggableRecyclerViewUtil { new TipsWith2OptionFragment.IOperatorCallback() { @Override public void onConfirm() { - if (operatorListener != null) { - operatorListener.onItemRemoved(adapterPosition); - } if (adapter != null) { adapter.onItemRemoved(adapterPosition); } + if (operatorListener != null) { + operatorListener.onItemRemoved(adapterPosition); + } } @Override diff --git a/app/src/main/java/com/bingce/controlnetwork/util/DatabaseFixUtils.java b/app/src/main/java/com/bingce/controlnetwork/util/DatabaseFixUtils.java deleted file mode 100644 index 5dc7d38..0000000 --- a/app/src/main/java/com/bingce/controlnetwork/util/DatabaseFixUtils.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.bingce.controlnetwork.util; - -import com.bingce.controlapphelper.datasource.database.SurveyorDataBase; -import com.bingce.controlapphelper.datasource.database.ToleranceTemplate; -import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; -import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; -import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; -import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; -import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupConstants; -import com.bingce.utils.ThreadPoolUtil; - -import java.util.List; - -public class DatabaseFixUtils { - //解决某个版本的bug: - //由于升级数据库,导致限差方案丢失,所以启动的时候检测所有project,为没有限差的项目重新添加限差 - public static void changeDefaultTolerance() { - ThreadPoolUtil.execute(() -> { - List projectRecordList = SurveyorDataBase.getInstance() - .projectDao().getAllSync(); - if (projectRecordList != null) { - //查询默认限限差 - ConfigRecord defaultToleranceId = SurveyorDataBase.getInstance().configDao().getByKeySync(ConfigConstants.KEY_DEFAULT_TOLERANCE_DETAIL); - ToleranceDetailRecord defaultTolerance = null; - if (defaultToleranceId == null) { - List detailRecords = - ToleranceTemplate.detailListOfGroup(ToleranceGroupConstants.VALUE_MUL_CYCLE_ANGLE); - if (detailRecords.isEmpty()) { - return; - } - defaultTolerance = detailRecords.get(0); - } else { - defaultTolerance = SurveyorDataBase.getInstance().toleranceDetailDao() - .getByIdSync(defaultToleranceId.configValue); - } - if (defaultTolerance == null) { - return; - } - for (ProjectRecord projectRecord : projectRecordList) { - String toleranceId = projectRecord.toleranceId; - ToleranceDetailRecord toleranceDetailRecord = SurveyorDataBase.getInstance().toleranceDetailDao() - .getByIdSync(toleranceId); - if (toleranceDetailRecord == null) { - projectRecord.toleranceId = defaultTolerance.id; - SurveyorDataBase.getInstance().projectDao() - .save(projectRecord); - //项目的限差id不为空了,但是数据库的限差可能还是没有? - } - } - } - }); - } -} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/DialogUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/DialogUtil.java new file mode 100644 index 0000000..ffc393c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/DialogUtil.java @@ -0,0 +1,128 @@ +package com.bingce.controlnetwork.util; + +import android.content.Context; + +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; + + +public class DialogUtil { + public static void showDataLoseHintDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, IConfirmBack callBack) { + showConfirmDialog(fragmentManager, lifecycleOwner, + Tools.getString(R.string.tips_station_data_will_lose), + Tools.getString(R.string.exit), callBack); + } + + public static void showConfirmDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + String hint, + String confirmText, + IConfirmBack callBack) { + TipsWith2OptionFragment + .tips( + fragmentManager, + lifecycleOwner, + confirmText, + Tools.getString(R.string.cancel), + hint, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + if (callBack != null) { + callBack.onConfirm(); + } + } + } + ); + } + + public static void showConfirmCancleDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + String hint, + String confirmText, + String cancelText, + IConfirmCancelBack callBack) { + TipsWith2OptionFragment + .tips( + fragmentManager, + lifecycleOwner, + confirmText, + cancelText, + hint, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + if (callBack != null) { + callBack.onConfirm(); + } + } + + @Override + public void onCancel() { + if (callBack != null) { + callBack.onCancel(); + } + } + } + ); + } + + public static void showAlertDialog(Context context, FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + String hint) { + TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, hint); + } + + public static void showConfirmCountDownDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + String hint, + String confirmText, + IConfirmBack callBack) { + TipsWith2OptionFragment + .tipsCountDownTime( + fragmentManager, + lifecycleOwner, + confirmText, + Tools.getString(R.string.cancel), + null, + hint, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + callBack.onConfirm(); + } + } + ); + } + + public static void showHighToNoHighConfirmDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + IConfirmBack callBack) { + TipsWith2OptionFragment + .tips( + fragmentManager, + lifecycleOwner, + Tools.getString(R.string.confirm), + Tools.getString(R.string.cancel), + "当前已有测量数据,切换后高精度气象数据将丢失", + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + callBack.onConfirm(); + } + } + ); + } + + + public interface IConfirmBack { + void onConfirm(); + } + + public interface IConfirmCancelBack { + void onConfirm(); + + void onCancel(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/KeyboardUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/KeyboardUtil.java new file mode 100644 index 0000000..5c39306 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/KeyboardUtil.java @@ -0,0 +1,19 @@ +package com.bingce.controlnetwork.util; + +import android.app.Activity; +import android.view.inputmethod.InputMethodManager; + +import blankj.utilcode.util.ActivityUtils; + +public class KeyboardUtil { + public static void hideSoftInput() { + hideSoftInput(ActivityUtils.getTopActivity()); + } + + public static void hideSoftInput(Activity act) { + if (act != null && act.getCurrentFocus() != null) { + InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE); + inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/SelectDeviceTypeUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/SelectDeviceTypeUtil.java new file mode 100644 index 0000000..32cec2e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/SelectDeviceTypeUtil.java @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.util; + +import android.content.Intent; +import android.view.View; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.AppChannel; +import com.bingce.controlnetwork.R; +import com.bingce.device.ui.ConnectLevelActivity; +import com.bingce.device.ui.ConnectTSActivity; + +import blankj.utilcode.util.ActivityUtils; + +public class SelectDeviceTypeUtil { + public static void showDeviceTypeDialog() { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.choose_instrument_type) + .items(new String[]{ActivityUtils.getTopActivity().getString(R.string.total_station), ActivityUtils.getTopActivity().getString(R.string.device_type_level)}) + .itemsCallback(new MaterialDialog.ListCallback() { + @Override + public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) { + switch (which) { + case 0: + Intent intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); + intent.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent); + break; + case 1: + Intent intent2 = new Intent(ActivityUtils.getTopActivity(), ConnectLevelActivity.class); + intent2.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent2); + break; + } + } + }).show(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/StationSettingCheckUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/StationSettingCheckUtil.java new file mode 100644 index 0000000..6c7fb22 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/StationSettingCheckUtil.java @@ -0,0 +1,213 @@ +package com.bingce.controlnetwork.util; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory; +import com.bingce.controlapphelper.datasource.database.leveling.idetection.isetting.LevelIDetectionSetting; +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord; +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.ui.fragment.TipsWith2OptionFragment; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlnetwork.func.level.activity.LevelStationSettingActivity; +import com.bingce.controlnetwork.newui.stationsetting.StationSettingsActivity; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionStationSettingActivity; + + +public class StationSettingCheckUtil { + //请设置温度、成像、太阳方向等相关信息(App只对以上信息进行留存,不会依此对数据进行校正). + private static final String HINT = "开始测量前请先进行测站设置"; + private static final String HINT_LEVEL = "开始测量前请先进行测段设置"; + public static final String HINT_LEVEL_END = "测段结束前请先进行测段设置"; + + private boolean isCheckSuccess; + + /** + * 检测测站是否设置了棱镜相关属性,如果没有则跳转到设置界面 + */ + public void checkStationSettings(String stationId, + @NonNull Fragment fragment, + @NonNull IUIRunner runner, ICheckSuccess checkSuccess) { + if (isCheckSuccess) { + checkSuccess.onSuccess(); + return; + } + + ThreadPoolUtil.execute(() -> { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + //检测温度、湿度、气压、棱镜是否设置 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + if (stationRecord == null) { + ToastUtils.showShort("stationRecord == null"); + return; + } + List stationItemList = stationRecord.getItems(); + if (stationItemList == null || stationItemList.isEmpty()) { + ToastUtils.showShort("stationItemList == null || stationItemList.isEmpty()"); + return; + } + boolean failure = false; + for (SurveyorPoint stationItem : stationItemList) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + continue; + } + if (stationItem.isWellSteel()) { + continue; + } + if (isEmpty(stationItem.getPrismHeight())) { + failure = true; + break; + } + } + if (!failure && (isEmpty(stationRecord.getTemperature()) || + isEmpty(stationRecord.getHumidity()) || + isEmpty(stationRecord.getAirPressure()) || + isEmpty(stationRecord.getInstrumentHeight()))) { + failure = true; + } + + if (failure) { + runner.runOnUI(() -> TipsWith2OptionFragment.hardTips( + fragment.getChildFragmentManager(), + fragment.getViewLifecycleOwner(), + HINT, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { +// StationSettingsFragment.start(fragment.getContext(), stationId); + StationSettingsActivity.start(fragment.requireContext(), stationId); + } + + @Override + public void onCancel() { +// if (fragment.getActivity() != null) { +// fragment.getActivity().finish(); +// } + } + })); + return; + } + + isCheckSuccess = true; + checkSuccess.onSuccess(); + + }); + + + } + + public static boolean isEmpty(String string) { + return string == null || string.isEmpty(); + } + + public interface ICheckSuccess { + void onSuccess(); + } + + /** + * 水准测站检测 + */ + public void checkStationSettingsLevel(String stationId, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + Context context, + IUIRunner runner, ICheckSuccess checkSuccessListener) { + if (isCheckSuccess) { + checkSuccessListener.onSuccess(); + return; + } + ThreadPoolUtil.execute(() -> { + LevelingStationRecord stationRecord = LevelingDbFactory.instance.getStationDataSource().getRecordSync(stationId); + if (stationRecord == null) { + ToastUtils.showShort("stationRecord == null"); + return; + } + LevelingStationSettingRecord stationSettingLatest = LevelingDbFactory.instance.getStationSettingDataSource().getLatest(stationRecord.routeId); + + if (stationSettingLatest == null || stationSettingLatest.weather == null) { + //需要设置环境设置 + runner.runOnUI(() -> showLevelSetStationSetting(fragmentManager, + lifecycleOwner, context, + HINT_LEVEL, + stationRecord.routeId, stationId, false) + ); + return; + } + + isCheckSuccess = true; + checkSuccessListener.onSuccess(); + }); + + } + + /** + * i角检测的测站设置 + */ + public void checkStationSettingsIDetection(String iDetectionId, + @NonNull AppCompatActivity activity, + @NonNull IUIRunner runner, ICheckSuccess checkSuccessListener) { + if (isCheckSuccess) { + checkSuccessListener.onSuccess(); + return; + } + ThreadPoolUtil.execute(() -> { + LevelIDetectionSetting setting = LevelingDbFactory.instance.getIDetectionSettingDataSource().getByIDetectionId(iDetectionId); + if (setting == null) { + //需要设置环境设置 + runner.runOnUI(() -> TipsWith2OptionFragment.hardTips( + activity.getSupportFragmentManager(), + activity, + HINT, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + LevelIDetectionStationSettingActivity.launch(activity, iDetectionId); + } + }) + ); + return; + } + isCheckSuccess = true; + checkSuccessListener.onSuccess(); + }); + + } + + /** + * 提示需要进行测站设置 + */ + public static void showLevelSetStationSetting(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Context context, + String hint, + String routeId, + String stationId, + boolean isSaveEndStation) { + TipsWith2OptionFragment.hardTips( + fragmentManager, + lifecycleOwner, + hint, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + LevelStationSettingActivity.start(context, routeId, stationId, isSaveEndStation); + } + }); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/SurveyorOpenAtrUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/SurveyorOpenAtrUtil.java new file mode 100644 index 0000000..0f4ddd9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/SurveyorOpenAtrUtil.java @@ -0,0 +1,27 @@ +package com.bingce.controlnetwork.util; + +import com.bingce.controlapphelper.datasource.database.prism.PrismConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; + +/** + * 测量转换工具类 + */ +public class SurveyorOpenAtrUtil { + + public static boolean isOpenAtr(SurveyorPoint surveyorPoint) { + return isOpenAtr(surveyorPoint.getPrismType(), surveyorPoint.getPrismTypeLarge()) && !surveyorPoint.isOpenAtrNot(); + } + + public static boolean isOpenAtr(int prismType, String prismTypeLarge) { + switch (prismType) { + case PrismConstants.TYPE_PRISM_ROUND: + case PrismConstants.TYPE_PRISM_MINI: + return true; + case PrismConstants.TYPE_USER: + return PrismConstants.TYPE_PRISM_LARGE.equals(prismTypeLarge); + default: + return false; + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigsSetConfigs.java b/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigsSetConfigs.java index 0f9eda2..7d1693c 100644 --- a/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigsSetConfigs.java +++ b/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigsSetConfigs.java @@ -3,9 +3,6 @@ package com.bingce.controlnetwork.util.config; import android.content.Context; import android.content.Intent; -import androidx.fragment.app.FragmentManager; -import androidx.lifecycle.LifecycleOwner; - import com.bingce.AppChannel; import com.bingce.controlnetwork.R; import com.bingce.controlnetwork.fragment.ConfigFragment; @@ -14,9 +11,7 @@ import com.bingce.controlnetwork.fragment.PrismManageFragment; import com.bingce.controlnetwork.fragment.SelectExportHeightTraverseFragment; import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordFragment; import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordWireFileFragment; -import com.bingce.controlnetwork.fragment.SelectMeasureDataExportTypeFragment; import com.bingce.controlnetwork.fragment.ToleranceManageFragment; -import com.bingce.data.database.deformationmonitor.util.GsonUtils; import com.bingce.device.ui.ConnectTSActivity; import com.wedcel.dragexpandgrid.model.DragIconInfo; @@ -35,7 +30,7 @@ public class ConfigsSetConfigs extends AbstractSetConfigs { @Override protected void init(Map list) { list.put(FUC_INSTRUMENTMANAGEMENT, - new ConfigItem(FUC_INSTRUMENTMANAGEMENT, R.string.total_station_online, R.drawable.icon_ts_connecting, DragIconInfo.CATEGORY_ONLY)); + new ConfigItem(FUC_INSTRUMENTMANAGEMENT, R.string.instrument_management, R.drawable.icon_ts_connecting, DragIconInfo.CATEGORY_ONLY)); list.put(FUC_GLOBAL_CONTROL_POINT, new ConfigItem(FUC_GLOBAL_CONTROL_POINT, R.string.global_control_point, R.drawable.icon_parameter_points, DragIconInfo.CATEGORY_ONLY)); list.put(FUC_EXPORT_STATION, @@ -76,7 +71,7 @@ public class ConfigsSetConfigs extends AbstractSetConfigs { PointListFragment.go2GlobalPointList(context); break; case FUC_EXPORT_STATION://观测数据导出 - startExportMeasureData(context, fragment.getChildFragmentManager(), fragment.getViewLifecycleOwner()); + SelectExportSurveyorRecordFragment.start(context); break; case FUC_EXPORT_WIRE_FILE://导线文件导出 SelectExportSurveyorRecordWireFileFragment.start(context); @@ -92,19 +87,4 @@ public class ConfigsSetConfigs extends AbstractSetConfigs { break; } } - - /** - * 测院导出观测前先选择导出文件类型 - * - * @param context - * @param fragmentManager - * @param lifecycleOwner - */ - private void startExportMeasureData(Context context, FragmentManager fragmentManager, - LifecycleOwner lifecycleOwner) { - SelectMeasureDataExportTypeFragment.start(fragmentManager, lifecycleOwner, beanList -> { - String json = GsonUtils.toJson(beanList); - SelectExportSurveyorRecordFragment.start(context); - }); - } } \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/util/tolerance/LevelToleranceOperate.kt b/app/src/main/java/com/bingce/controlnetwork/util/tolerance/LevelToleranceOperate.kt new file mode 100644 index 0000000..9115a0c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/tolerance/LevelToleranceOperate.kt @@ -0,0 +1,40 @@ +package com.bingce.controlnetwork.util.tolerance + +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.tolerance.LevelingToleranceDetail +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil +import com.bingce.utils.IOnSingleGetCallback + +class LevelToleranceOperate : IToleranceOperate { + override fun getIToleranceDetail(id: String): IToleranceDetail? { + return LevelingDbFactory.instance + .getToleranceDetailDataSource().getRecordSync(id) + } + + override fun saveToleranceDetail(bean: IToleranceDetail?) { + bean?.let { + LevelingDbFactory.instance + .getToleranceDetailDataSource().saveWithCallback(it as LevelingToleranceDetail) { + + } + } + } + + override fun getGroup(itoleranceDetail: IToleranceDetail): ToleranceGroupRecord? { + return ToleranceLoadUtil.getLevelToleranceLoad().groupOf(itoleranceDetail.groupId) + } + + override fun getLevel(itoleranceDetail: IToleranceDetail): ToleranceLevelRecord? { + return ToleranceLoadUtil.getLevelToleranceLoad().levelOf(itoleranceDetail.levelId) + } + + override fun getDefaultRecord(callback: IOnSingleGetCallback) { + LevelingDbFactory.instance + .getToleranceDetailDataSource().getDefaultRecord(callback) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/util/tolerance/ToleranceOperateUtil.kt b/app/src/main/java/com/bingce/controlnetwork/util/tolerance/ToleranceOperateUtil.kt new file mode 100644 index 0000000..5154567 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/tolerance/ToleranceOperateUtil.kt @@ -0,0 +1,19 @@ +package com.bingce.controlnetwork.util.tolerance + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate +import com.bingce.controlapphelper.datasource.database.tolerance.load.BingceToleranceOperate + +object ToleranceOperateUtil { + + @JvmStatic + fun getOperate(toleranceId: String?): IToleranceOperate? { + return toleranceId?.let { + when { + toleranceId.contains(ProjectTypeValue.LEVEL) -> LevelToleranceOperate() + else -> BingceToleranceOperate() + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/viewmodel/MainActivityViewModel.kt b/app/src/main/java/com/bingce/controlnetwork/viewmodel/MainActivityViewModel.kt new file mode 100644 index 0000000..e3c5faf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/viewmodel/MainActivityViewModel.kt @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.bingce.controlnetwork.bean.MainUserBean + +class MainActivityViewModel : ViewModel() { + + val refreshLoginUserLiveData = MutableLiveData() + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/BaseEditSpinnerAdapter.java b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/BaseEditSpinnerAdapter.java new file mode 100644 index 0000000..6b7d8c4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/BaseEditSpinnerAdapter.java @@ -0,0 +1,27 @@ +package com.bingce.controlnetwork.widget.editspinner; + +import android.widget.BaseAdapter; + +/** + * BaseEditSpinnerAdapter + * + * @author WrBug + * @since 2017/2/25 + */ +public abstract class BaseEditSpinnerAdapter extends BaseAdapter { + /** + * editText输入监听 + * + * @return + */ + public abstract EditSpinnerFilter getEditSpinnerFilter(); + + /** + * 获取需要填入editText的字符串 + * + * @param position + * @return + */ + public abstract String getItemString(int position); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinner.java b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinner.java new file mode 100644 index 0000000..d9207e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinner.java @@ -0,0 +1,256 @@ +package com.bingce.controlnetwork.widget.editspinner; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.animation.Animation; +import android.view.animation.RotateAnimation; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.ListPopupWindow; +import android.widget.PopupWindow; +import android.widget.RelativeLayout; + +import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; + +import com.bingce.controlnetwork.R; + +import java.util.List; + + +/** + * Created by WrBug on 2017/2/26 0026. + */ +public class EditSpinner extends RelativeLayout implements View.OnClickListener, AdapterView.OnItemClickListener, TextWatcher { + private EditText editText; + private ImageView mRightIv; + private View mRightImageTopView; + private final Context mContext; + private ListPopupWindow popupWindow; + BaseEditSpinnerAdapter adapter; + private long popupWindowHideTime; + private Animation mAnimation; + private Animation mResetAnimation; + private AdapterView.OnItemClickListener mOnItemClickListener; + private int maxLine = 1; + + public EditSpinner(Context context, AttributeSet attrs) { + super(context, attrs); + this.mContext = context; + initView(attrs); + initAnimation(); + } + + + public void setItemData(List data) { + adapter = new SimpleAdapter(mContext, data); + setAdapter(adapter); + } + + public void setOnItemClickListener(AdapterView.OnItemClickListener listener) { + this.mOnItemClickListener = listener; + } + + public void setText(String text) { + editText.setText(text); + } + + public void setTextColor(@ColorInt int color) { + editText.setTextColor(color); + } + + public String getText() { + return editText.getText().toString(); + } + + public void setHint(String hint) { + editText.setHint(hint); + } + + public void setRightImageDrawable(Drawable drawable) { + mRightIv.setImageDrawable(drawable); + } + + public void setRightImageResource(@DrawableRes int res) { + mRightIv.setImageResource(res); + } + + public void setAdapter(BaseEditSpinnerAdapter adapter) { + this.adapter = adapter; + setBaseAdapter(this.adapter); + } + + public void setMaxLine(int maxLine) { + this.maxLine = maxLine; + editText.setMaxLines(this.maxLine); + } + + private void initAnimation() { + mAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + mAnimation.setDuration(300); + mAnimation.setFillAfter(true); + mResetAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + mResetAnimation.setDuration(300); + mResetAnimation.setFillAfter(true); + } + + private void initView(AttributeSet attrs) { + LayoutInflater.from(mContext).inflate(R.layout.edit_spinner, this); + editText = (EditText) findViewById(R.id.edit_sipnner_edit); + mRightIv = (ImageView) findViewById(R.id.edit_spinner_expand); + mRightImageTopView = findViewById(R.id.edit_spinner_expand_above); + mRightImageTopView.setOnClickListener(this); + mRightImageTopView.setClickable(false); + mRightIv.setOnClickListener(this); +// mRightIv.setRotation(90); + editText.addTextChangedListener(this); + TypedArray tArray = mContext.obtainStyledAttributes(attrs, + R.styleable.EditSpinner); + editText.setHint(tArray.getString(R.styleable.EditSpinner_hint)); + int imageId = tArray.getResourceId(R.styleable.EditSpinner_rightImage, 0); + if (imageId != 0) { + mRightIv.setImageResource(imageId); + } + int bg = tArray.getResourceId(R.styleable.EditSpinner_Background, 0); + if (bg != 0) { + editText.setBackgroundResource(bg); + } + maxLine = tArray.getInt(R.styleable.EditSpinner_maxLine, 1); + editText.setMaxLines(maxLine); + tArray.recycle(); + } + + private final void setBaseAdapter(BaseAdapter adapter) { + if (popupWindow == null) { + initPopupWindow(); + } + popupWindow.setAdapter(adapter); + } + + private void initPopupWindow() { + popupWindow = new ListPopupWindow(mContext) { + + @Override + public void show() { + super.show(); + mRightImageTopView.setClickable(true); + mRightIv.startAnimation(mAnimation); + } + + @Override + public void dismiss() { + super.dismiss(); + } + + }; + popupWindow.setOnItemClickListener(this); + popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + popupWindow.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW); + popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); + popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); + popupWindow.setAnchorView(editText); + popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { + @Override + public void onDismiss() { + popupWindowHideTime = System.currentTimeMillis(); + mRightIv.startAnimation(mResetAnimation); + } + }); + } + + + @Override + public final void onClick(View v) { + togglePopupWindow(); + } + + private void togglePopupWindow() { + if (System.currentTimeMillis() - popupWindowHideTime > 200) { + if (adapter == null || popupWindow == null) { + return; + } + showFilterData(""); + } + } + + @Override + public final void onItemClick(AdapterView parent, View view, int position, long id) { + editText.setText(((BaseEditSpinnerAdapter) parent.getAdapter()).getItemString(position)); + mRightImageTopView.setClickable(false); + if (popupWindow != null) { + popupWindow.dismiss(); + } + if (mOnItemClickListener != null) { + mOnItemClickListener.onItemClick(parent, view, position, id); + } + } + + @Override + public final void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public final void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public final void afterTextChanged(Editable s) { + String key = s.toString(); + editText.setSelection(key.length()); +// if (!TextUtils.isEmpty(key)) { +// showFilterData(key); +// } else { +// if (popupWindow != null) { +// popupWindow.dismiss(); +// } +// } + if (popupWindow != null) { + popupWindow.dismiss(); + } + } + + private void showFilterData(String key) { + if (popupWindow == null || adapter == null || adapter.getEditSpinnerFilter() == null) { + if (popupWindow != null) { + popupWindow.dismiss(); + } + return; + } + if (adapter.getEditSpinnerFilter().onFilter(key)) { + if (popupWindow != null) { + popupWindow.dismiss(); + } + } else { + if (popupWindow != null) { + popupWindow.show(); + } + } + } + + public void setEtGravity(int gravity) { + if (editText != null) { + editText.setGravity(gravity); + } + } + + public void setCanEdit(boolean enable) { + if (editText != null) { + editText.setEnabled(enable); + mRightIv.setEnabled(enable); + } + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinnerFilter.java b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinnerFilter.java new file mode 100644 index 0000000..1692228 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinnerFilter.java @@ -0,0 +1,17 @@ +package com.bingce.controlnetwork.widget.editspinner; + +/** + * EditSpinnerFilter + * + * @author WrBug + * @since 2017/2/25 + */ +public interface EditSpinnerFilter { + /** + * editText输入监听 + * + * @param keyword + * @return + */ + boolean onFilter(String keyword); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/SimpleAdapter.java b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/SimpleAdapter.java new file mode 100644 index 0000000..faa9154 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/SimpleAdapter.java @@ -0,0 +1,98 @@ +package com.bingce.controlnetwork.widget.editspinner; + +import android.content.Context; +import android.text.Html; +import android.text.TextUtils; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.bingce.utils.ScreenUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * SimpleAdapter + * + * @author WrBug + * @since 2017/2/25 + */ +public class SimpleAdapter extends BaseEditSpinnerAdapter implements EditSpinnerFilter { + private final Context mContext; + private final List mSpinnerData; + private final List mCacheData; + private final int[] indexs; + + public SimpleAdapter(Context context, List spinnerData) { + this.mContext = context; + this.mSpinnerData = spinnerData; + mCacheData = new ArrayList<>(spinnerData); + indexs = new int[mSpinnerData.size()]; + } + + @Override + public EditSpinnerFilter getEditSpinnerFilter() { + return this; + } + + @Override + public String getItemString(int position) { + return mSpinnerData.get(indexs[position]); + } + + @Override + public int getCount() { + return mCacheData == null ? 0 : mCacheData.size(); + } + + @Override + public String getItem(int position) { + return mCacheData == null ? "" : mCacheData.get(position) == null ? "" : mCacheData.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView textView = null; + if (convertView == null) { + textView = (TextView) LayoutInflater.from(mContext).inflate(android.R.layout.simple_spinner_item, null); + ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ScreenUtil.dp2px(parent.getContext(), 48f)); + textView.setLayoutParams(layoutParams); + textView.setGravity(Gravity.CENTER_VERTICAL); + } else { + textView = (TextView) convertView; + } + + textView.setText(Html.fromHtml(getItem(position))); + return textView; + } + + @Override + public boolean onFilter(String keyword) { + mCacheData.clear(); + if (TextUtils.isEmpty(keyword)) { + mCacheData.addAll(mSpinnerData); + for (int i = 0; i < indexs.length; i++) { + indexs[i] = i; + } + } else { + StringBuilder builder = new StringBuilder(); + builder.append("[^\\s]*").append(keyword).append("[^\\s]*"); + for (int i = 0; i < mSpinnerData.size(); i++) { + if (mSpinnerData.get(i).replaceAll("\\s+", "|").matches(builder.toString())) { + indexs[mCacheData.size()] = i; + mCacheData.add(mSpinnerData.get(i).replaceFirst(keyword, "" + keyword + "")); + } + } + } + notifyDataSetChanged(); + return mCacheData.size() <= 0; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java index a25cbca..545dc39 100644 --- a/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java +++ b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java @@ -4,8 +4,8 @@ import android.app.Activity; import android.content.Intent; import android.os.Bundle; +import com.bingce.controlnetwork.R; import com.bingce.event.WxRespCodeEvent; -import com.bingce.event.WxRespFailedEvent; import com.tencent.mm.opensdk.constants.ConstantsAPI; import com.tencent.mm.opensdk.modelbase.BaseReq; import com.tencent.mm.opensdk.modelbase.BaseResp; @@ -20,8 +20,6 @@ import blankj.utilcode.util.ToastUtils; import cn.leancloud.LCObject; import cn.leancloud.LCUser; -import com.bingce.controlnetwork.R; - public class WXEntryActivity extends Activity implements IWXAPIEventHandler { // IWXAPI 是第三方app和微信通信的openapi接口 private IWXAPI api; @@ -57,22 +55,22 @@ public class WXEntryActivity extends Activity implements IWXAPIEventHandler { EventBus.getDefault().post(new WxRespCodeEvent(code)); break; case BaseResp.ErrCode.ERR_USER_CANCEL: - EventBus.getDefault().post(new WxRespFailedEvent("User cancel")); + ToastUtils.showShort("User cancel"); break; case BaseResp.ErrCode.ERR_AUTH_DENIED: - EventBus.getDefault().post(new WxRespFailedEvent("Auth denied")); + ToastUtils.showShort("Auth denied"); break; case BaseResp.ErrCode.ERR_COMM: - EventBus.getDefault().post(new WxRespFailedEvent("Error Comm")); + ToastUtils.showShort("Error Comm"); break; case BaseResp.ErrCode.ERR_SENT_FAILED: - EventBus.getDefault().post(new WxRespFailedEvent("Send failed")); + ToastUtils.showShort("Send failed"); break; case BaseResp.ErrCode.ERR_UNSUPPORT: - EventBus.getDefault().post(new WxRespFailedEvent("Error unsupported")); + ToastUtils.showShort("Error unsupported"); break; case BaseResp.ErrCode.ERR_BAN: - EventBus.getDefault().post(new WxRespFailedEvent("Error ban")); + ToastUtils.showShort("Error ban"); break; } } else if (resp.getType() == ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX) { diff --git a/app/src/main/res/anim/dialog_enter_bottom.xml b/app/src/main/res/anim/dialog_enter_bottom.xml new file mode 100644 index 0000000..8f95a9c --- /dev/null +++ b/app/src/main/res/anim/dialog_enter_bottom.xml @@ -0,0 +1,6 @@ + + diff --git a/app/src/main/res/anim/dialog_exit_bottom.xml b/app/src/main/res/anim/dialog_exit_bottom.xml new file mode 100644 index 0000000..ad6db02 --- /dev/null +++ b/app/src/main/res/anim/dialog_exit_bottom.xml @@ -0,0 +1,6 @@ + + diff --git a/app/src/main/res/drawable/bg_circle_gary_chatui.xml b/app/src/main/res/drawable/bg_circle_gary_chatui.xml new file mode 100644 index 0000000..b7f43ad --- /dev/null +++ b/app/src/main/res/drawable/bg_circle_gary_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/corners_edit_chatui.xml b/app/src/main/res/drawable/corners_edit_chatui.xml new file mode 100644 index 0000000..12f1494 --- /dev/null +++ b/app/src/main/res/drawable/corners_edit_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/edit_spinner_text_color.xml b/app/src/main/res/drawable/edit_spinner_text_color.xml new file mode 100644 index 0000000..f1b8303 --- /dev/null +++ b/app/src/main/res/drawable/edit_spinner_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/icon_avatar.xml b/app/src/main/res/drawable/icon_avatar.xml new file mode 100644 index 0000000..0684437 --- /dev/null +++ b/app/src/main/res/drawable/icon_avatar.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/line_horizontal.xml b/app/src/main/res/drawable/line_horizontal.xml new file mode 100644 index 0000000..429565c --- /dev/null +++ b/app/src/main/res/drawable/line_horizontal.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_btn_bg_colormay_3.xml b/app/src/main/res/drawable/round_btn_bg_colormay_3.xml new file mode 100644 index 0000000..2d31948 --- /dev/null +++ b/app/src/main/res/drawable/round_btn_bg_colormay_3.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_btn_bg_gray_3.xml b/app/src/main/res/drawable/round_btn_bg_gray_3.xml new file mode 100644 index 0000000..4c90a6f --- /dev/null +++ b/app/src/main/res/drawable/round_btn_bg_gray_3.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_white_10.xml b/app/src/main/res/drawable/round_white_10.xml new file mode 100644 index 0000000..261d165 --- /dev/null +++ b/app/src/main/res/drawable/round_white_10.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_white_16.xml b/app/src/main/res/drawable/round_white_16.xml new file mode 100644 index 0000000..0229f6a --- /dev/null +++ b/app/src/main/res/drawable/round_white_16.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_base_binding.xml b/app/src/main/res/layout/activity_base_binding.xml new file mode 100644 index 0000000..dce2a21 --- /dev/null +++ b/app/src/main/res/layout/activity_base_binding.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_level_i_detection_list.xml b/app/src/main/res/layout/activity_level_i_detection_list.xml new file mode 100644 index 0000000..15c9c4a --- /dev/null +++ b/app/src/main/res/layout/activity_level_i_detection_list.xml @@ -0,0 +1,34 @@ + + + + + + + +