commit e97cc4a406c83123780b29554d99c9df9064af92 Author: huangwei <983142558@qq.com> Date: Wed Aug 28 17:38:49 2024 +0800 军测第一个版本 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d293cf1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +#git submodule update --init --recursive +*.hprof +build/ +.vscode/ +.gradle +/local.properties +/.idea +.DS_Store +/captures +/build +/app/build +/app/release +/app/mapping.txt +/app/src/main/libs +/app/src/main/obj +/controlapp/mapping.txt +/controlapp/release +/alpha/build +/alpha/release +/alpha/mapping.txt +/alpha/src/main/schemas/zone.a.dimap.db.RecordsDataBase/1.json +*.iml +.idea +*.jks +obj/ +.cxx/ +*.class +#定制版本 +/app/*/release +/alpha/*/release +/pad/*/release diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a8b9b8d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "control_common"] + path = control_common + url = http://code.bingce.com/BingCe-Android/control_common.git diff --git a/README.md b/README.md new file mode 100644 index 0000000..d592795 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +解放军信息工程导线助手 diff --git a/aar/base/base-release.aar b/aar/base/base-release.aar new file mode 100644 index 0000000..2458b09 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/aar/level/build.gradle b/aar/level/build.gradle new file mode 100644 index 0000000..f3b34f6 --- /dev/null +++ b/aar/level/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('level-release.aar')) \ No newline at end of file diff --git a/aar/level/level-release.aar b/aar/level/level-release.aar new file mode 100644 index 0000000..ab2382e Binary files /dev/null and b/aar/level/level-release.aar differ diff --git a/aar/rtk/build.gradle b/aar/rtk/build.gradle new file mode 100644 index 0000000..8c3ec85 --- /dev/null +++ b/aar/rtk/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('rtk-release.aar')) \ No newline at end of file diff --git a/aar/rtk/rtk-release.aar b/aar/rtk/rtk-release.aar new file mode 100644 index 0000000..0b8a62f Binary files /dev/null and b/aar/rtk/rtk-release.aar differ diff --git a/aar/totalstation/build.gradle b/aar/totalstation/build.gradle new file mode 100644 index 0000000..72f86f4 --- /dev/null +++ b/aar/totalstation/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('totalstation-release.aar')) \ No newline at end of file diff --git a/aar/totalstation/totalstation-release.aar b/aar/totalstation/totalstation-release.aar new file mode 100644 index 0000000..3af5d1f Binary files /dev/null and b/aar/totalstation/totalstation-release.aar differ diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..3f08270 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1,2 @@ +/build +*/release \ 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 new file mode 100644 index 0000000..d59238e --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,151 @@ +import com.bingce.AndroidSdk +import com.bingce.App +import com.bingce.Libs +import com.bingce.ModuleName + +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 { + useLibrary Libs.httpLegacy + compileSdk AndroidSdk.compileSdkVersion + namespace App.ControlNetwork.applicationId + + defaultConfig { + versionName "1.0.1" + versionCode 1 + applicationId "com.bingce.controlnetwork.pla" + minSdkVersion AndroidSdk.minSdkVersion + targetSdkVersion AndroidSdk.targetSdkVersion + ndk {} + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + multiDexEnabled true + + javaCompileOptions { + annotationProcessorOptions { + arguments = [ + //数据库room + "room.schemaLocation": "$projectDir/src/main/schemas".toString() + ] + } + } + } + + buildFeatures { + viewBinding true + buildConfig true + } + + signingConfigs { + debug { + storeFile file('./debug.keystore') + } + } + + buildTypes { + debug { + signingConfig signingConfigs.debug + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + release { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + 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', 'x86'//, 'x86_64', 'mips','armeabi', + } + } + + //为了解决部分第三方库重复打包了META-INF的问题 + packagingOptions { + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/LICENSE' + 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' + } +} + +dependencies { + 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.9.10") { + because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib") + } + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10") { + because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib") + } + } + +// 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' + + 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/debug.keystore b/app/debug.keystore new file mode 100644 index 0000000..5bb84af Binary files /dev/null and b/app/debug.keystore differ diff --git a/app/doc/Untitled-old.mdj b/app/doc/Untitled-old.mdj new file mode 100644 index 0000000..c83fd9d --- /dev/null +++ b/app/doc/Untitled-old.mdj @@ -0,0 +1,44 @@ +{ + "_type": "Project", + "_id": "AAAAAAFF+h6SjaM2Hec=", + "name": "Untitled", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFF+qBWK6M3Z8Y=", + "_parent": { + "$ref": "AAAAAAFF+h6SjaM2Hec=" + }, + "name": "Model", + "ownedElements": [ + { + "_type": "UMLStateMachine", + "_id": "AAAAAAF5RXOA7okfG2A=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "StateMachine1", + "ownedElements": [ + { + "_type": "UMLStatechartDiagram", + "_id": "AAAAAAF5RXOA7okhiTg=", + "_parent": { + "$ref": "AAAAAAF5RXOA7okfG2A=" + }, + "name": "StatechartDiagram1" + } + ], + "regions": [ + { + "_type": "UMLRegion", + "_id": "AAAAAAF5RXOA7okgaKU=", + "_parent": { + "$ref": "AAAAAAF5RXOA7okfG2A=" + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/app/doc/states.mdj b/app/doc/states.mdj new file mode 100644 index 0000000..fa3a069 --- /dev/null +++ b/app/doc/states.mdj @@ -0,0 +1,36869 @@ +{ + "_type": "Project", + "_id": "AAAAAAFElm5XMFNoGY0=", + "name": "Untitled", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFElm6BOFNpegQ=", + "_parent": { + "$ref": "AAAAAAFElm5XMFNoGY0=" + }, + "name": "Model", + "ownedElements": [ + { + "_type": "UMLUseCaseDiagram", + "_id": "AAAAAAF5P5m6Qk1jVXQ=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseDiagram1", + "ownedViews": [ + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5nMr01oLTI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5nMr01pxLs=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01qZlQ=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 224, + "top": 352, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01rWkA=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "font": "Arial;13;1", + "left": 132, + "top": 187.5, + "width": 62, + "height": 13, + "text": "check2C" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01srVY=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 224, + "top": 352, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01tKAI=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 224, + "top": 352, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 127, + "top": 180.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5nMr01qZlQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5nMr01rWkA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5nMr01srVY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5nMr01tKAI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5nMr01u10s=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5nMr01vn/8=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5nMr01wvTc=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5nMr01xNvU=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5nMr01yEgM=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 112, + "top": 176, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5nMr01u10s=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5nMr01vn/8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5nMr01wvTc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5nMr01xNvU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5nMr01yEgM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5rmBE2YaOM=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5rmBE2Z1VU=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5rmBE2awCc=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -112, + "top": -368, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5rmBE2bxgA=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "font": "Arial;13;1", + "left": 367, + "top": 83.5, + "width": 75, + "height": 13, + "text": "recordClean" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5rmBU2c6aQ=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -112, + "top": -368, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5rmBU2dJfU=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -112, + "top": -368, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 362, + "top": 76.5, + "width": 85.86083984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5rmBE2awCc=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5rmBE2bxgA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5rmBU2c6aQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5rmBU2dJfU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5rmBU2e6A8=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5rmBU2f+Vc=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5rmBU2gXnU=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5rmBU2hbLU=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5rmBU2iePg=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 344, + "top": 72, + "width": 121, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5rmBU2e6A8=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5rmBU2f+Vc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5rmBU2gXnU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5rmBU2hbLU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5rmBU2iePg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P5saWE3J2FY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3K1ts=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "font": "Arial;13;0", + "left": 248, + "top": 121, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3LIi0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 271, + "top": 107, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3M7xA=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 288, + "top": 148, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3NmNI=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 221, + "top": 144, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3Oy1k=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 218, + "top": 131, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3PZiY=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 228, + "top": 171, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3QKR0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 332, + "top": 97, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3RVpc=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 324, + "top": 86, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3S3i0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 347, + "top": 121, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5saWE3TepE=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5saWE3U3g4=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "tail": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "lineStyle": 1, + "points": "204:175;362:107", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P5saWE3K1ts=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5saWE3LIi0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5saWE3M7xA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P5saWE3NmNI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P5saWE3Oy1k=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P5saWE3PZiY=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P5saWE3QKR0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P5saWE3RVpc=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P5saWE3S3i0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P5saWE3TepE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P5saWE3U3g4=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P56LZE6M/G8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P56LZE6NeNY=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6OE2I=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6PKW0=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 205, + "top": 283.5, + "width": 103, + "height": 13, + "text": "【用户选择操作】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6QSXM=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6RMmU=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 200, + "top": 276.5, + "width": 114, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P56LZE6OE2I=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P56LZE6PKW0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P56LZE6QSXM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P56LZE6RMmU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P56LZE6SLIg=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P56LZE6TWFg=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P56LZE6U8ts=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P56LZE6VNIk=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P56LZE6W1sE=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 176, + "top": 272, + "width": 161, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P56LZE6SLIg=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P56LZE6TWFg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P56LZE6U8ts=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P56LZE6VNIk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P56LZE6W1sE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P56tgE7IY7E=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7JO9U=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "font": "Arial;13;0", + "left": 183, + "top": 224, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7Kkjk=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 230, + "top": 214, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7LlPE=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 198, + "top": 245, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7MSF4=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 213, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7NsLs=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 219, + "top": 205, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7OBww=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 186, + "top": 229, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7PoMY=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 230, + "top": 235, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7Q0NM=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 238, + "top": 225, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7RtW8=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 213, + "top": 258, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P56tgE7SCeE=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P56tgE7TSmw=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "tail": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "lineStyle": 1, + "points": "180:211;238:271", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P56tgE7JO9U=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P56tgE7Kkjk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P56tgE7LlPE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P56tgE7MSF4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P56tgE7NsLs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P56tgE7OBww=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P56tgE7PoMY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P56tgE7Q0NM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P56tgE7RtW8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P56tgE7SCeE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P56tgE7TSmw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5/CAk98zZc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5/CAk99r9g=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA09+uJY=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 64, + "top": -64, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA09/h4M=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "font": "Arial;13;1", + "left": 764, + "top": 467.5, + "width": 62, + "height": 13, + "text": "Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA0+AvMQ=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 64, + "top": -64, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA0+BODA=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 64, + "top": -64, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 759, + "top": 460.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5/CA09+uJY=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5/CA09/h4M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5/CA0+AvMQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5/CA0+BODA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5/CA0+CFD4=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5/CA0+DO7Q=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5/CA0+EZ7w=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5/CA0+FMSM=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5/CA0+GOcA=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 744, + "top": 456, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5/CA0+CFD4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5/CA0+DO7Q=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5/CA0+EZ7w=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5/CA0+FMSM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5/CA0+GOcA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P5/ask/ENuY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/FCi8=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "font": "Arial;13;0", + "left": 300, + "top": 372, + "width": 124.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1, + "text": "+选择忽略or重测目标" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/GmBY=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 373, + "top": 362, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/H9Os=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 341, + "top": 393, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/ITgo=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 301, + "top": 309, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/J3dw=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 312, + "top": 301, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/KH+Q=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 279, + "top": 325, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/LwxI=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 424, + "top": 435, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/MCSM=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 425, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/N7rw=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 407, + "top": 458, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5/ask/OUQY=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5/ask/P3tM=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "lineStyle": 1, + "points": "273:307;432:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P5/ask/FCi8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5/ask/GmBY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5/ask/H9Os=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P5/ask/ITgo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P5/ask/J3dw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P5/ask/KH+Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P5/ask/LwxI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P5/ask/MCSM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P5/ask/N7rw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P5/ask/OUQY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P5/ask/P3tM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P6Btl1DS04s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P6Btl1DTuQ4=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P6Btl1DUbE8=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDVnHI=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 74.5, + "top": 411.5, + "width": 207, + "height": 13, + "text": "【提示用户是否确定删除整个测回】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDW1Rc=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDXJZ4=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 69.5, + "top": 404.5, + "width": 218, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6Btl1DUbE8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P6BtmFDVnHI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P6BtmFDW1Rc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6BtmFDXJZ4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P6BtmFDYzoo=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P6BtmFDZfOA=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P6BtmFDabNE=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P6BtmFDbcVg=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P6BtmFDcrag=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 400, + "width": 308, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P6BtmFDYzoo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P6BtmFDZfOA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P6BtmFDabNE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P6BtmFDbcVg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P6BtmFDcrag=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6ETu1Fw08c=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFx1mw=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "font": "Arial;13;0", + "left": 199, + "top": 354, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1, + "text": "+重测测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFyw0s=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 241, + "top": 362, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFzyRs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 203, + "top": 339, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF0+lY=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 244, + "top": 330, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF1ok8=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 254, + "top": 339, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF2wKI=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 222, + "top": 312, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF3tbw=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 214, + "top": 378, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF4Oc0=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 226, + "top": 383, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF586k=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 188, + "top": 368, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6ETvFF6xek=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6ETvFF7szs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "tail": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "lineStyle": 1, + "points": "245:307;188:399", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6ETvFFx1mw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6ETvFFyw0s=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6ETvFFzyRs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6ETvFF0+lY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6ETvFF1ok8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6ETvFF2wKI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6ETvFF3tbw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6ETvFF4Oc0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6ETvFF586k=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6ETvFF6xek=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6ETvFF7szs=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6HZl1JC23Y=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JDZsQ=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "font": "Arial;13;0", + "left": 267, + "top": 432, + "width": 98.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1, + "text": "+选择忽略or取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JECIw=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 320, + "top": 417, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JF8pk=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 309, + "top": 461, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JG0HA=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 273, + "top": 421, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JHztQ=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 279, + "top": 408, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JIPD0=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 262, + "top": 446, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JJLUs=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 359, + "top": 443, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JKFgU=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 360, + "top": 430, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JLM+Y=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 356, + "top": 471, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6HZl1JMru0=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6HZl1JNqZA=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "lineStyle": 1, + "points": "245:435;381:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6HZl1JDZsQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6HZl1JECIw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6HZl1JF8pk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6HZl1JG0HA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6HZl1JHztQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6HZl1JIPD0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6HZl1JJLUs=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6HZl1JKFgU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6HZl1JLM+Y=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6HZl1JMru0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6HZl1JNqZA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P6IYDFMMeFQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P6IYDFMNnzQ=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDFMOOjk=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMPgvc=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 125, + "top": 531.5, + "width": 103, + "height": 13, + "text": "【执行删除操作】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMQezU=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMRBdM=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 120, + "top": 524.5, + "width": 114, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6IYDFMOOjk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P6IYDVMPgvc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P6IYDVMQezU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6IYDVMRBdM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P6IYDVMSZQE=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P6IYDVMTe6E=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P6IYDVMUviY=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P6IYDVMVT7Q=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P6IYDVMWeEE=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 96, + "top": 520, + "width": 161, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P6IYDVMSZQE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P6IYDVMTe6E=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P6IYDVMUviY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P6IYDVMVT7Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P6IYDVMWeEE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6Jc6FQAXTQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQBsAA=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "font": "Arial;13;0", + "left": 161, + "top": 470, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1, + "text": "+确认删除" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQCliU=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 205, + "top": 470, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQDs0Y=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 161, + "top": 471, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQErUI=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 455, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQFXc4=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 457, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQGACw=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 450, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQH5rw=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 487, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQIDDY=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 485, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQJXs0=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 163, + "top": 491, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6Jc6VQKiwE=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6Jc6VQLymI=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "tail": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "lineStyle": 1, + "points": "177:435;176:519", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6Jc6FQBsAA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6Jc6FQCliU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6Jc6FQDs0Y=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6Jc6VQErUI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6Jc6VQFXc4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6Jc6VQGACw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6Jc6VQH5rw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6Jc6VQIDDY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6Jc6VQJXs0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6Jc6VQKiwE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6Jc6VQLymI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6KuWFYy590=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFYzBrY=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 409, + "top": 536, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY07+U=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 410, + "top": 521, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY1T2M=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 406, + "top": 565, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY2uTU=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 284, + "top": 525, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY3Q0s=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 287, + "top": 512, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY4NMQ=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 277, + "top": 552, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY5sZg=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 534, + "top": 547, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY62Oo=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 533, + "top": 534, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY78L8=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 536, + "top": 575, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6KuWFY8wFs=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6KuWVY9b40=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": -144, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "lineStyle": 1, + "points": "257:544;559:571", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6KuWFYzBrY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6KuWFY07+U=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6KuWFY1T2M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6KuWFY2uTU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6KuWFY3Q0s=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6KuWFY4NMQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6KuWFY5sZg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6KuWFY62Oo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6KuWFY78L8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6KuWFY8wFs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6KuWVY9b40=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJWvCwgzk0M=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJWvCwg0EPw=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg1NpM=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 2032, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg2wKE=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "font": "Arial;13;1", + "left": 1144, + "top": 1419.5, + "width": 119, + "height": 13, + "text": "move2NextValidate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg3lvo=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 2032, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg4tCw=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 2032, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1139, + "top": 1412.5, + "width": 129, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJWvCwg1NpM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJWvCwg2wKE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJWvCwg3lvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJWvCwg4tCw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJWvCwg5PfY=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJWvDAg6ClE=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJWvDAg7Ros=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJWvDAg8tC0=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJWvDAg9Vl8=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1112, + "top": 1408, + "width": 183, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJWvCwg5PfY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJWvDAg6ClE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJWvDAg7Ros=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJWvDAg8tC0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJWvDAg9Vl8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJc4CA2oNI0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJc4CA2p+Dw=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJc4CA2qdmU=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1808, + "top": -848, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJc4CA2r3po=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "font": "Arial;13;1", + "left": 1081, + "top": 339.5, + "width": 124, + "height": 13, + "text": "checkHalfCycleZero" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJc4CA2s9SY=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1808, + "top": -848, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJc4CA2tVXo=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1808, + "top": -848, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1076, + "top": 332.5, + "width": 134.28076171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJc4CA2qdmU=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJc4CA2r3po=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJc4CA2s9SY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJc4CA2tVXo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJc4CA2uA/U=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJc4CQ2vtIA=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJc4CQ2wvoY=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJc4CQ2xB7c=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJc4CQ2yPQg=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1048, + "top": 328, + "width": 190, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJc4CA2uA/U=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJc4CQ2vtIA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJc4CQ2wvoY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJc4CQ2xB7c=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJc4CQ2yPQg=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJeXAw9Y7Yc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJeXAw9Z7G0=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJeXAw9azp8=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1936, + "top": -752, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJeXAw9b8aE=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "font": "Arial;13;1", + "left": 1469, + "top": 219.5, + "width": 105, + "height": 13, + "text": "isReady2CCheck" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJeXAw9cphk=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1936, + "top": -752, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJeXAw9dhRA=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1936, + "top": -752, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1464, + "top": 212.5, + "width": 115.498046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJeXAw9azp8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJeXAw9b8aE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJeXAw9cphk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJeXAw9dhRA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJeXAw9eiUw=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJeXAw9fQSo=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJeXAw9gktM=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJeXAw9hx78=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJeXAw9iEQ8=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1440, + "top": 208, + "width": 163, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJeXAw9eiUw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJeXAw9fQSo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJeXAw9gktM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJeXAw9hx78=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJeXAw9iEQ8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJesYRAYGmw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAZQUY=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "font": "Arial;13;0", + "left": 1232, + "top": 264, + "width": 189.2279815673828, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1, + "text": "+测站不闭合or半测回归零差正常" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAa+X8=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1321, + "top": 250, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAb41g=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1335, + "top": 293, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAcFHE=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1219, + "top": 298, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAdnH8=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1217, + "top": 285, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAeLA0=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1223, + "top": 326, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAfocQ=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1434, + "top": 230, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAgNDY=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1428, + "top": 218, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAh4Q4=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1447, + "top": 255, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJesYhAiBdg=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJesYhAjzjQ=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": -144, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "tail": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "lineStyle": 1, + "points": "1199:327;1464:243", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJesYRAZQUY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJesYRAa+X8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJesYRAb41g=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJesYhAcFHE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJesYhAdnH8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJesYhAeLA0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJesYhAfocQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJesYhAgNDY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJesYhAh4Q4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJesYhAiBdg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJesYhAjzjQ=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJjLZRML/gk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJjLZRMMO54=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMN0eQ=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 32, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMOGnw=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 380, + "top": 483.5, + "width": 139, + "height": 13, + "text": "switchState2StandStill" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMPJsQ=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 32, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMQZsw=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 32, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 375, + "top": 476.5, + "width": 149.419921875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJjLZRMN0eQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJjLZRMOGnw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJjLZRMPJsQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJjLZRMQZsw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJjLZRMRZxg=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJjLZRMSuGM=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJjLZRMTa74=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJjLZRMUk04=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJjLZRMVcTY=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 344, + "top": 472, + "width": 211, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJjLZRMRZxg=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJjLZRMSuGM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJjLZRMTa74=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJjLZRMUk04=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJjLZRMVcTY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJk5ohVYjKI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJk5ohVZ7LA=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVaBvo=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 528, + "top": -368, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVbtSw=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 669, + "top": 387.5, + "width": 142, + "height": 13, + "text": "提示半测回归零检测失败" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVc1ns=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 528, + "top": -368, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVdnqY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 528, + "top": -368, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 664, + "top": 380.5, + "width": 153, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJk5ohVaBvo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJk5ohVbtSw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJk5ohVc1ns=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJk5ohVdnqY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJk5ohVeC3M=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJk5ohVfd1M=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJk5ohVg6Qc=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJk5ohVh4ZY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJk5ohViitY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 632, + "top": 376, + "width": 216, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJk5ohVeC3M=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJk5ohVfd1M=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJk5ohVg6Qc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJk5ohVh4ZY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJk5ohViitY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJmQwBdwdmk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwBdxb3k=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "font": "Arial;13;0", + "left": 906, + "top": 376, + "width": 85.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1, + "text": "+没有通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRdyFDg=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 950, + "top": 391, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRdzOi4=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 945, + "top": 347, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd0cxc=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1023, + "top": 368, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd1+jk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1022, + "top": 381, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd2je8=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1024, + "top": 340, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd3aOM=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 385, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd4cEI=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 879, + "top": 398, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd5h7I=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 867, + "top": 358, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJmQwRd6XO0=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJmQwRd7bPQ=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "tail": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "lineStyle": 1, + "points": "1047:356;848:380", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJmQwBdxb3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJmQwRdyFDg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJmQwRdzOi4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJmQwRd0cxc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJmQwRd1+jk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJmQwRd2je8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJmQwRd3aOM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJmQwRd4cEI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJmQwRd5h7I=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJmQwRd6XO0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJmQwRd7bPQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJnHsRkO52k=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkPXt4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 598, + "top": 449, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkQg5M=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 603, + "top": 463, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkRfd8=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 589, + "top": 420, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkS/7E=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 665, + "top": 427, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkTUvo=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 666, + "top": 440, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkU2kA=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 660, + "top": 399, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkVrbg=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 532, + "top": 471, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkWL5A=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 538, + "top": 483, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkXIlE=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 519, + "top": 446, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnHsRkYjF0=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnHsRkZRp4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "lineStyle": 1, + "points": "685:411;503:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJnHsRkPXt4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJnHsRkQg5M=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJnHsRkRfd8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJnHsRkS/7E=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJnHsRkTUvo=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJnHsRkU2kA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJnHsRkVrbg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJnHsRkWL5A=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJnHsRkXIlE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJnHsRkYjF0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJnHsRkZRp4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJnk3hnngQ0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnoFuM=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 648, + "top": 458, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnpzsU=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 647, + "top": 443, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnqowI=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 649, + "top": 487, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnr2A8=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 580, + "top": 461, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnsPz4=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 581, + "top": 448, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnt7X0=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 577, + "top": 489, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnuPbw=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 716, + "top": 455, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnvOwA=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 713, + "top": 442, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnwvuU=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 721, + "top": 482, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnk3hnxCbA=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnk3hny8xs=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "lineStyle": 1, + "points": "555:484;743:475", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJnk3hnoFuM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJnk3hnpzsU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJnk3hnqowI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJnk3hnr2A8=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJnk3hnsPz4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJnk3hnt7X0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJnk3hnuPbw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJnk3hnvOwA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJnk3hnwvuU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJnk3hnxCbA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJnk3hny8xs=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ6ahiPXyXI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ6ahiPYzM0=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahiPZdhA=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": -896, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahiPa2BQ=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "font": "Arial;13;1", + "left": 795.5, + "top": 123.5, + "width": 96, + "height": 13, + "text": "checkReadData" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahyPb1CY=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": -896, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahyPcSJM=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": -896, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 790.5, + "top": 116.5, + "width": 106.8271484375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ6ahiPZdhA=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ6ahiPa2BQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ6ahyPb1CY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ6ahyPcSJM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ6ahyPdwvQ=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ6ahyPeius=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ6ahyPfDuE=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ6ahyPgVJE=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ6ahyPhyOw=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 768, + "top": 112, + "width": 151, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ6ahyPdwvQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ6ahyPeius=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ6ahyPfDuE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ6ahyPgVJE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ6ahyPhyOw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ8m8Sf6ofY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ8m8Sf7JBU=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf8/hc=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": -1280, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf9x9A=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "font": "Arial;13;1", + "left": 1044, + "top": 107.5, + "width": 175, + "height": 13, + "text": "isHalfCycleZeroCheckReady" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf+ddw=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": -1280, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf/cbI=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": -1280, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1039, + "top": 100.5, + "width": 186.2998046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ8m8Sf8/hc=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ8m8Sf9x9A=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ8m8Sf+ddw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ8m8Sf/cbI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ8m8SgAs+Y=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ8m8SgBoKU=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ8m8SgCMgY=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ8m8SgDeic=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ8m8SgEIBM=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1000, + "top": 96, + "width": 263, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ8m8SgAs+Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ8m8SgBoKU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ8m8SgCMgY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ8m8SgDeic=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ8m8SgEIBM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ87PCkCJ2c=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkD2ew=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "font": "Arial;13;0", + "left": 903, + "top": 101, + "width": 111.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1, + "text": "+单测量or通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkEHYk=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 957, + "top": 86, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkFD0M=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 959, + "top": 130, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkGBOM=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 943, + "top": 102, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkHciQ=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 945, + "top": 89, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkI53k=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 941, + "top": 130, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkJ5DY=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 972, + "top": 100, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkKd2s=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 969, + "top": 87, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkLnCE=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 978, + "top": 127, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ87PCkMizE=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ87PCkNuH0=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "tail": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "lineStyle": 1, + "points": "919:125;999:120", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ87PCkD2ew=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ87PCkEHYk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ87PCkFD0M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ87PCkGBOM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ87PCkHciQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ87PCkI53k=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ87PCkJ5DY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ87PCkKd2s=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ87PCkLnCE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ87PCkMizE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ87PCkNuH0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ+mRitZ0H0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ+mRitad0o=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRitbxtk=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 544, + "top": -784, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytcRUc=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 591.5, + "top": 179.5, + "width": 77, + "height": 13, + "text": "提示读数有误" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytdKoM=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 544, + "top": -784, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytecXk=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 544, + "top": -784, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 586.5, + "top": 172.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ+mRitbxtk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ+mRytcRUc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ+mRytdKoM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ+mRytecXk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ+mRytf9wc=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ+mRytgl/8=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ+mRythGBg=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ+mRytiPDo=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ+mRytjdZM=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 568, + "top": 168, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ+mRytf9wc=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ+mRytgl/8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ+mRythGBg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ+mRytiPDo=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ+mRytjdZM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ/UgywlH50=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/Ugywm6Cw=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "font": "Arial;13;0", + "left": 700, + "top": 166, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UgywnNpM=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 740, + "top": 180, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UgywoaZM=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 729, + "top": 137, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwpjOU=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": 162, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwqyBI=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 754, + "top": 175, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwrLDA=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 749, + "top": 134, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCws+Vw=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 720, + "top": 170, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwtL5c=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 726, + "top": 182, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwuYNo=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 709, + "top": 145, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/UhCwvaPk=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/UhCwwUDY=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "tail": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "lineStyle": 1, + "points": "774:147;692:169", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ/Ugywm6Cw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ/UgywnNpM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ/UgywoaZM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ/UhCwpjOU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ/UhCwqyBI=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/UhCwrLDA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ/UhCws+Vw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ/UhCwtL5c=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/UhCwuYNo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/UhCwvaPk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/UhCwwUDY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ/0PC0CShY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0DtlQ=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 551, + "top": 338, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0ETCk=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 564, + "top": 346, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0FS9M=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 526, + "top": 323, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0G2RA=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 617, + "top": 226, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0HEgs=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 628, + "top": 235, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0IKu8=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 596, + "top": 209, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0JtjU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 486, + "top": 450, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0KkBY=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 498, + "top": 454, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0LEUU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 460, + "top": 440, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/0PS0MAmo=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/0PS0Nb0Y=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "lineStyle": 1, + "points": "618:203;460:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ/0PS0DtlQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ/0PS0ETCk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0FS9M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ/0PS0G2RA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0HEgs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/0PS0IKu8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ/0PS0JtjU=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0KkBY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/0PS0LEUU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/0PS0MAmo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/0PS0Nb0Y=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKE6Ojfzjv0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKE6Ojf0W9Y=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf12Ns=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1472, + "top": 352, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf2D5I=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "font": "Arial;13;1", + "left": 1342, + "top": 1123.5, + "width": 110, + "height": 13, + "text": "checkSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf3N+g=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1472, + "top": 352, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf4rrM=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1472, + "top": 352, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1337, + "top": 1116.5, + "width": 120.55712890625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKE6Ojf12Ns=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKE6Ojf2D5I=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKE6Ojf3N+g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKE6Ojf4rrM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKE6Ojf5X6A=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKE6Ojf6i5o=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKE6Ojf7hDo=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKE6Ojf8oq8=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKE6Ojf9edk=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1312, + "top": 1112, + "width": 170, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKE6Ojf5X6A=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKE6Ojf6i5o=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKE6Ojf7hDo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKE6Ojf8oq8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKE6Ojf9edk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKIG+T9Y4ko=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKIG+T9Zl2o=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9a7vU=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1408, + "top": 544, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9bDug=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "font": "Arial;13;1", + "left": 1386, + "top": 1299.5, + "width": 129, + "height": 13, + "text": "isAllCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9cIfM=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1408, + "top": 544, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9dArI=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1408, + "top": 544, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1381, + "top": 1292.5, + "width": 139.314453125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKIG+T9a7vU=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKIG+T9bDug=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKIG+T9cIfM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKIG+T9dArI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKIG+T9e1Wk=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKIG+T9fRvU=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKIG+T9gBhM=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKIG+T9hA48=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKIG+T9inVI=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1352, + "top": 1288, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKIG+T9e1Wk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKIG+T9fRvU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKIG+T9gBhM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKIG+T9hA48=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKIG+T9inVI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QKI4zEKHpSc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKIQ1c=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "font": "Arial;13;0", + "left": 1408, + "top": 1206, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKJdn8=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1451, + "top": 1202, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKKTG0=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1408, + "top": 1215, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKL0+I=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1423, + "top": 1161, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKMDrE=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1437, + "top": 1159, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKNoT0=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1396, + "top": 1165, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKOx2g=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1450, + "top": 1251, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKP85E=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1462, + "top": 1245, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKQLJU=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1425, + "top": 1263, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKI4zEKR1Nc=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKI4zEKSZgo=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "tail": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "lineStyle": 1, + "points": "1402:1147;1444:1287", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QKI4zEKIQ1c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKI4zEKJdn8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKI4zEKKTG0=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QKI4zEKL0+I=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QKI4zEKMDrE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QKI4zEKNoT0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QKI4zEKOx2g=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QKI4zEKP85E=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QKI4zEKQLJU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QKI4zEKR1Nc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QKI4zEKSZgo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKuCwkzY630=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKuCwkzZLtk=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzadw4=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1872, + "top": 48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzbRGU=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 1463.5, + "top": 963.5, + "width": 77, + "height": 13, + "text": "提示用户选择" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzc5kQ=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1872, + "top": 48, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzd3VI=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1872, + "top": 48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1458.5, + "top": 956.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKuCwkzadw4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKuCwkzbRGU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKuCwkzc5kQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKuCwkzd3VI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKuCw0zeMMo=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKuCw0zfhJM=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKuCw0zgO20=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKuCw0zhG3k=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKuCw0ziN7I=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1440, + "top": 952, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKuCw0zeMMo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKuCw0zfhJM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKuCw0zgO20=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKuCw0zhG3k=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKuCw0ziN7I=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QKvMIE8ZF/E=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8a1To=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "font": "Arial;13;0", + "left": 1399, + "top": 1034, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8bx7Y=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1422, + "top": 1026, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8c/MU=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1460, + "top": 1051, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8df1Y=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1409, + "top": 1075, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8e89E=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1399, + "top": 1065, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8frKE=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1430, + "top": 1093, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8gpg0=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1462, + "top": 994, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8hUUs=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1449, + "top": 989, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8iPfY=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1487, + "top": 1005, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKvMIU8jJRc=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKvMIU8kteI=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "lineStyle": 1, + "points": "1408:1111;1489:987", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QKvMIU8a1To=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKvMIU8bx7Y=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKvMIU8c/MU=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QKvMIU8df1Y=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QKvMIU8e89E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QKvMIU8frKE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QKvMIU8gpg0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QKvMIU8hUUs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QKvMIU8iPfY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QKvMIU8jJRc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QKvMIU8kteI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKyR6VB+5F0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKyR6VB/sq8=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCAlIw=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -272, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCBFDc=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 956, + "top": 731.5, + "width": 62, + "height": 13, + "text": "重测方向" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCC81I=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -272, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCDFwk=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -272, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 951, + "top": 724.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKyR6lCAlIw=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKyR6lCBFDc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKyR6lCC81I=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKyR6lCDFwk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKyR6lCEof0=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKyR6lCFl5A=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKyR6lCGLz0=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKyR6lCHKbg=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKyR6lCIqJE=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 936, + "top": 720, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKyR6lCEof0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKyR6lCFl5A=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKyR6lCGLz0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKyR6lCHKbg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKyR6lCIqJE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKysH1F4naw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKysH1F5Vw8=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F6t1U=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 672, + "top": -512, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F7w44=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 1172, + "top": 675.5, + "width": 62, + "height": 13, + "text": "重测测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F8ews=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 672, + "top": -512, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F9CVk=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 672, + "top": -512, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1167, + "top": 668.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKysH1F6t1U=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKysH1F7w44=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKysH1F8ews=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKysH1F9CVk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKysH1F+SbI=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKysH1F/p8w=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKysH1GAwRg=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKysH1GBWy4=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKysH1GC8OE=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1152, + "top": 664, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKysH1F+SbI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKysH1F/p8w=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKysH1GAwRg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKysH1GBWy4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKysH1GC8OE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKzDRVJysxE=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKzDRVJztrc=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ0nsk=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 752, + "top": -1088, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ1z+Q=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 1238.5, + "top": 443.5, + "width": 226, + "height": 13, + "text": "resetSurveyorStateAndKeepPosition" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ29Q0=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 752, + "top": -1088, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ3D90=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 752, + "top": -1088, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1233.5, + "top": 436.5, + "width": 237.5634765625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKzDRVJ0nsk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKzDRVJ1z+Q=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKzDRVJ29Q0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKzDRVJ3D90=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKzDRVJ4vK0=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKzDRVJ5ijM=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKzDRVJ6ScY=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKzDRVJ71p4=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKzDRVJ8l2g=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1184, + "top": 432, + "width": 335, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKzDRVJ4vK0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKzDRVJ5ijM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKzDRVJ6ScY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKzDRVJ71p4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKzDRVJ8l2g=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QK2QmFlvdS8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlwJfE=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "font": "Arial;13;0", + "left": 1395, + "top": 707, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1, + "text": "+忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlxSkY=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1397, + "top": 711, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFly6tM=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1440, + "top": 698, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlzr3g=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1474, + "top": 924, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl0RxM=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1460, + "top": 925, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl1X3o=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1501, + "top": 920, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl29pE=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1348, + "top": 490, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl39y0=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1336, + "top": 496, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl4Ns0=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1374, + "top": 478, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK2QmFl5muU=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK2QmFl6Y7A=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1496:951;1356:467", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QK2QmFlwJfE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QK2QmFlxSkY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QK2QmFly6tM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QK2QmFlzr3g=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QK2QmFl0RxM=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QK2QmFl1X3o=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QK2QmFl29pE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QK2QmFl39y0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QK2QmFl4Ns0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QK2QmFl5muU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QK2QmFl6Y7A=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QK340l0Fv9Q=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0GnqQ=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1014, + "top": 471, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Habc=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1015, + "top": 486, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0IZgE=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1013, + "top": 442, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Jr30=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1157, + "top": 466, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0KziQ=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1156, + "top": 479, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0LSAI=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1160, + "top": 438, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0MEF0=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 872, + "top": 478, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0NAX0=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 491, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Obj8=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 867, + "top": 451, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK340l0PZLk=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK340l0QvTM=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "lineStyle": 1, + "points": "1183:456;846:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QK340l0GnqQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QK340l0Habc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QK340l0IZgE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QK340l0Jr30=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QK340l0KziQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QK340l0LSAI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QK340l0MEF0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QK340l0NAX0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QK340l0Obj8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QK340l0PZLk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QK340l0QvTM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QLdiXGHqtMU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHrPm0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1236, + "top": 860, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHsNrs=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1230, + "top": 874, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHtajM=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1249, + "top": 833, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHu5Ak=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1431, + "top": 948, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHvESE=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1423, + "top": 959, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHwu2c=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1446, + "top": 924, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHxgP0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1043, + "top": 773, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHyZg0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1040, + "top": 786, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHzjfw=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1050, + "top": 746, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLdiXGH0aoo=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLdiXGH1FM8=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1461:951;1026:755", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QLdiXGHrPm0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLdiXGHsNrs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLdiXGHtajM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QLdiXGHu5Ak=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QLdiXGHvESE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QLdiXGHwu2c=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QLdiXGHxgP0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QLdiXGHyZg0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QLdiXGHzjfw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QLdiXGH0aoo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QLdiXGH1FM8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QLwOJ2bPDnI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QLwOJ2bQ8Ro=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bRPfA=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bSTVM=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "fillColor": "#5656ff", + "font": "Arial;13;1", + "left": 1090.5, + "top": 587.5, + "width": 93, + "height": 13, + "text": "resurveyPoints" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bTKUY=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bUBI4=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 1085.5, + "top": 580.5, + "width": 103.9326171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLwOJ2bRPfA=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QLwOJ2bSTVM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QLwOJ2bTKUY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLwOJ2bUBI4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QLwOJ2bVEa0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QLwOJ2bWae0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QLwOJ2bXEAg=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QLwOKGbYe7A=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QLwOKGbZQqo=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + } + ], + "fillColor": "#5656ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1064, + "top": 576, + "width": 146, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QLwOJ2bVEa0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QLwOJ2bWae0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QLwOJ2bXEAg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QLwOKGbYe7A=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QLwOKGbZQqo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QLx6RGoNnGE=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoOcBM=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1050, + "top": 648, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoPkXM=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1040, + "top": 637, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoQUT8=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1071, + "top": 669, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoRB9A=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1013, + "top": 684, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoSk+A=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1005, + "top": 673, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoT8Lo=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1029, + "top": 706, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoUHro=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1087, + "top": 612, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoVk68=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1077, + "top": 604, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoW9No=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1110, + "top": 629, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLx6RGoXj7U=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLx6RGoYmUk=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "tail": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "lineStyle": 1, + "points": "1005:719;1117:611", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QLx6RGoOcBM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLx6RGoPkXM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLx6RGoQUT8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QLx6RGoRB9A=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QLx6RGoSk+A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QLx6RGoT8Lo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QLx6RGoUHro=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QLx6RGoVk68=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QLx6RGoW9No=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QLx6RGoXj7U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QLx6RGoYmUk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QMaQUG/rlG8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QMaQUG/sv3A=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUG/tkJ4=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -448, + "top": -256, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUG/umGY=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 612.5, + "top": 579.5, + "width": 216, + "height": 13, + "text": "switchState2RestartInCurrentCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUW/vdlU=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -448, + "top": -256, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUW/w0wQ=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -448, + "top": -256, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 607.5, + "top": 572.5, + "width": 227.4580078125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMaQUG/tkJ4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QMaQUG/umGY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QMaQUW/vdlU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMaQUW/w0wQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QMaQUW/x48o=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QMaQUW/yJ84=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QMaQUW/z4XE=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QMaQUW/0u+w=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QMaQUW/13YU=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 560, + "top": 568, + "width": 321, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QMaQUW/x48o=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QMaQUW/yJ84=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QMaQUW/z4XE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QMaQUW/0u+w=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QMaQUW/13YU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMbzEXNQ00I=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNR/aw=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "font": "Arial;13;0", + "left": 942, + "top": 598, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1, + "text": "+开始重测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNSJUg=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 971, + "top": 613, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNTTKw=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 972, + "top": 569, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNUT2s=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1036, + "top": 600, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNVmq4=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1034, + "top": 613, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNWUrs=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1041, + "top": 573, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNX73U=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 906, + "top": 597, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNYoLo=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 908, + "top": 610, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNZwIQ=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 902, + "top": 569, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMbzEXNaGMo=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMbzEXNbVPI=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "lineStyle": 1, + "points": "1063:592;881:588", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMbzEXNR/aw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMbzEXNSJUg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMbzEXNTTKw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMbzEXNUT2s=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMbzEXNVmq4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMbzEXNWUrs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMbzEXNX73U=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMbzEXNYoLo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMbzEXNZwIQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMbzEXNaGMo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMbzEXNbVPI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMjEp4Xxm70=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4XyXqY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 973, + "top": 991, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4XzTSE=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 986, + "top": 984, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X0hBs=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 948, + "top": 1006, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X1sYc=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 755, + "top": 612, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X2bX4=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 768, + "top": 607, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X3ebc=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 729, + "top": 621, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X4oDY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1193, + "top": 1371, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X5UnY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1203, + "top": 1362, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X6pQM=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1171, + "top": 1388, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMjEqIX7oU8=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMjEqIX8oCk=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "tail": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "lineStyle": 1, + "points": "730:603;1193:1407", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMjEp4XyXqY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMjEp4XzTSE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMjEp4X0hBs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMjEp4X1sYc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMjEp4X2bX4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMjEp4X3ebc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMjEp4X4oDY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMjEp4X5UnY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMjEp4X6pQM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMjEqIX7oU8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMjEqIX8oCk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMnaf4p31wI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p4YhA=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1340, + "top": 829, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p5heM=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1330, + "top": 840, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p6u/E=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1361, + "top": 808, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p7HWo=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1452, + "top": 937, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p8uO8=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1442, + "top": 945, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p9ZYk=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1475, + "top": 920, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p+8dA=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1229, + "top": 721, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p/pOU=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1221, + "top": 732, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4qAet8=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1245, + "top": 699, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMnaf4qBmzo=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMnaf4qCCtY=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1482:951;1221:699", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMnaf4p4YhA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMnaf4p5heM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMnaf4p6u/E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMnaf4p7HWo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMnaf4p8uO8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMnaf4p9ZYk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMnaf4p+8dA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMnaf4p/pOU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMnaf4qAet8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMnaf4qBmzo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMnaf4qCCtY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QNAhapFuI7s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFvVXY=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "font": "Arial;13;0", + "left": 1312, + "top": 829, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1, + "text": "+取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFwVCE=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1336, + "top": 817, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFxPvQ=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1311, + "top": 854, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFyOWw=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1242, + "top": 705, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFz3Mw=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1254, + "top": 699, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapF0mvQ=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1217, + "top": 717, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F1FkI=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1460, + "top": 918, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F2OJ8=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1466, + "top": 905, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F3+WU=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1449, + "top": 943, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNAha5F4AZU=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": -56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNAha5F5UgE=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": -56, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1215:699;1320:848;1474:951", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QNAhapFvVXY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QNAhapFwVCE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QNAhapFxPvQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QNAhapFyOWw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QNAhapFz3Mw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QNAhapF0mvQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QNAha5F1FkI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QNAha5F2OJ8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QNAha5F3+WU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QNAha5F4AZU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QNAha5F5UgE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QNFL66Cbz6k=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CcWkE=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "font": "Arial;13;0", + "left": 1247, + "top": 550, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1, + "text": "+忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CdTo8=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1250, + "top": 542, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Ce+u8=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1288, + "top": 567, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CfR+U=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1215, + "top": 627, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Cg04o=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1205, + "top": 617, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66ChcXw=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1236, + "top": 645, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CipGA=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1312, + "top": 474, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Cj6oQ=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1299, + "top": 469, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Ck0os=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1337, + "top": 485, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNFL66ClLUo=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNFL66Cm8No=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1214:663;1339:467", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QNFL66CcWkE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QNFL66CdTo8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QNFL66Ce+u8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QNFL66CfR+U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QNFL66Cg04o=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QNFL66ChcXw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QNFL66CipGA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QNFL66Cj6oQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QNFL66Ck0os=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QNFL66ClLUo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QNFL66Cm8No=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVTun0vZBv0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vaxdo=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "font": "Arial;13;0", + "left": 1205, + "top": 502, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1, + "text": "+重测失败" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vbxuQ=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1226, + "top": 490, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vcmj8=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1251, + "top": 527, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vdoCc=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1176, + "top": 542, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0ved/I=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1170, + "top": 529, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vfAMs=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1187, + "top": 567, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vg9C0=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1294, + "top": 463, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTuoEvhMzo=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1284, + "top": 453, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTuoEviZLY=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1312, + "top": 483, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVTuoEvjqMY=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVTuoEvkZEE=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "lineStyle": 1, + "points": "1163:575;1324:467", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVTun0vaxdo=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVTun0vbxuQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVTun0vcmj8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVTun0vdoCc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVTun0ved/I=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVTun0vfAMs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVTun0vg9C0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVTuoEvhMzo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVTuoEviZLY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVTuoEvjqMY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVTuoEvkZEE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVWv21Zu6Aw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZvsKs=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1032, + "top": 1458, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZwRzk=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1034, + "top": 1473, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZxCSk=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1027, + "top": 1429, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21Zyej0=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1087, + "top": 1451, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZzuYg=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1086, + "top": 1464, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ0MPo=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1087, + "top": 1423, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ18no=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 977, + "top": 1467, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ21Iw=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 981, + "top": 1480, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ3nLg=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 969, + "top": 1440, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVWv3FZ4weo=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVWv3FZ58yM=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "tail": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "lineStyle": 1, + "points": "1111:1439;950:1462", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVWv21ZvsKs=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVWv21ZwRzk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVWv21ZxCSk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVWv21Zyej0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVWv21ZzuYg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVWv3FZ0MPo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVWv3FZ18no=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVWv3FZ21Iw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVWv3FZ3nLg=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVWv3FZ4weo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVWv3FZ58yM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RVbpp1nKVhc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RVbpp1nLusg=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnM530=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1680, + "top": -704, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnNEWc=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 1095.5, + "top": 819.5, + "width": 77, + "height": 13, + "text": "执行测回删除" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnO5/0=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1680, + "top": -704, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnPMMU=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1680, + "top": -704, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1090.5, + "top": 812.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVbpqFnM530=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RVbpqFnNEWc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RVbpqFnO5/0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVbpqFnPMMU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RVbpqFnQqa0=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RVbpqFnRVaY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RVbpqFnSiyY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RVbpqFnTp/o=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RVbpqFnUeVQ=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1072, + "top": 808, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RVbpqFnQqa0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RVbpqFnRVaY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RVbpqFnSiyY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RVbpqFnTp/o=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RVbpqFnUeVQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVcwNF0lj/I=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0m640=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1180, + "top": 753, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0n9pE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1194, + "top": 759, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0osMg=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1153, + "top": 740, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0pne0=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1195, + "top": 722, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0qTm8=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1206, + "top": 730, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0rLrQ=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1172, + "top": 707, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0s558=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1166, + "top": 783, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0tAew=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1179, + "top": 787, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0uE34=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1139, + "top": 776, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVcwNF0vsAE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVcwNF0w5ls=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1193:699;1142:807", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVcwNF0m640=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVcwNF0n9pE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVcwNF0osMg=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVcwNF0pne0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVcwNF0qTm8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVcwNF0rLrQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVcwNF0s558=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVcwNF0tAew=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVcwNF0uE34=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVcwNF0vsAE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVcwNF0w5ls=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVdEqmBOVoU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBP7Mw=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 918, + "top": 711, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBQ+G0=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 910, + "top": 724, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBRwAI=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 933, + "top": 686, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBSb60=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1072, + "top": 800, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBT13s=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1063, + "top": 811, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBU/V0=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1089, + "top": 779, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBVD2o=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 765, + "top": 623, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBWru8=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 761, + "top": 635, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBX1jY=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 775, + "top": 597, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVdEqmBYqxc=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVdEqmBZh5U=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "lineStyle": 1, + "points": "1102:807;751:603", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVdEqmBP7Mw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVdEqmBQ+G0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVdEqmBRwAI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVdEqmBSb60=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVdEqmBT13s=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVdEqmBU/V0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVdEqmBVD2o=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVdEqmBWru8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVdEqmBX1jY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVdEqmBYqxc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVdEqmBZh5U=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWbWiJQ+LqI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWbWiJQ/pQw=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRAz/w=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1808, + "top": 368, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRBIu8=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "font": "Arial;13;1", + "left": 594, + "top": 819.5, + "width": 167, + "height": 13, + "text": "doCalScheduleSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRCluw=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1808, + "top": 368, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRDVic=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1808, + "top": 368, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 589, + "top": 812.5, + "width": 177.603515625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWbWiJRAz/w=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWbWiJRBIu8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWbWiJRCluw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWbWiJRDVic=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWbWiJRE0bA=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWbWiJRF/Bs=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWbWiJRG03U=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWbWiJRHoKE=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWbWiZRIksM=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 552, + "top": 808, + "width": 251, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWbWiJRE0bA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWbWiJRF/Bs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWbWiJRG03U=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWbWiJRHoKE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWbWiZRIksM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWiYh6tfjKM=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWiYh6tg64I=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6th8ec=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1424, + "top": 416, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tiGF8=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 703.5, + "top": 931.5, + "width": 116, + "height": 13, + "text": "该测回是否完成测量" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tjmMc=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1424, + "top": 416, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tktDE=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1424, + "top": 416, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 698.5, + "top": 924.5, + "width": 127, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWiYh6th8ec=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWiYh6tiGF8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWiYh6tjmMc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWiYh6tktDE=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWiYh6tlfk4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWiYh6tmr4M=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWiYiKtnqn4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWiYiKtodLM=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWiYiKtpwlU=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 672, + "top": 920, + "width": 179, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWiYh6tlfk4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWiYh6tmr4M=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWiYiKtnqn4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWiYiKtodLM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWiYiKtpwlU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWkDsK/8U8w=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK/9X9k=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 730, + "top": 865, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK/+yfw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 742, + "top": 856, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK//l9E=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 707, + "top": 884, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAAR6U=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 718, + "top": 848, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAB24o=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 730, + "top": 842, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLACKmw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 693, + "top": 861, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLADQMw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": 883, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAEjZI=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 753, + "top": 873, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAFuWM=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 725, + "top": 903, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWkDsLAGH8s=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1160, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWkDsLAHEmo=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1160, + "top": 208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "tail": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "lineStyle": 1, + "points": "691:843;748:919", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWkDsK/9X9k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWkDsK/+yfw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWkDsK//l9E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWkDsLAAR6U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWkDsLAB24o=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWkDsLACKmw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWkDsLADQMw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWkDsLAEjZI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWkDsLAFuWM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWkDsLAGH8s=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWkDsLAHEmo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWmAObijdJg=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObikqE4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "font": "Arial;13;0", + "left": 702, + "top": 756, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObilnCo=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 710, + "top": 758, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObima+o=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 754, + "top": 753, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObinxIM=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 741, + "top": 888, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObioxZQ=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 727, + "top": 888, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObip4S4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 768, + "top": 890, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObiqN8s=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 710, + "top": 624, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObir6/Y=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 697, + "top": 628, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObisLv4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 617, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWmAObitY30=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -888, + "top": 512, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWmAObiuohI=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -888, + "top": 512, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "lineStyle": 1, + "points": "759:919;722:603", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWmAObikqE4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWmAObilnCo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWmAObima+o=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWmAObinxIM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWmAObioxZQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWmAObip4S4=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWmAObiqN8s=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWmAObir6/Y=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWmAObisLv4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWmAObitY30=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWmAObiuohI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWo+Isgcitc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWo+Isgdtvs=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isge0Bo=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 496, + "top": -256, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isgf4GU=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 658, + "top": 1051.5, + "width": 90, + "height": 13, + "text": "执行单测回检测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isgg0Do=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 496, + "top": -256, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+IsghCRI=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 496, + "top": -256, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 653, + "top": 1044.5, + "width": 101, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWo+Isge0Bo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWo+Isgf4GU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWo+Isgg0Do=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWo+IsghCRI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWo+IsgimWA=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWo+IsgjYQU=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWo+I8gkz+0=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWo+I8gl0UM=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWo+I8gmRYk=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 632, + "top": 1040, + "width": 142, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWo+IsgimWA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWo+IsgjYQU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWo+I8gkz+0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWo+I8gl0UM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWo+I8gmRYk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWqc88vvIe4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vwQ3o=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "font": "Arial;13;0", + "left": 728, + "top": 997, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1, + "text": "+完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vxT8A=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 758, + "top": 1003, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vy9C4=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 717, + "top": 984, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vzWws=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 754, + "top": 978, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v0Sh0=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 765, + "top": 986, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v168Q=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 731, + "top": 962, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v2l68=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 735, + "top": 1016, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v3ThA=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 748, + "top": 1019, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v4wsI=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 709, + "top": 1008, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWqc88v5V34=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWqc88v6Awc=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "tail": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "lineStyle": 1, + "points": "752:955;711:1039", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWqc88vwQ3o=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWqc88vxT8A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWqc88vy9C4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWqc88vzWws=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWqc88v0Sh0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWqc88v168Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWqc88v2l68=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWqc88v3ThA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWqc88v4wsI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWqc88v5V34=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWqc88v6Awc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWvJyNWG+ro=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJyNWHf5E=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "font": "Arial;13;0", + "left": 1068, + "top": 991, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWI+RY=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1102, + "top": 976, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWJFaw=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1107, + "top": 1020, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWKHVg=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 798, + "top": 1025, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWLzSM=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 799, + "top": 1011, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWM5GE=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 796, + "top": 1053, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWN+wY=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1411, + "top": 957, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWO3W0=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1407, + "top": 944, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWPqsM=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1418, + "top": 984, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWvJydWQnX8=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWvJydWRolw=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "lineStyle": 1, + "points": "774:1049;1439:976", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWvJyNWHf5E=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWvJydWI+RY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWvJydWJFaw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWvJydWKHVg=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWvJydWLzSM=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWvJydWM5GE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWvJydWN+wY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWvJydWO3W0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWvJydWPqsM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWvJydWQnX8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWvJydWRolw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWzzg+QpJu4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWzzg+QqF0g=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QruaM=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -800, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QscXo=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "font": "Arial;13;1", + "left": 1093.5, + "top": 907.5, + "width": 144, + "height": 13, + "text": "doCalScheduleAllCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QtTVY=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -800, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QuN+0=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -800, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1088.5, + "top": 900.5, + "width": 155.208984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWzzg+QruaM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWzzg+QscXo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWzzg+QtTVY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWzzg+QuN+0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWzzg+QvVhA=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWzzhOQwWI4=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWzzhOQxyn0=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWzzhOQy5lE=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWzzhOQzPbk=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1056, + "top": 896, + "width": 219, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWzzg+QvVhA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWzzhOQwWI4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWzzhOQxyn0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWzzhOQy5lE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWzzhOQzPbk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXS1EJdHVug=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EJdIPgY=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 953, + "top": 934, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EJdJc8o=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 954, + "top": 949, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdKavs=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 952, + "top": 905, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdLggY=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1029, + "top": 930, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdMTYk=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1028, + "top": 943, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdNexM=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1032, + "top": 902, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdOTNQ=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 877, + "top": 939, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdPiGs=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 880, + "top": 952, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdQDNw=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 871, + "top": 912, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXS1EZdR8Jw=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXS1EZdSgUI=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "tail": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "lineStyle": 1, + "points": "1055:920;851:932", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXS1EJdIPgY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXS1EJdJc8o=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXS1EZdKavs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXS1EZdLggY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXS1EZdMTYk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXS1EZdNexM=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXS1EZdOTNQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXS1EZdPiGs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXS1EZdQDNw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXS1EZdR8Jw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXS1EZdSgUI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RXZT37eTFkI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RXZT37eUYGs=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eVlUE=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -768, + "top": -352, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eWL9s=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 75, + "top": 683.5, + "width": 209, + "height": 13, + "text": "是否是doCalScheduleAllCycle状态" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eXM1A=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -768, + "top": -352, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eYXNc=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -768, + "top": -352, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 70, + "top": 676.5, + "width": 220.208984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXZT37eVlUE=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RXZT37eWL9s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RXZT37eXM1A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXZT37eYXNc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RXZT4LeZ09I=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RXZT4LeaFc4=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RXZT4Leb1Fs=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RXZT4Lec37Q=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RXZT4Led934=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 672, + "width": 311, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RXZT4LeZ09I=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RXZT4LeaFc4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RXZT4Leb1Fs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RXZT4Lec37Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RXZT4Led934=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXgsFM1PXPQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1QsVQ=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "font": "Arial;13;0", + "left": 415, + "top": 879, + "width": 33.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1, + "text": "+通过" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1Ra4g=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 422, + "top": 891, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1S7Hk=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 448, + "top": 854, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1TpZY=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 646, + "top": 1030, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1UfIs=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 636, + "top": 1039, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1VQJk=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 665, + "top": 1010, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1WeYo=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 217, + "top": 728, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1XNlM=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 211, + "top": 740, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1Y+GY=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 229, + "top": 703, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXgsFc1ZbPg=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXgsFc1aqC8=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "tail": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "lineStyle": 1, + "points": "676:1039;205:707", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXgsFM1QsVQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXgsFM1Ra4g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXgsFM1S7Hk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXgsFM1TpZY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXgsFM1UfIs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXgsFM1VQJk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXgsFM1WeYo=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXgsFM1XNlM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXgsFM1Y+GY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXgsFc1ZbPg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXgsFc1aqC8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXiiXNaNYZA=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaOCjk=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "font": "Arial;13;0", + "left": 289, + "top": 570, + "width": 33.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1, + "text": "+不是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaPvOQ=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 296, + "top": 558, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaQrNs=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 322, + "top": 595, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaRjEI=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 214, + "top": 637, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaS5Dg=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 625, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaT/jE=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 227, + "top": 662, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaUStc=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 395, + "top": 504, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaVtIQ=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 385, + "top": 495, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaWcc8=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 415, + "top": 523, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXiiXNaXeGE=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXiiXNaY4kk=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "lineStyle": 1, + "points": "203:671;425:507", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXiiXNaOCjk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXiiXNaPvOQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXiiXNaQrNs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXiiXNaRjEI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXiiXNaS5Dg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXiiXNaT/jE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXiiXNaUStc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXiiXNaVtIQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXiiXNaWcc8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXiiXNaXeGE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXiiXNaY4kk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX4IzuDknh4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX4IzuDlZLU=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDmg8A=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDnpIw=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 69, + "top": 1043.5, + "width": 181, + "height": 13, + "text": "检测其他测回是否有待补测数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDoCnY=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDpft0=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 64, + "top": 1036.5, + "width": 192, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX4IzuDmg8A=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX4IzuDnpIw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX4IzuDoCnY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX4IzuDpft0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX4IzuDqBSE=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX4IzuDrpSs=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX4IzuDsUmU=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX4IzuDtPH4=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX4IzuDu2iA=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 1032, + "width": 271, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX4IzuDqBSE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX4IzuDrpSs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX4IzuDsUmU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX4IzuDtPH4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX4IzuDu2iA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX50xuaSWVY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaTzmw=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "font": "Arial;13;0", + "left": 173, + "top": 863, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1, + "text": "+是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaUoZk=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 198, + "top": 864, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaVv9g=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 154, + "top": 862, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaWjUs=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 727, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaX0wc=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 730, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaYr8k=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 721, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaZPzE=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 176, + "top": 999, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaaRl8=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 189, + "top": 998, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuabK8k=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 148, + "top": 1002, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX50xuac8yw=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX50xuadjR8=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "tail": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "lineStyle": 1, + "points": "178:707;160:1031", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX50xuaTzmw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX50xuaUoZk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX50xuaVv9g=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX50xuaWjUs=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX50xuaX0wc=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX50xuaYr8k=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX50xuaZPzE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX50xuaaRl8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX50xuabK8k=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX50xuac8yw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX50xuadjR8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX8e8+6VSP4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX8e9O6W2xM=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6XR7Q=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -400, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6YBmI=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 295.5, + "top": 1211.5, + "width": 77, + "height": 13, + "text": "提示用户选择" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6ZG1Q=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -400, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6aHT4=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -400, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 290.5, + "top": 1204.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX8e9O6XR7Q=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX8e9O6YBmI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX8e9O6ZG1Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX8e9O6aHT4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX8e9O6brFw=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX8e9O6chUQ=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX8e9O6d2JQ=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX8e9O6ehSE=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX8e9O6fsgA=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 272, + "top": 1200, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX8e9O6brFw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX8e9O6chUQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX8e9O6d2JQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX8e9O6ehSE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX8e9O6fsgA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX9EYPFfH8Q=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFg5zI=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "font": "Arial;13;0", + "left": 246, + "top": 1116, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFh+Xw=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 266, + "top": 1105, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFiQm8=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 235, + "top": 1137, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFj0XU=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 207, + "top": 1068, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFkHH4=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 217, + "top": 1060, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFlEI4=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 184, + "top": 1085, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFmXkk=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 305, + "top": 1164, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFnjvk=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 313, + "top": 1153, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFoLfQ=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 289, + "top": 1186, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX9EYPFp0GM=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX9EYPFqX8k=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "tail": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "lineStyle": 1, + "points": "178:1067;314:1199", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX9EYPFg5zI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX9EYPFh+Xw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX9EYPFiQm8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX9EYPFj0XU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX9EYPFkHH4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX9EYPFlEI4=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX9EYPFmXkk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX9EYPFnjvk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX9EYPFoLfQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX9EYPFp0GM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX9EYPFqX8k=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX+92/rtdeY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX+92/ru5aU=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rvMVo=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -608, + "top": -240, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rwk7c=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 492, + "top": 1107.5, + "width": 62, + "height": 13, + "text": "切换测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rxBWI=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -608, + "top": -240, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/ryOmk=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -608, + "top": -240, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 487, + "top": 1100.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX+92/rvMVo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX+92/rwk7c=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX+92/rxBWI=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX+92/ryOmk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX+92/rzeck=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX+92/r0UGE=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX+92/r1dEM=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX+92/r24rI=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX+92/r3m0Y=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 472, + "top": 1096, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX+92/rzeck=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX+92/r0UGE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX+92/r1dEM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX+92/r24rI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX+92/r3m0Y=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX/wMv3JNxw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3KAYY=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 606, + "top": 837, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3L2sA=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 592, + "top": 832, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3MDuY=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 635, + "top": 848, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3NMMM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 524, + "top": 1059, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3OaEE=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 512, + "top": 1052, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3P2uw=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 548, + "top": 1073, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3QkNM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 689, + "top": 616, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3RuyM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 676, + "top": 613, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3SQ5M=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 717, + "top": 621, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX/wM/3TMvA=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX/wM/3Udik=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "lineStyle": 1, + "points": "529:1095;713:603", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX/wM/3KAYY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX/wM/3L2sA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX/wM/3MDuY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX/wM/3NMMM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX/wM/3OaEE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX/wM/3P2uw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX/wM/3QkNM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX/wM/3RuyM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX/wM/3SQ5M=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX/wM/3TMvA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX/wM/3Udik=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYA6Lgau9u4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgavBvE=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "font": "Arial;13;0", + "left": 370, + "top": 1145, + "width": 98.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1, + "text": "+跳转到相应测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgawDgk=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 412, + "top": 1132, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lgaxot4=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 434, + "top": 1172, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgayEWk=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 381, + "top": 1167, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lgazq+M=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 377, + "top": 1154, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga0Sio=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 390, + "top": 1193, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga1FSA=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 459, + "top": 1124, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga2vcA=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 450, + "top": 1113, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga3b2g=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 476, + "top": 1146, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYA6Lga4c4g=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYA6Lga51go=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "tail": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "lineStyle": 1, + "points": "366:1199;489:1131", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYA6LgavBvE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYA6LgawDgk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYA6Lgaxot4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYA6LgayEWk=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYA6Lgazq+M=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYA6Lga0Sio=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYA6Lga1FSA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYA6Lga2vcA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYA6Lga3b2g=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYA6Lga4c4g=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYA6Lga51go=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYRxIyqNVJQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqOsk8=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "font": "Arial;13;0", + "left": 340, + "top": 844, + "width": 72.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1, + "text": "+忽略或取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqPdMg=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 361, + "top": 842, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqQWvY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 405, + "top": 849, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqRHT4=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 325, + "top": 1164, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqS57E=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 312, + "top": 1160, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqTkAo=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 351, + "top": 1173, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqUXmw=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 427, + "top": 524, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqVgEY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 413, + "top": 524, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqWNBU=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 454, + "top": 524, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYRxJCqXBjo=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYRxJCqYdsw=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "lineStyle": 1, + "points": "336:1199;446:507", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYRxIyqOsk8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYRxIyqPdMg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYRxIyqQWvY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYRxIyqRHT4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYRxJCqS57E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYRxJCqTkAo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYRxJCqUXmw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYRxJCqVgEY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYRxJCqWNBU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYRxJCqXBjo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYRxJCqYdsw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RYWBNj55r2s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RYWBNj56ll8=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj57vDo=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj582Gg=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 167.5, + "top": 1403.5, + "width": 155, + "height": 13, + "text": "检测其他测回是否有空数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj59CIs=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj5+a6c=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 162.5, + "top": 1396.5, + "width": 166, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYWBNj57vDo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RYWBNj582Gg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RYWBNj59CIs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYWBNj5+a6c=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RYWBNj5/meo=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RYWBNj6ApFY=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RYWBNj6BKos=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RYWBNj6CyfU=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RYWBNj6DzGw=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 128, + "top": 1392, + "width": 234, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RYWBNj5/meo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RYWBNj6ApFY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RYWBNj6BKos=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RYWBNj6CyfU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RYWBNj6DzGw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYXKoUPzfpc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP0Xm4=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "font": "Arial;13;0", + "left": 205, + "top": 1219, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP1/8o=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 230, + "top": 1215, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP2TmE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 186, + "top": 1226, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP3dpE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 183, + "top": 1082, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP4Dks=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 197, + "top": 1081, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP5sn0=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 155, + "top": 1084, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP6dKk=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 248, + "top": 1356, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP7hGo=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 260, + "top": 1350, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP8Pbs=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 222, + "top": 1366, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYXKoUP9qJ8=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYXKokP+OFo=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "tail": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "lineStyle": 1, + "points": "163:1067;240:1391", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYXKoUP0Xm4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYXKoUP1/8o=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYXKoUP2TmE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYXKoUP3dpE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYXKoUP4Dks=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYXKoUP5sn0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYXKoUP6dKk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYXKoUP7hGo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYXKoUP8Pbs=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYXKoUP9qJ8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYXKokP+OFo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYbKCEsNrL8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsOHZ0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "font": "Arial;13;0", + "left": 264, + "top": 1300, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsP+kM=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 260, + "top": 1294, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsQdPM=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 301, + "top": 1313, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsRxi0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 249, + "top": 1355, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsSIa0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 238, + "top": 1347, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsTIOs=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 272, + "top": 1370, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsUoUc=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 300, + "top": 1246, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCUsVQTY=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 287, + "top": 1242, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCUsWC+U=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 327, + "top": 1253, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYbKCUsX4lU=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYbKCUsYcdA=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "tail": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "lineStyle": 1, + "points": "252:1391;325:1235", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYbKCEsOHZ0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYbKCEsP+kM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYbKCEsQdPM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYbKCEsRxi0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYbKCEsSIa0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYbKCEsTIOs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYbKCEsUoUc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYbKCUsVQTY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYbKCUsWC+U=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYbKCUsX4lU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYbKCUsYcdA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RYo1sZrzoek=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RYo1sZr0KlU=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr1HjQ=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr2W5c=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 623.5, + "top": 1275.5, + "width": 116, + "height": 13, + "text": "检测其他测回合法性" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr3XYs=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -160, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr4E80=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 618.5, + "top": 1268.5, + "width": 127, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYo1sZr1HjQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RYo1sZr2W5c=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RYo1sZr3XYs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYo1sZr4E80=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RYo1sZr5VvI=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RYo1sZr6Veg=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RYo1sZr7Dv4=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RYo1sZr8TjI=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RYo1sZr9JcM=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 592, + "top": 1264, + "width": 179, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RYo1sZr5VvI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RYo1sZr6Veg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RYo1sZr7Dv4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RYo1sZr8TjI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RYo1sZr9JcM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYqgkqO2MyI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO3BkI=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "font": "Arial;13;0", + "left": 428, + "top": 1324, + "width": 59.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1, + "text": "+无空测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO4B50=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 453, + "top": 1310, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO5Eu4=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 466, + "top": 1353, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO6Q3U=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 325, + "top": 1363, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO7HyE=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 324, + "top": 1349, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO8jmg=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 329, + "top": 1390, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO9LA0=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 590, + "top": 1285, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO+vZw=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 584, + "top": 1273, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO/OQc=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 602, + "top": 1311, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYqgkqPAF8U=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYqgkqPBTIk=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "tail": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "lineStyle": 1, + "points": "305:1391;620:1299", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYqgkqO3BkI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYqgkqO4B50=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYqgkqO5Eu4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYqgkqO6Q3U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYqgkqO7HyE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYqgkqO8jmg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYqgkqO9LA0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYqgkqO+vZw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYqgkqO/OQc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYqgkqPAF8U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYqgkqPBTIk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYuGzq0zcW0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq00uWc=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "font": "Arial;13;0", + "left": 1017, + "top": 1104, + "width": 137.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1, + "text": "+发现有测回未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq01kJ4=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1080, + "top": 1090, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq02LjQ=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1096, + "top": 1133, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq03E1k=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 746, + "top": 1233, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq044hU=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": 1220, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq05NGE=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": 1260, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq06xW4=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1424, + "top": 976, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq07gn8=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1417, + "top": 964, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq08/Nc=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1438, + "top": 1000, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYuGzq09BO0=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYuGzq0+Fys=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "lineStyle": 1, + "points": "728:1263;1454:987", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYuGzq00uWc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYuGzq01kJ4=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYuGzq02LjQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYuGzq03E1k=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYuGzq044hU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYuGzq05NGE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYuGzq06xW4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYuGzq07gn8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYuGzq08/Nc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYuGzq09BO0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYuGzq0+Fys=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RY5M47VS/5M=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M47VTDWg=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "font": "Arial;13;0", + "left": 508, + "top": 883, + "width": 85.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1, + "text": "+全部通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M47VUjKA=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 536, + "top": 887, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVVTlw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 579, + "top": 874, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVWBPw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 654, + "top": 1236, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVX2xY=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 640, + "top": 1237, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVYskw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 681, + "top": 1232, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVZo0A=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 446, + "top": 530, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVaI9U=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 434, + "top": 536, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVbdjo=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 472, + "top": 518, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY5M5LVcoPg=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY5M5LVdBDo=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "lineStyle": 1, + "points": "676:1263;454:507", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RY5M47VTDWg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY5M47VUjKA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY5M5LVVTlw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RY5M5LVWBPw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RY5M5LVX2xY=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RY5M5LVYskw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RY5M5LVZo0A=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RY5M5LVaI9U=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RY5M5LVbdjo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RY5M5LVcoPg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RY5M5LVdBDo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RY+P3cq78x4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RY+P3cq8lrU=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq9UVw=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -384, + "top": -48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq+inU=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 860.5, + "top": 1283.5, + "width": 101, + "height": 13, + "text": "switchState2Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq/1Xo=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -384, + "top": -48, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3crAIoY=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -384, + "top": -48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 855.5, + "top": 1276.5, + "width": 111.8671875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY+P3cq9UVw=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RY+P3cq+inU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RY+P3cq/1Xo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY+P3crAIoY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RY+P3srBu6A=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RY+P3srCnMw=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RY+P3srDTrA=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RY+P3srE+P0=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RY+P3srFRq4=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 832, + "top": 1272, + "width": 158, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RY+P3srBu6A=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RY+P3srCnMw=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RY+P3srDTrA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RY+P3srE+P0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RY+P3srFRq4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RY/lW9HunTY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hvi/A=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 837, + "top": 877, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hw6yM=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 822, + "top": 879, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hx5k8=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 866, + "top": 872, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9HyN1A=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 888, + "top": 1241, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hz89k=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 1240, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H0J0I=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 916, + "top": 1241, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H1ErY=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 785, + "top": 512, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H23xw=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 772, + "top": 516, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H3Onc=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 812, + "top": 504, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY/lW9H46uE=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY/lW9H5+K0=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "lineStyle": 1, + "points": "907:1271;797:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RY/lW9Hvi/A=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY/lW9Hw6yM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY/lW9Hx5k8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RY/lW9HyN1A=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RY/lW9Hz89k=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RY/lW9H0J0I=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RY/lW9H1ErY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RY/lW9H23xw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RY/lW9H3Onc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RY/lW9H46uE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RY/lW9H5+K0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZAQqNi9KXs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZAQqNi+U5k=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNi/3K4=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": 160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjAnDw=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 834, + "top": 1467.5, + "width": 90, + "height": 13, + "text": "查找待补测数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjB74E=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": 160, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjCvdQ=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": 160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 829, + "top": 1460.5, + "width": 101, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZAQqNi/3K4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZAQqNjAnDw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZAQqNjB74E=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZAQqNjCvdQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZAQqNjDBLs=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZAQqNjEOXs=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZAQqNjF53M=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZAQqNjGCMk=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZAQqNjHp8s=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 808, + "top": 1456, + "width": 142, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZAQqNjDBLs=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZAQqNjEOXs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZAQqNjF53M=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZAQqNjGCMk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZAQqNjHp8s=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZDsue7ftRY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7gCik=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "font": "Arial;13;0", + "left": 869, + "top": 1372, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7h1YU=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 864, + "top": 1369, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7iQis=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 908, + "top": 1377, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7jDYo=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 870, + "top": 1420, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7kyAA=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 1416, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7ll8Q=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 897, + "top": 1429, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7mtW0=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 887, + "top": 1323, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7n/oo=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 874, + "top": 1323, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7oje8=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 915, + "top": 1324, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZDsue7pTkA=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZDsue7qLNI=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "tail": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "lineStyle": 1, + "points": "881:1455;907:1307", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZDsue7gCik=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZDsue7h1YU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZDsue7iQis=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZDsue7jDYo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZDsue7kyAA=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZDsue7ll8Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZDsue7mtW0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZDsue7n/oo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZDsue7oje8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZDsue7pTkA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZDsue7qLNI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZEXNfhC2ho=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZEXNfhDeUQ=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhE1JY=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -880, + "top": -96, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhF08s=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 525, + "top": 1419.5, + "width": 64, + "height": 13, + "text": "查找空数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhGZmc=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -880, + "top": -96, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhHCVU=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -880, + "top": -96, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 520, + "top": 1412.5, + "width": 75, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZEXNfhE1JY=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZEXNfhF08s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZEXNfhGZmc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZEXNfhHCVU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZEXNfhIvoY=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZEXNvhJXeE=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZEXNvhKzwc=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZEXNvhLfS4=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZEXNvhM3lA=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 504, + "top": 1408, + "width": 106, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZEXNfhIvoY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZEXNvhJXeE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZEXNvhKzwc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZEXNvhLfS4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZEXNvhM3lA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZE5Jvvk8+0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vlq9g=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "font": "Arial;13;0", + "left": 695, + "top": 1455, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vm7FE=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 703, + "top": 1470, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vn7vY=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 710, + "top": 1426, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/voHLE=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 779, + "top": 1467, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vpdnU=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 774, + "top": 1479, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vqSPU=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 787, + "top": 1440, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vrD3M=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 633, + "top": 1445, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vslRk=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 633, + "top": 1459, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vtins=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 633, + "top": 1417, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZE5J/vuuHI=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZE5J/vvgB0=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "tail": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "lineStyle": 1, + "points": "807:1462;610:1433", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZE5J/vlq9g=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZE5J/vm7FE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZE5J/vn7vY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZE5J/voHLE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZE5J/vpdnU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZE5J/vqSPU=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZE5J/vrD3M=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZE5J/vslRk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZE5J/vtins=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZE5J/vuuHI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZE5J/vvgB0=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZGEZgj/XLs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkArOw=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "font": "Arial;13;0", + "left": 717, + "top": 1336, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkB2TY=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 722, + "top": 1322, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkChVo=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 738, + "top": 1365, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkDRjc=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 621, + "top": 1377, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkERZ0=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 619, + "top": 1364, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkFONE=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 627, + "top": 1404, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkGzgA=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 833, + "top": 1296, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkHVm4=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 826, + "top": 1284, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkIGXU=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 847, + "top": 1320, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZGEZgkJQgE=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZGEZgkK2ek=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "tail": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "lineStyle": 1, + "points": "603:1407;863:1307", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZGEZgkArOw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZGEZgkB2TY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZGEZgkChVo=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZGEZgkDRjc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZGEZgkERZ0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZGEZgkFONE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZGEZgkGzgA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZGEZgkHVm4=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZGEZgkIGXU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZGEZgkJQgE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZGEZgkK2ek=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZHb+w38rbY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w39z3k=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "font": "Arial;13;0", + "left": 477, + "top": 952, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w3+E8c=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 472, + "top": 954, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w3/cnc=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 516, + "top": 949, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4A7LA=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 536, + "top": 1376, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4BF6A=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 522, + "top": 1376, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4COx0=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 563, + "top": 1378, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4DS1Q=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 439, + "top": 528, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4Efb8=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 426, + "top": 532, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4Fx+M=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 465, + "top": 521, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZHb+w4GxWE=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZHb+w4HFa8=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "lineStyle": 1, + "points": "554:1407;451:507", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZHb+w39z3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZHb+w3+E8c=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZHb+w3/cnc=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZHb+w4A7LA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZHb+w4BF6A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZHb+w4COx0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZHb+w4DS1Q=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZHb+w4Efb8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZHb+w4Fx+M=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZHb+w4GxWE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZHb+w4HFa8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZ6XBji6Gjs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZ6XBji742g=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji84Lo=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji96yI=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "font": "Arial;13;1", + "left": 1112, + "top": 1595.5, + "width": 79, + "height": 13, + "text": "doMoveBack" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji+VvE=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji/AjM=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1107, + "top": 1588.5, + "width": 90.18994140625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZ6XBji84Lo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZ6XBji96yI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZ6XBji+VvE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZ6XBji/AjM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZ6XBjjASWk=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZ6XBzjBtGc=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZ6XBzjCvBw=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZ6XBzjD9LY=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZ6XBzjEkZ0=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1088, + "top": 1584, + "width": 127, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZ6XBjjASWk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZ6XBzjBtGc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZ6XBzjCvBw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZ6XBzjD9LY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZ6XBzjEkZ0=" + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5nMrk1mLCw=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "check2C", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P5saV03F9So=", + "_parent": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5saV03GReQ=", + "_parent": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5saV03HrLQ=", + "_parent": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "reference": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P56tf07Epig=", + "_parent": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P56tgE7F7Yk=", + "_parent": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P56tgE7GNNA=", + "_parent": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5rmBE2WOV0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "recordClean" + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5P5vlT04vpIc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "用户选择操作" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P56LY06KFIA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【用户选择操作】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P5/ask/ASWM=", + "_parent": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "name": "选择忽略or重测目标", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5/ask/BASE=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5/ask/CwwU=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6ETu1Fsgo0=", + "_parent": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "name": "重测测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6ETu1FtUvs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6ETu1Fuzfc=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5/CAk96MB0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "Idle" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6Btl1DQYFs=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【提示用户是否确定删除整个测回】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6HZl1I+eIg=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "name": "选择忽略or取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6HZl1I/u/s=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6HZl1JAt1Q=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6Jc6FP89fs=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "name": "确认删除", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6Jc6FP9Ay0=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6Jc6FP+W/w=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "reference": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6IYDFMK28k=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【执行删除操作】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6KuWFYuLA4=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6KuWFYvXto=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "reference": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6KuWFYwtmg=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6I/oFN00qM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重新搜索目标开启新一轮测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJXgiQky2RI=", + "_parent": { + "$ref": "AAAAAAF5P6I/oFN00qM=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJXgiQkzVQM=", + "_parent": { + "$ref": "AAAAAAF5QJXgiQky2RI=" + }, + "reference": { + "$ref": "AAAAAAF5P6I/oFN00qM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJXgiQk0kU4=", + "_parent": { + "$ref": "AAAAAAF5QJXgiQky2RI=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJWvCggxZrM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "move2NextValidate", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVWv2lZqu2A=", + "_parent": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVWv2lZro+8=", + "_parent": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVWv2lZs/XI=", + "_parent": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJc4CA2m0sA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkHalfCycleZero", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJesYRAUeZI=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "name": "测站不闭合or半测回归零差正常", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJesYRAV/Pw=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "reference": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJesYRAWIno=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "reference": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJmQwBdscKg=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "name": "没有通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJmQwBdt/Nk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "reference": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJmQwBdu0wk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "reference": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJeXAw9WAQQ=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isReady2CCheck" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJjLZBMJQJ8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2StandStill", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJnk3RnjFKU=", + "_parent": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnk3Rnk4S8=", + "_parent": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnk3Rnlvxc=", + "_parent": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJk5ohVWyGc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示半测回归零检测失败", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJnHsRkKHYc=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnHsRkLdTo=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "reference": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnHsRkM5N4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ6ahSPVJNg=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkReadData", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ87Oyj+dCg=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "name": "单测量or通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ87Oyj/TJQ=", + "_parent": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ87OykA4RY=", + "_parent": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "reference": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ/Ugywh52g=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/Ugywiha4=", + "_parent": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/UgywjRPE=", + "_parent": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "reference": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ8m8Sf4R1w=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isHalfCycleZeroCheckReady" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ+mRitXafY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示读数有误", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ/0PCz+xYo=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/0PCz/2CU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "reference": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/0PC0AjHo=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKE6OTfx/D4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QKI4y0KDGow=", + "_parent": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKI4zEKEuw8=", + "_parent": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKI4zEKFtZg=", + "_parent": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "reference": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QKvMIE8VEZE=", + "_parent": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKvMIE8WKCE=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKvMIE8XsG8=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKIG+T9Wjdo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isAllCycleCompleted" + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5QKJM6UPX41c=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseSubject1" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKuCwkzWMuI=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户选择", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QK2Ql1lrW/0=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "name": "忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK2Ql1lsCzU=", + "_parent": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK2Ql1ltUBY=", + "_parent": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QLdiW2HmZcI=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLdiW2HnzLc=", + "_parent": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLdiW2HodP8=", + "_parent": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "reference": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMnaf4pzXpA=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMnaf4p0R7o=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMnaf4p1n0A=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKyR6VB8Gq8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重测方向", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QLx6RGoJ91g=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLx6RGoKxZI=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "reference": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLx6RGoLs1U=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKysH1F2Xh8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重测测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QNAhapFq3kM=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "name": "取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNAhapFrudc=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNAhapFsZZ8=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QNFL6qCXEtU=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "name": "忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNFL6qCY2AQ=", + "_parent": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNFL6qCZ01s=", + "_parent": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVcwNF0hcaI=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVcwNF0iVWE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVcwNF0jQf0=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "reference": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKzDRVJwpI4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "resetSurveyorStateAndKeepPosition", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QK340l0BzRk=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK340l0ChAw=", + "_parent": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK340l0D79M=", + "_parent": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QLwOJ2bN7N0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "resurveyPoints", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMbzEHNMUo0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "开始重测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMbzEHNNh8o=", + "_parent": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMbzEHNOm6M=", + "_parent": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLGeneralization", + "_id": "AAAAAAF5QMevPnTKBWs=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "重测失败", + "source": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "target": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVTunkvVKUs=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "重测失败", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVTun0vWQ0U=", + "_parent": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVTun0vXr0g=", + "_parent": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QMaQUG/pf+g=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2RestartInCurrentCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMjEpoXtFac=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMjEpoXuicM=", + "_parent": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMjEpoXvKNs=", + "_parent": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RVbpp1nIOnU=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行测回删除", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVdEqWBKDgY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVdEqWBL2Ro=", + "_parent": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "reference": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVdEqWBMaWs=", + "_parent": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWbWh5Q82SE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doCalScheduleSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWkDr6/4piw=", + "_parent": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWkDr6/5hKI=", + "_parent": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "reference": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWkDr6/6Fyk=", + "_parent": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + } + } + } + ] + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5RWdznZ2YK/Q=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseSubject2" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWiYh6tdXHE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "该测回是否完成测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWmAObifwr4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWmAObigyuY=", + "_parent": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWmAObih5u0=", + "_parent": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWqc8svr3pE=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "name": "完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWqc8svs8AE=", + "_parent": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWqc8svtE1U=", + "_parent": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWo+Icga7No=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行单测回检测", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWvJyNWC314=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWvJyNWDYLg=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWvJyNWEI/s=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWxGx9n5fHg=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWxGx9n6uSs=", + "_parent": { + "$ref": "AAAAAAF5RWxGx9n5fHg=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWxGx9n7A0k=", + "_parent": { + "$ref": "AAAAAAF5RWxGx9n5fHg=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXgsE81LcLM=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "通过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXgsE81Ml9Y=", + "_parent": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXgsE81Ncj4=", + "_parent": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWzzg+QnXQo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doCalScheduleAllCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXS1D5dDHCY=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXS1D5dEJJs=", + "_parent": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "reference": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXS1D5dF2N4=", + "_parent": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RXZT3reRJjE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "是否是doCalScheduleAllCycle状态", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXiiW9aJDaw=", + "_parent": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "name": "不是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXiiW9aKkno=", + "_parent": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXiiW9aL3M4=", + "_parent": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX50xeaOm84=", + "_parent": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "name": "是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX50xeaPW6s=", + "_parent": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX50xeaQJxA=", + "_parent": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX4IzeDinbw=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有待补测数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX9EYPFbm2U=", + "_parent": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX9EYPFcd3k=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX9EYPFdtmc=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYXKoEPvmVE=", + "_parent": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYXKoUPwWeY=", + "_parent": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYXKoUPxCsE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX8e8+6Tpi8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户选择", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYA6LQaqG8I=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "name": "跳转到相应测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYA6LQaryvU=", + "_parent": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYA6LQashgM=", + "_parent": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "reference": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYRxIiqJIUE=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "name": "忽略或取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYRxIyqKuUY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYRxIyqLN6Y=", + "_parent": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX+92vrrsgo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "切换测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX/wMv3F6d4=", + "_parent": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX/wMv3GM64=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "reference": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX/wMv3HIz8=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RYWBNT536bM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有空数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYbKCEsJsiQ=", + "_parent": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYbKCEsKkG0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYbKCEsLR+0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYqgkaOybww=", + "_parent": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "name": "无空测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYqgkaOzOcA=", + "_parent": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYqgkaO0Gyw=", + "_parent": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RYo1sJrxVxU=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回合法性", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYuGza0vDqU=", + "_parent": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "name": "发现有测回未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYuGza0wl4I=", + "_parent": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYuGza0xzjs=", + "_parent": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RY5M4rVOVIM=", + "_parent": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "name": "全部通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY5M4rVPReU=", + "_parent": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY5M4rVQGdM=", + "_parent": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RY+P3cq56es=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2Idle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RY/lWtHqafY=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY/lW9Hrql4=", + "_parent": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY/lW9HsN84=", + "_parent": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZAQp9i7BLM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "查找待补测数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZDsue7baAw=", + "_parent": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZDsue7cAPs=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZDsue7dBLs=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZE5JvvgNmk=", + "_parent": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZE5Jvvh7eI=", + "_parent": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZE5JvviTz0=", + "_parent": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZEXNfhA9nA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "查找空数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZGEZgj773A=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZGEZgj8gpI=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZGEZgj9p0E=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZHb+g34JOw=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZHb+g35LNk=", + "_parent": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZHb+g36Mvo=", + "_parent": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZ6XBTi4yu4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doMoveBack" + } + ] + }, + { + "_type": "UMLProfile", + "_id": "AAAAAAFElnEzslS1AuE=", + "_parent": { + "$ref": "AAAAAAFElm5XMFNoGY0=" + }, + "name": "UMLStandardProfile", + "ownedElements": [ + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFElnFUQFS4mT4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "StandardProfileL2", + "ownedViews": [ + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFElnFrT1S8vVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnFrT1S9WOE=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "model": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1S+aHM=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1S/1HM=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 57, + "top": 59, + "width": 81, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TAD0M=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 57, + "top": 73, + "width": 81, + "height": 12, + "text": "UMLClassifier" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TBaUI=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TCF/Y=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 52, + "top": 52, + "width": 91, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnFrT1S/1HM=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnFrT1TAD0M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnFrT1TBaUI=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnFrT1TCF/Y=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 52, + "top": 52, + "width": 91, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFElnF1nFTadPw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqCEfLOas=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnF1nFTbplQ=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTcCng=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTd3xg=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 213, + "top": 55, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTewJM=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 213, + "top": 69, + "width": 83, + "height": 12, + "text": "Realization" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTfQRQ=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTgrV8=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 48, + "width": 93, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnF1nVTd3xg=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnF1nVTewJM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnF1nVTfQRQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnF1nVTgrV8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFElnF1nVThfqA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 86, + "width": 93, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFElnF1nVTiFXA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 96, + "width": 93, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFElnF1nVTjasU=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 48, + "width": 93, + "height": 38, + "nameCompartment": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFElnF1nVThfqA=" + }, + "operationCompartment": { + "$ref": "AAAAAAFElnF1nVTiFXA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqCEfLOas=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFElnF1nVTjasU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFElnGGLFUGHnM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUH+8s=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 174, + "top": 73, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUIOR8=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": null, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 174, + "top": 88, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUJv6k=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 175, + "top": 43, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "head": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "tail": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "points": "208:64;142:64", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFElnGGLFUH+8s=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFElnGGLFUIOR8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnGGLFUJv6k=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFElnJRglVMyB8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqCkfpKls=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnJRglVN/RI=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVO7ow=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVPiBM=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 217, + "top": 119, + "width": 74.73593139648438, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVQT1k=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 217, + "top": 133, + "width": 74.73593139648438, + "height": 12, + "text": "Specification" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVRdk8=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVSFic=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 112, + "width": 84.73593139648438, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnJRglVPiBM=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnJRglVQT1k=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnJRglVRdk8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnJRglVSFic=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFElnJRglVTXPE=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 150, + "width": 84, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFElnJRglVUe0c=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 160, + "width": 84, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFElnJRg1VVWNU=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 112, + "width": 84.73593139648438, + "height": 38, + "nameCompartment": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFElnJRglVTXPE=" + }, + "operationCompartment": { + "$ref": "AAAAAAFElnJRglVUe0c=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqCkfpKls=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFElnJRg1VVWNU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFElnKVuVV5hVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV6VLo=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 176, + "top": 141, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV7m9U=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 176, + "top": 156, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV8bvU=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 177, + "top": 111, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "head": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "tail": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "points": "212:132;142:132", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFElnKVuVV6VLo=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFElnKVuVV7m9U=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnKVuVV8bvU=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFJsZbpDNpnkE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFJsZbpTNq6XM=", + "_parent": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNrbHw=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 561, + "top": 209, + "width": 87, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNsdGc=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 561, + "top": 223, + "width": 87, + "height": 12, + "text": "UMLClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNtikk=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 1500, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNuOXU=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 1500, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 556, + "top": 204, + "width": 97, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFJsZbpTNrbHw=" + }, + "nameLabel": { + "$ref": "AAAAAAFFJsZbpTNsdGc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFJsZbpTNtikk=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFJsZbpTNuOXU=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 556, + "top": 204, + "width": 97, + "height": 305, + "nameCompartment": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwKqhJFq1z2Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKqhJFq2eQM=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "model": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq3hUU=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 57, + "top": 209, + "width": 79, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq4Vb4=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 57, + "top": 223, + "width": 79, + "height": 12, + "text": "UMLArtifact" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq5GlQ=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq6Fls=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 52, + "top": 204, + "width": 89, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKqhJFq3hUU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKqhJFq4Vb4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKqhJFq5GlQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKqhJFq6Fls=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 52, + "top": 204, + "width": 89, + "height": 329, + "nameCompartment": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKsvdVrTyNI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDUglDBo=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKsvdVrUE8w=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrVvYg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 237, + "top": 209, + "width": 119, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrW/Dg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "font": "Arial;12;3", + "containerExtending": true, + "left": 237, + "top": 223, + "width": 119, + "height": 12, + "text": "File" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrXXrQ=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 48, + "top": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrYnv8=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 48, + "top": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 232, + "top": 204, + "width": 129, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKsvdVrVvYg=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKsvdVrW/Dg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKsvdVrXXrQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKsvdVrYnv8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKsvdVrZA0U=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 248, + "top": 236, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKsvdlraVvA=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 248, + "top": 236, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKsvdlrbd2U=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 32, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 232, + "top": 204, + "width": 129, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKsvdVrZA0U=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKsvdlraVvA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDUglDBo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKsvdlrbd2U=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKtwS1r8DQQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDUg7My0=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKtwS1r9YJ4=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1r+fw8=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 313, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1r/Lsw=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 189, + "top": 327, + "width": 72.51593017578125, + "height": 12, + "text": "Document" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1sAGYA=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 24, + "top": 24, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1sB7y4=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 24, + "top": 24, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKtwS1r+fw8=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKtwS1r/Lsw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKtwS1sAGYA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKtwS1sB7y4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKtwTFsC02k=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 192, + "top": 352, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKtwTFsD5lc=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 192, + "top": 352, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKtwTFsEQlE=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 16, + "top": 16, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKtwTFsC02k=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKtwTFsD5lc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDUg7My0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKtwTFsEQlE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuBulskCVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDkhRFFg=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuBulsld0g=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBulsmb/s=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 257, + "top": 357, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBulsnKBI=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 257, + "top": 371, + "width": 72.51593017578125, + "height": 12, + "text": "Executable" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBu1soKF0=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBu1spOXA=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "top": 352, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuBulsmb/s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuBulsnKBI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuBu1soKF0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuBu1spOXA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuBu1sqPhk=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 284, + "top": 372, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuBu1srnoE=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 284, + "top": 372, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuBu1ssVVg=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 64, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "top": 352, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuBu1sqPhk=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuBu1srnoE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDkhRFFg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuBu1ssVVg=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuIMltMJw4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqD0hnnhc=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuIMltNJK8=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tO63M=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 321, + "top": 405, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tPj60=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 321, + "top": 419, + "width": 72.51593017578125, + "height": 12, + "text": "Library" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tQD7A=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 132, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tRSSY=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 132, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 316, + "top": 400, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuIM1tO63M=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuIM1tPj60=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuIM1tQD7A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuIM1tRSSY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuIM1tSiN4=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 360, + "top": 400, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuIM1tTPjo=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 360, + "top": 400, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuIM1tUHbM=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 88, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 316, + "top": 400, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuIM1tSiN4=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuIM1tTPjo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqD0hnnhc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuIM1tUHbM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuS0lt0dAE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqEEh93KM=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuS0lt1+MM=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt2XgE=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 385, + "top": 453, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt36r8=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 385, + "top": 467, + "width": 72.51593017578125, + "height": 12, + "text": "Script" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt4pP4=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 180, + "top": -180, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt5mi4=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 180, + "top": -180, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 448, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuS0lt2XgE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuS0lt36r8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuS0lt4pP4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuS0lt5mi4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuS0lt6gjg=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 424, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuS0lt7fo0=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 424, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuS0lt8w2A=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -120, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 448, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuS0lt6gjg=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuS0lt7fo0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqEEh93KM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuS0lt8w2A=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKueMluc5bE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqEUiTykw=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKueMludFfk=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMlueAco=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 445, + "top": 501, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMluflfo=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 445, + "top": 515, + "width": 72.51593017578125, + "height": 12, + "text": "Source" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMlughos=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMluhfws=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 496, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKueMlueAco=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKueMluflfo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKueMlughos=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKueMluhfws=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKueMluihu4=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 500, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKueMlujEyo=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 500, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKueMlukJo8=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 496, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKueMluihu4=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKueMlujEyo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqEUiTykw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKueMlukJo8=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzkslvYVdw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzkslvZbd0=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 267, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzks1vasdU=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 252, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzks1vby/c=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 297, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "points": "216:308;216:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzkslvZbd0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzks1vasdU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzks1vby/c=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzsCVvpt2A=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvqAUg=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 285, + "top": 289, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvrTi8=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 270, + "top": 289, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvsewQ=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 314, + "top": 290, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "points": "300:352;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzsCVvqAUg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzsCVvrTi8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzsCVvsewQ=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzxcVv6A2c=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv7wpA=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 327, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv8NxM=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 327, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv9X58=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 328, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "points": "356:400;356:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzxcVv7wpA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzxcVv8NxM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzxcVv9X58=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKz3OVwLl+8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwMNB4=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 357, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwNd3E=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 357, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwODiI=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 358, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "points": "416:448;416:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKz3OVwMNB4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKz3OVwNd3E=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKz3OVwODiI=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKz9mVwcos8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVwdsGc=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 391, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVweYvs=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 391, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVwfOSk=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 392, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "points": "484:496;484:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKz9mVwdsGc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKz9mVweYvs=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKz9mVwfOSk=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4k1VxFxwI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxGUvg=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 161, + "top": 333, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxHABk=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 161, + "top": 348, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxIpIg=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 162, + "top": 303, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "points": "184:324;140:324", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4k1lxGUvg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4k1lxHABk=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4k1lxIpIg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4o4VxWQBI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxXVGc=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 195, + "top": 378, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxYgZc=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 195, + "top": 393, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxZqsQ=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 196, + "top": 348, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "points": "252:369;140:369", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4o4VxXVGc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4o4VxYgZc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4o4VxZqsQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4tiVxnpno=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxoTEk=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 227, + "top": 429, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxpG0I=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 227, + "top": 444, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxqKIY=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 228, + "top": 399, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "points": "316:420;140:420", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4tiVxoTEk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4tiVxpG0I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4tiVxqKIY=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK41YVx4sZw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx5rZ4=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 259, + "top": 473, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx6mfE=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 259, + "top": 488, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx7lFo=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 443, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "points": "380:464;140:464", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK41YVx5rZ4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK41YVx6mfE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK41YVx7lFo=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK47MFyJhkk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MFyKeH8=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 289, + "top": 521, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MVyL2Gg=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 289, + "top": 536, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MVyMJyk=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 290, + "top": 491, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "points": "440:512;140:512", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK47MFyKeH8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK47MVyL2Gg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK47MVyMJyk=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK5AeFyarms=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeFybX8s=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 185, + "top": 229, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeFycm2c=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 185, + "top": 244, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeVydbSU=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 186, + "top": 199, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "points": "232:220;140:220", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK5AeFybX8s=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK5AeFycm2c=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK5AeVydbSU=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwK/k1ly1mNU=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwK/k1ly236Y=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "model": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k1ly3kes=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 385, + "top": 585, + "width": 132, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k1ly4Kb0=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 385, + "top": 599, + "width": 132, + "height": 12, + "text": "UMLBehavioralFeature" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k11y5jis=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 972, + "top": 60, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k11y6pH4=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 972, + "top": 60, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 580, + "width": 142, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK/k1ly3kes=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwK/k1ly4Kb0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwK/k11y5jis=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK/k11y6pH4=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 580, + "width": 142, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLBdPFzSzQk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqFkkF9pQ=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLBdPFzT/sk=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzUtqg=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 589, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzVTVM=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 603, + "width": 72.51593017578125, + "height": 12, + "text": "Destroy" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzWXGg=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": 24, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzX7Kw=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": 24, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 584, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLBdPFzUtqg=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLBdPFzVTVM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLBdPFzWXGg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLBdPFzX7Kw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLBdPFzYl0A=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 632, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLBdPFzZMKQ=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 632, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLBdPFzaqUA=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 80, + "top": 16, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 584, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLBdPFzYl0A=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLBdPFzZMKQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqFkkF9pQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLBdPFzaqUA=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLDMaFz6CG0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz7zuA=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 579, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz8JJ4=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 564, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz92bU=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 609, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "tail": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "points": "318:600;380:600", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLDMaFz7zuA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLDMaFz8JJ4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLDMaFz92bU=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLFUbV0ScDI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqF0kiyCM=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLFUbV0TTdY=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0UvYs=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 209, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0V4oU=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 223, + "width": 72.51593017578125, + "height": 12, + "text": "Auxiliary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0WLEA=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -336, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0XEPg=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -336, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 204, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLFUbV0UvYs=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLFUbV0V4oU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLFUbV0WLEA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLFUbV0XEPg=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLFUbV0YxWc=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 128, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLFUbV0Z3Xk=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 128, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLFUbV0aLJo=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -224, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 204, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLFUbV0YxWc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLFUbV0Z3Xk=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqF0kiyCM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLFUbV0aLJo=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLFu9F06sWk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGEk49nc=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLFu9F07mo0=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F08FIY=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 261, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F09Ig0=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 275, + "width": 72.51593017578125, + "height": 12, + "text": "Focus" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F0+sYU=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -420, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F0/2cA=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -420, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 256, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLFu9F08FIY=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLFu9F09Ig0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLFu9F0+sYU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLFu9F0/2cA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLFu9F1A690=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 152, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLFu9F1BAsU=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 152, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLFu9F1CLR8=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -280, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 256, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLFu9F1A690=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLFu9F1BAsU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGEk49nc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLFu9F1CLR8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLF4tF1iftI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGUlOO9I=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLF4tF1jr/w=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1kg2Y=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 313, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1la4E=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 327, + "width": 72.51593017578125, + "height": 12, + "text": "Metaclass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1mW9o=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -480, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1ngPk=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -480, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLF4tF1kg2Y=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLF4tF1la4E=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLF4tF1mW9o=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLF4tF1ngPk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLF4tF1oP5U=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 184, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLF4tF1pEYI=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 184, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLF4tF1qaMM=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -320, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLF4tF1oP5U=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLF4tF1pEYI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGUlOO9I=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLF4tF1qaMM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLF/G12KFPg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGUlk1Tc=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLF/G12LESY=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12MFWs=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 365, + "width": 121, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12Nq6M=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 379, + "width": 121, + "height": 12, + "text": "ImplementationClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12OWK0=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -564, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12PipY=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -564, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 360, + "width": 131, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLF/G12MFWs=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLF/G12Nq6M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLF/G12OWK0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLF/G12PipY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLF/G12QJs8=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 208, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLF/G12Rf8c=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 208, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLF/HF2Sm8E=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -376, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 360, + "width": 131, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLF/G12QJs8=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLF/G12Rf8c=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGUlk1Tc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLF/HF2Sm8E=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLGEPF2y6SI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqHEl6Zbo=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLGEPF2zyUI=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF20OuI=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 421, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF21TcM=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 435, + "width": 72.51593017578125, + "height": 12, + "text": "Type" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF22f/8=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -624, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF23oz0=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -624, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 416, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLGEPF20OuI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLGEPF21TcM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLGEPF22f/8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLGEPF23oz0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLGEPF24D5Y=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 244, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLGEPF252Tg=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 244, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLGEPF26r38=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -416, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 416, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLGEPF24D5Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLGEPF252Tg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqHEl6Zbo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLGEPF26r38=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLGI813a/Lo=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqHEmQAJ4=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLGI813bmDw=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3c6dc=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 477, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3dgjo=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 491, + "width": 72.51593017578125, + "height": 12, + "text": "Utility" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3eWQw=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -672, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3fVUI=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -672, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 472, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLGI9F3c6dc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLGI9F3dgjo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLGI9F3eWQw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLGI9F3fVUI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLGI9F3g9+w=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 284, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLGI9F3hmIE=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 284, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLGI9F3i+8k=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -448, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 472, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLGI9F3g9+w=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLGI9F3hmIE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqHEmQAJ4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLGI9F3i+8k=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNej158NLk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej1590I0=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 233, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej15+8jc=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 248, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej15/BRY=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 203, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "points": "720:224;652:224", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNej1590I0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNej15+8jc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNej15/BRY=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNkZ16NQ/Q=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16OhBQ=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 281, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16PBtY=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 296, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16QvLQ=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 251, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "points": "720:272;652:272", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNkZ16OhBQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNkZ16PBtY=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNkZ16QvLQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNn916eDZQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916fvYQ=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 333, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916guUU=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 348, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916hjhM=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 303, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "points": "720:324;652:324", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNn916fvYQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNn916guUU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNn916hjhM=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNr116vKpE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116weUM=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 385, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116xjvo=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 400, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116yGN0=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 355, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "points": "720:376;652:376", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNr116weUM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNr116xjvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNr116yGN0=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNvdl7AF7U=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17Byl0=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 442, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17Cmyo=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 457, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17DduQ=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 412, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "points": "720:433;652:433", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNvd17Byl0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNvd17Cmyo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNvd17DduQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLN0fl7RscA=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0fl7SzeE=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 498, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0fl7Tq3c=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 513, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0f17UptI=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 468, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "points": "720:489;652:489", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLN0fl7SzeE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLN0fl7Tq3c=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLN0f17UptI=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwLRECl7stC8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLRECl7tsQE=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7u5vE=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 545, + "width": 92.85594177246094, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7vrCk=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 559, + "width": 92.85594177246094, + "height": 12, + "text": "UMLComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7wqHs=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7xJrI=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 540, + "width": 102.85594177246094, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLRECl7u5vE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLRECl7vrCk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLRECl7wqHs=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLRECl7xJrI=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 540, + "width": 102.85594177246094, + "height": 261, + "nameCompartment": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLR8CV8I99Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqH0nfZIU=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLR8CV8JFWY=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8Knxc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 549, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8LWIw=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 563, + "width": 72.51593017578125, + "height": 12, + "text": "Entity" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8Mvqc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8NdIc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 544, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLR8CV8Knxc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLR8CV8LWIw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLR8CV8Mvqc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLR8CV8NdIc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLR8CV8OpVY=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 748, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLR8CV8PW8k=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 748, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLR8Cl8QCTM=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 336, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 544, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLR8CV8OpVY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLR8CV8PW8k=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqH0nfZIU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLR8Cl8QCTM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSByF8w+gI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIEn1Irc=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSByF8x/Yc=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF8yMLo=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 597, + "width": 88.67578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF8zspI=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 611, + "width": 88.67578125, + "height": 12, + "text": "Implementation" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF80AnU=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 420, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF81b24=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 420, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 592, + "width": 98.67578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSByF8yMLo=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSByF8zspI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSByF80AnU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSByF81b24=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSByF82e10=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 768, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSByF83aE4=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 768, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSByF84G88=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 280, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 592, + "width": 98.67578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSByF82e10=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSByF83aE4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIEn1Irc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSByF84G88=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSIN19Ytdk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIUoLdrY=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSIN19ZQ0U=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9a8kE=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 653, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9bYBg=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 667, + "width": 72.51593017578125, + "height": 12, + "text": "Process" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9cqZQ=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 348, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9dI5U=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 348, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 648, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSIOF9a8kE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSIOF9bYBg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSIOF9cqZQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSIOF9dI5U=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSIOF9ekq0=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 800, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSIOF9fibc=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 800, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSIOF9gUN0=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 232, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 648, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSIOF9ekq0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSIOF9fibc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIUoLdrY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSIOF9gUN0=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSO/1+AoeQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIkohl1g=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSO/1+BWGA=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSO/1+CG1s=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 709, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSO/1+DoUc=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 723, + "width": 72.51593017578125, + "height": 12, + "text": "Service" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSPAF+EVIo=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 312, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSPAF+FZR8=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 312, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 704, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSO/1+CG1s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSO/1+DoUc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSPAF+EVIo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSPAF+FZR8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSPAF+GnaI=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 844, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSPAF+Ho/s=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 844, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSPAF+I3E8=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 704, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSPAF+GnaI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSPAF+Ho/s=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIkohl1g=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSPAF+I3E8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSXP1+o0Kw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIko3HYE=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSXP1+peko=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+qR3g=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 765, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+rnfg=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 779, + "width": 72.51593017578125, + "height": 12, + "text": "Subsystem" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+sqCM=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+t4Mc=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 760, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSXP1+qR3g=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSXP1+rnfg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSXP1+sqCM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSXP1+t4Mc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSXP1+uKrA=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 880, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSXP1+vdxM=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 880, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSXP1+woFc=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 760, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSXP1+uKrA=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSXP1+vdxM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIko3HYE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSXP1+woFc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLV9gV/Ybio=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gV/Z8CU=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 569, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gl/a23I=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 584, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gl/b3BU=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 539, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "points": "720:560;658:560", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLV9gV/Z8CU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLV9gl/a23I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLV9gl/b3BU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWA0V/pWEg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/q2AI=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 621, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/rrYc=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 636, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/spgM=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 591, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "points": "720:612;658:612", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWA0V/q2AI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWA0V/rrYc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWA0V/spgM=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWEUV/6d1E=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/78Ig=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 677, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/8eIM=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 692, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/9T0A=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 647, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "points": "720:668;658:668", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWEUV/78Ig=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWEUV/8eIM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWEUV/9T0A=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWIQWALE8M=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWAMDo8=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 737, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWANo/A=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 752, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWAO6qA=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 707, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "points": "720:728;658:728", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWIQWAMDo8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWIQWANo/A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWIQWAO6qA=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWMgWAcaQw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAd1rc=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 789, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAeZ8k=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 804, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAfxqc=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 759, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "points": "720:780;658:780", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWMgWAd1rc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWMgWAeZ8k=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWMgWAfxqc=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwL2WeWA5NQI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL2WeGA460g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL2WeWA62bI=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "model": { + "$ref": "AAAAAAFFwL2WeGA460g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA7mnk=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 61, + "top": 649, + "width": 98, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA8/Wk=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 61, + "top": 663, + "width": 98, + "height": 12, + "text": "UMLDependency" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA9NaM=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 144, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA+CiM=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 144, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 56, + "top": 644, + "width": 108, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL2WeWA7mnk=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL2WeWA8/Wk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL2WeWA9NaM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL2WeWA+CiM=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 56, + "top": 644, + "width": 108, + "height": 277, + "nameCompartment": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL4D0mBZIkY=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJkp/rUc=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL4D0mBaqmw=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D0mBbBNE=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 649, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D0mBc7go=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 663, + "width": 69.380859375, + "height": 12, + "text": "Create" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D02Bd3+g=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D02BeWA8=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 644, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL4D0mBbBNE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL4D0mBc7go=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL4D02Bd3+g=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL4D02BeWA8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL4D02Bf0q0=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 664, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL4D02BgYs8=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 664, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL4D02BhsHw=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 644, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL4D02Bf0q0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL4D02BgYs8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJkp/rUc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL4D02BhsHw=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL4h4WCCAAY=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJ0qVBvA=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL4h4WCD82Y=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCE1YI=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 713, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCFbHY=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 727, + "width": 69.380859375, + "height": 12, + "text": "Call" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCG+Bo=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCHhD8=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 708, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL4h4mCE1YI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL4h4mCFbHY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL4h4mCG+Bo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL4h4mCHhD8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL4h4mCIEqs=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 708, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL4h4mCJktQ=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 708, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL4h4mCKdqI=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 708, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL4h4mCIEqs=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL4h4mCJktQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJ0qVBvA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL4h4mCKdqI=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL45WWCr3cU=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJ0qrDxY=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL45WWCsDkc=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCtTBI=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 769, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCuTW0=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 783, + "width": 69.380859375, + "height": 12, + "text": "Instantiate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCv18Q=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -192, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCwZzE=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -192, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 764, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL45WWCtTBI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL45WWCuTW0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL45WWCv18Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL45WWCwZzE=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL45WWCxsuk=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 736, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL45WmCy+mU=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 736, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL45WmCzW1Y=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -128, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 764, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL45WWCxsuk=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL45WmCy+mU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJ0qrDxY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL45WmCzW1Y=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL5hQGDUxa0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKErBHOc=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL5hQGDVSBg=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDWrwI=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 825, + "width": 82.013671875, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDXPFU=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 839, + "width": 82.013671875, + "height": 12, + "text": "Responsibility" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDYpi0=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDZAt8=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 820, + "width": 92.013671875, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL5hQGDWrwI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL5hQGDXPFU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL5hQGDYpi0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL5hQGDZAt8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL5hQGDa1nY=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 772, + "width": 91, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL5hQGDbixI=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 772, + "width": 91, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL5hQGDcuS4=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 820, + "width": 92.013671875, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL5hQGDa1nY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL5hQGDbixI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKErBHOc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL5hQGDcuS4=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL7KdWEqew0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKErXxgY=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL7KdWEr60A=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEspPc=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 881, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEt7g0=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 895, + "width": 69.380859375, + "height": 12, + "text": "Send" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEum1Q=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -324, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEv3Yk=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -324, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 876, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL7KdWEspPc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL7KdWEt7g0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL7KdWEum1Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL7KdWEv3Yk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL7KdWEwzHc=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 804, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL7KdWExRWs=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 804, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL7KdWEyL0Q=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -216, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 876, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL7KdWEwzHc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL7KdWExRWs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKErXxgY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL7KdWEyL0Q=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+LCGFgCjw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFhp5w=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 634, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFihK4=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 619, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFjcmE=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 664, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "tail": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "points": "314:655;380:655", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+LCGFhp5w=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+LCGFihK4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+LCGFjcmE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+O8GFxUF4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GFyCzY=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 677, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GFzT+A=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 692, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GF0qhg=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 647, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "points": "236:668;163:668", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+O8GFyCzY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+O8GFzT+A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+O8GF0qhg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+SkWGC/a4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGDbeA=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 731, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGEkxM=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 746, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGFVnU=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 701, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "points": "236:722;163:722", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+SkWGDbeA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+SkWGEkxM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+SkWGFVnU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+WL2GTesQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GUDZ4=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 797, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GVfH8=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 812, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GW4Ys=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 767, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "points": "236:788;163:788", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+WL2GUDZ4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+WL2GVfH8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+WL2GW4Ys=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+Z72GkT5Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72GllyU=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 854, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72Gm6K8=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 869, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72GnawI=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 824, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "points": "236:845;163:845", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+Z72GllyU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+Z72Gm6K8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+Z72GnawI=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+eh2G1gXM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G2oXg=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 910, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G3GpE=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 925, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G4woY=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 880, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "points": "236:901;163:901", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+eh2G2oXg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+eh2G3GpE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+eh2G4woY=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwMFq1GHZe+E=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMFq1GHa5CM=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "model": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHbxIU=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 33, + "width": 93, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHc3zA=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 47, + "width": 93, + "height": 12, + "text": "UMLAbstraction" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHdTFI=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHeicg=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 28, + "width": 103, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMFq1GHbxIU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMFq1GHc3zA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMFq1GHdTFI=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMFq1GHeicg=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 28, + "width": 103, + "height": 153, + "nameCompartment": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGle2H29zI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKksmed8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGle2H3I+8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H4B8s=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 29, + "width": 110.396484375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H5FWo=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 43, + "width": 110.396484375, + "height": 12, + "text": "Derive" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H6wQw=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H7ifs=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 24, + "width": 120.396484375, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGle2H4B8s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGle2H5FWo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGle2H6wQw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGle2H7ifs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGle2H8ZWU=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFFwMJPAWJ40Vg=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H8ZWU=" + }, + "model": { + "$ref": "AAAAAAFFwMJO92J1Y/s=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 65, + "width": 110.396484375, + "height": 12, + "text": "+computation: String", + "horizontalAlignment": 0 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 60, + "width": 127.16787719726562, + "height": 22 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGle2H9VL8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 824, + "top": 60, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGle2H+hpQ=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 24, + "width": 120.396484375, + "height": 58, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGle2H8ZWU=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGle2H9VL8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKksmed8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGle2H+hpQ=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGo6mIepMc=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqK0s9CwU=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGo6mIfS5g=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIgcys=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 101, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIha40=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 115, + "width": 69.380859375, + "height": 12, + "text": "Refine" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIiGvE=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 276, + "top": 120, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIjVCs=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 276, + "top": 120, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 96, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGo6mIgcys=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGo6mIha40=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGo6mIiGvE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGo6mIjVCs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGo6mIkY0Y=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 832, + "top": 172, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGo6mIlYhc=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 832, + "top": 172, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGo6mImbZE=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 80, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 96, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGo6mIkY0Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGo6mIlYhc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqK0s9CwU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGo6mImbZE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGrimJGJ0s=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqK0tTuyw=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGrimJHZ7Y=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJIfxU=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 153, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJJ7uc=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 167, + "width": 69.380859375, + "height": 12, + "text": "Trace" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJKI9M=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 324, + "top": 168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJL3ag=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 324, + "top": 168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 148, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGrimJIfxU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGrimJJ7uc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGrimJKI9M=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGrimJL3ag=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGrimJMCIQ=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 848, + "top": 240, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGrimJNPbE=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 848, + "top": 240, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGrimJOkXc=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 112, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 148, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGrimJMCIQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGrimJNPbE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqK0tTuyw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGrimJOkXc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLTm2KEAI0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KFRRg=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 61, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KGrkQ=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 76, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KHZTE=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 31, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "points": "740:52;658:52", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLTm2KFRRg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLTm2KGrkQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLTm2KHZTE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLXQmKVDuM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKW+3c=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 121, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKXpUQ=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 136, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKYWOg=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 91, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "points": "740:112;658:112", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLXQmKW+3c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLXQmKXpUQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLXQmKYWOg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLbmmKmAvI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKnMuM=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 169, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKonTw=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 184, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKpbLQ=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 139, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "points": "740:160;658:160", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLbmmKnMuM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLbmmKonTw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLbmmKpbLQ=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwMYNEWK8jeA=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMYNEWK9Wb8=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "model": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWK++fU=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 833, + "width": 91, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWK/PY8=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 847, + "width": 91, + "height": 12, + "text": "UMLPackage" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWLAHjA=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWLBm9I=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 828, + "width": 101, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMYNEWK++fU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMYNEWK/PY8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMYNEWLAHjA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMYNEWLBm9I=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 828, + "width": 101, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMdnrWLZAY8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqLUuNRhM=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMdnrWLaXkY=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLbib0=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 729, + "top": 837, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLclU4=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 729, + "top": 851, + "width": 72.51593017578125, + "height": 12, + "text": "Framework" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLdBNU=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLeF4I=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 832, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMdnrmLbib0=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMdnrmLclU4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMdnrmLdBNU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMdnrmLeF4I=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMdnrmLf950=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 868, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMdnrmLgzek=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 878, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMdnrmLhmpQ=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 832, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMdnrmLf950=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMdnrmLgzek=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqLUuNRhM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMdnrmLhmpQ=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMeIHGMCTCk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqLUujT3E=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMeIHGMDiPY=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMEN4g=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 729, + "top": 893, + "width": 75.345703125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMFxQc=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 729, + "top": 907, + "width": 75.345703125, + "height": 12, + "text": "ModelLibrary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMG6CQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -60, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMH2dQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -60, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 888, + "width": 85.345703125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMeIHGMEN4g=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMeIHGMFxQc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMeIHGMG6CQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMeIHGMH2dQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMeIHGMI7hI=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 904, + "width": 85, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMeIHGMJi90=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 914, + "width": 85, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMeIHGMK1pc=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -40, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 888, + "width": 85.345703125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMeIHGMI7hI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMeIHGMJi90=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqLUujT3E=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMeIHGMK1pc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMevo2Mq4Ew=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2Mr7wQ=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 861, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2Msv/w=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 876, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2MtL5c=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 690, + "top": 831, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "tail": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "points": "724:852;656:852", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMevo2Mr7wQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMevo2Msv/w=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMevo2MtL5c=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMe0G2M7rmg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M8gls=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 917, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M9WEg=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 932, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M+CD8=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 690, + "top": 887, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "tail": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "points": "724:908;656:908", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMe0G2M8gls=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMe0G2M9WEg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMe0G2M+CD8=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFElnFrT1S7Kic=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLClassifier" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFElnF1nFTY/Sw=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Realization", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFElnGGLFUFZFA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "source": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "target": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFElnF1nFTZHOU=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFElnJRglVKSoc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Specification", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFElnKVuVV4pBU=", + "_parent": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "source": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "target": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFElnJRglVLifA=", + "_parent": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFJsYgDTM+Z6E=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "entity", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFJsZx3DOCac8=", + "_parent": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "source": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFJsYgDTM/qY8=", + "_parent": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "width": 40, + "height": 40, + "content": "var w = rect.getWidth(),\n m = w / 10;\ncanvas.fillEllipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.ellipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.line(rect.x1 + m, rect.y2 - m, rect.x2 - m, rect.y2 - m);\n" + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFJsZbpDNobIs=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLClass" + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwKqhJFq06mA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLArtifact" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKsvdVrRJUQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "File", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK5AeFyZpVg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "source": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "isAbstract": true, + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKsvdVrSLo0=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKtwS1r6wew=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Document", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzkslvX4gU=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "source": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4k1VxEEpM=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "source": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKtwS1r7XqE=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuBulsidLQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Executable", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzsCVvo11g=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4o4VxVx00=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuBulsjhp0=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuIMltKnQQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Library", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzxcVv56Dg=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4tiVxmVJM=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuIMltLkmg=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuS0ltysPk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Script", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKz3OVwK9hs=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "source": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK41YVx3Hr0=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "source": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuS0ltz9pw=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKueMVuaLXM=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Source", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKz9mFwbfDg=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "source": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK47MFyIL/c=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "source": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKueMlubedY=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwK/k1ly00Ec=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLBehavioralFeature" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLBdO1zQosE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Destroy", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLDMaFz5C14=", + "_parent": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "source": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "target": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLBdO1zR7Ak=", + "_parent": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLFUbV0QQVA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Auxiliary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNej157D6Y=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "source": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLFUbV0RoPU=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLFu8104he4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Focus", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNkZ16Mp7Y=", + "_parent": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "source": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLFu9F05JGE=", + "_parent": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLF4tF1g4No=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Metaclass", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNn916d4Yc=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "source": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLF4tF1h94I=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLF/G12IJ54=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "ImplementationClass", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNr116u93k=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "source": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLF/G12JIns=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLGEO12wqJ8=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Type", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNvdl6/WJI=", + "_parent": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "source": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLGEPF2x7bg=", + "_parent": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLGI813YL3s=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Utility", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLN0fl7QL9o=", + "_parent": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "source": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLGI813ZPxY=", + "_parent": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFFwLKxU14QPaE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Robustness Stereotypes", + "ownedViews": [ + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLL0NF4VWXk=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMEwRREE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLL0NF4WzoE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4X88I=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 89, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4YSt8=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 103, + "width": 72.51593017578125, + "height": 12, + "text": "entity" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4ZQaQ=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -1065, + "top": -270, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4asxs=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -1065, + "top": -270, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 84, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLL0NF4X88I=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLL0NF4YSt8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLL0NF4ZQaQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLL0NF4asxs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLL0NF4bgXg=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 92, + "top": -28, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLL0NF4cZ88=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 92, + "top": -18, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLL0NF4dJaE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -710, + "top": -180, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 84, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLL0NF4bgXg=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLL0NF4cZ88=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMEwRREE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLL0NF4dJaE=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwLMO8l44tWU=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLMO8l45ook=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l46Nac=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 33, + "top": 33, + "width": 79, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l47xu4=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 33, + "top": 47, + "width": 79, + "height": 12, + "text": "UMLClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l48V+s=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -489, + "top": -414, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l490+g=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -489, + "top": -414, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 28, + "top": 28, + "width": 89, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLMO8l46Nac=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLMO8l47xu4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLMO8l48V+s=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLMO8l490+g=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 28, + "top": 28, + "width": 89, + "height": 149, + "nameCompartment": { + "$ref": "AAAAAAFFwLMO8l45ook=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLMO814+17w=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO814/vLk=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 109, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO815A2sw=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 124, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO815BAcU=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 79, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "points": "212:100;116:100", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLMO814/vLk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLMO815A2sw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLMO815BAcU=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwx8Q/35wG9A=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMUw9MBk=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwx8Q/35xpyY=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/35yVU8=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 37, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/35z0VE=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 51, + "width": 72.51593017578125, + "height": 12, + "text": "control" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/3506PU=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -336, + "top": -312, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/351cP0=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -336, + "top": -312, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 32, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwx8Q/35yVU8=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwx8Q/35z0VE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwx8Q/3506PU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwx8Q/351cP0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwx8RAH52xko=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 76, + "top": -4, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwx8RAH53MWs=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 76, + "top": 6, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwx8RAH54kik=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -224, + "top": -208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 32, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwx8RAH52xko=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwx8RAH53MWs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMUw9MBk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwx8RAH54kik=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwyAHeH6a9yk=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6b9JY=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 61, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6cKyY=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 76, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6dvIk=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 31, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "points": "212:52;116:52", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwyAHeX6b9JY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwyAHeX6cKyY=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwyAHeX6dvIk=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFw0h1/QXNqo4=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMkxa+TA=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFw0h1/gXOBI4=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXPA/w=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 141, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXQ/LI=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 155, + "width": 72.51593017578125, + "height": 12, + "text": "boundary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXRrB4=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -360, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXSVgA=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -360, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 136, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFw0h1/gXPA/w=" + }, + "nameLabel": { + "$ref": "AAAAAAFFw0h1/gXQ/LI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFw0h1/gXRrB4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFw0h1/gXSVgA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFw0h1/gXTCRY=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -20, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFw0h1/gXUu1g=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -10, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFw0h1/gXVEL8=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 64, + "top": -240, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 136, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFw0h1/gXTCRY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFw0h1/gXUu1g=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMkxa+TA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFw0h1/gXVEL8=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFw0o5p5IVMGM=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IW5Js=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 165, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IXSKA=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 180, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IY/GE=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 135, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "points": "212:156;116:156", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFw0o5p5IW5Js=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFw0o5p5IXSKA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFw0o5p5IY/GE=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwLRECl7r1R4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLComponent" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLR8CF8G68k=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Entity", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLV9gV/Xhk4=", + "_parent": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "source": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLR8CF8HOik=", + "_parent": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSByF8umMo=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Implementation", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWA0V/olVk=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "source": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSByF8vzKA=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSIN19WMnE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Process", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWEUV/5Qq4=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "source": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSIN19XVng=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSO/19+cMY=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Service", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWIQWAKKPo=", + "_parent": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "source": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSO/19/YUk=", + "_parent": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSXP1+mTVk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Subsystem", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWMgWAb2Sk=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "source": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSXP1+njeI=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwL2WeGA460g=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLDependency" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL4D0mBXwu4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Create", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+LCGFfPQs=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "source": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "target": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+O8GFwbog=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "source": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL4D0mBYXVU=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL4h4WCAEkg=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Call", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+SkWGBCOg=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "source": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL4h4WCBKPU=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL45WWCpJ0o=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Instantiate", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+WL2GScgY=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "source": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL45WWCq/8I=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL5hP2DSEFk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Responsibility", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+Z72GjzGw=", + "_parent": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "source": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL5hQGDTCjI=", + "_parent": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL7KdWEoDhA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Send", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+eh2G01aU=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "source": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL7KdWEpx8M=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwMFq1GHYSKM=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLAbstraction" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGlemH0Tq8=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Derive", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLTmmKDF1M=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "source": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFFwMJO92J1Y/s=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "name": "computation", + "type": "String" + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGlemH1M8k=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGo6mIcITc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Refine", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLXQmKUyu0=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "source": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGo6mIdBMU=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGrimJEvvk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Trace", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLbmmKloGE=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "source": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGrimJF+z8=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwMYNEWK7ItA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLPackage" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMdnrWLXWLA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Framework", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMevo2MpIU4=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "source": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "target": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMdnrWLYFcM=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMeIHGMAPDc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "ModelLibrary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMe0G2M69PQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "source": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "target": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMeIHGMBKKk=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFFwQCuI7bLjDk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "StandardProfileL3", + "ownedViews": [ + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwQHC9rbwK6A=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQHC9rbx7Lo=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "model": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rbyTUQ=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 45, + "top": 121, + "width": 107, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rbzlgQ=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 45, + "top": 135, + "width": 107, + "height": 12, + "text": "UMLModel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rb0L9g=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rb1XIk=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 116, + "width": 117, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQHC9rbyTUQ=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQHC9rbzlgQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQHC9rb0L9g=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQHC9rb1XIk=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 116, + "width": 117, + "height": 97, + "nameCompartment": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQHjjbcLQPM=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqN0zJrS0=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQHjjbcMlRY=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcNrIk=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 41, + "width": 115, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcOnWs=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 55, + "width": 115, + "height": 12, + "text": "BuildComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcPLIM=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcQOtc=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 36, + "width": 125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQHjjbcNrIk=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQHjjbcOnWs=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQHjjbcPLIM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQHjjbcQOtc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQHjjrcRsYI=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 56, + "width": 105, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQHjjrcSCoc=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 66, + "width": 105, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQHjjrcTWEY=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 36, + "width": 125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQHjjrcRsYI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQHjjrcSCoc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqN0zJrS0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQHjjrcTWEY=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQIPLLc0Q7M=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqOEzfvr8=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQIPLLc1jrg=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc2rps=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 121, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc3wdo=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 135, + "width": 83, + "height": 12, + "text": "Metamodel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc4SHA=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -84, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc5Qvc=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -84, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 116, + "width": 93, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQIPLLc2rps=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQIPLLc3wdo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQIPLLc4SHA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQIPLLc5Qvc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQIPLLc63qc=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 124, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQIPLbc7y2w=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 134, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQIPLbc8jC8=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -56, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 116, + "width": 93, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQIPLLc63qc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQIPLbc7y2w=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqOEzfvr8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQIPLbc8jC8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQIrDLddK/I=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqOEz1SWk=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQIrDLdevJE=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdfcec=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 181, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdgsTM=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 195, + "width": 83, + "height": 12, + "text": "SystemModel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdhAR0=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdiiuQ=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 176, + "width": 93, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQIrDLdfcec=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQIrDLdgsTM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQIrDLdhAR0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQIrDLdiiuQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQIrDLdjYt8=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 264, + "top": 156, + "width": 88, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQIrDLdkEoo=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 264, + "top": 166, + "width": 88, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQIrDLdlkbo=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 80, + "top": -112, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 176, + "width": 93, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQIrDLdjYt8=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQIrDLdkEoo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqOEz1SWk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQIrDLdlkbo=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQLOH7eRZzI=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOH7eSzo8=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 145, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOILeTl4U=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 160, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOILeU1qE=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 115, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "tail": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "points": "224:136;156:136", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQLOH7eSzo8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQLOILeTl4U=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQLOILeU1qE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQLSp7eim6s=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7ejdqM=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 205, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7ekT+I=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 220, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7el67w=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 175, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "tail": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "points": "224:196;156:196", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQLSp7ejdqM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQLSp7ekT+I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQLSp7el67w=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwQdYRLfPnZs=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQdYRLfQc8o=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfPnZs=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfRm/U=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 45, + "top": 41, + "width": 107, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfSwyU=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 45, + "top": 55, + "width": 107, + "height": 12, + "text": "UMLComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfTyV4=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -702, + "top": -954, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfUafY=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -702, + "top": -954, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 36, + "width": 117, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQdYRLfRm/U=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQdYRLfSwyU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQdYRLfTyV4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQdYRLfUafY=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 36, + "width": 117, + "height": 41, + "nameCompartment": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQgwnLf7u0w=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnLf82nE=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 64, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnbf9bFo=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 79, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnbf+ckE=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 34, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQdYRLfPnZs=" + }, + "tail": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "lineStyle": 1, + "points": "223:55;157:55", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQgwnLf82nE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQgwnbf9bFo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQgwnbf+ckE=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwQHC9rbvUkk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLModel" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQHjjbcJ4Ks=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "BuildComponent", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQgwnLf6Q+0=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "source": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQHjjbcKYjk=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQIPLLcykEY=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Metamodel", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQLOH7eQuvE=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "source": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "target": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQIPLLcz/1A=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQIrDLdbTko=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "SystemModel", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQLSp7eh5o0=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "source": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "target": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQIrDLdcjKw=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwx8Q/35u/80=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "control", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwyAHeH6Znas=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "source": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwx8Q/35vMf0=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "width": 40, + "height": 40, + "content": "var w = rect.getWidth(),\n h = w / 2,\n m = w / 8;\ncanvas.fillEllipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.ellipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.line(rect.x1 + h, rect.y1 + m, rect.x1 + h + m, rect.y1);\ncanvas.line(rect.x1 + h, rect.y1 + m, rect.x1 + h + m, rect.y1 + 2 * m);\n" + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFw0h1/QXL978=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "boundary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFw0o5ppIUB2s=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "source": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFw0h1/QXM/ss=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "width": "50", + "height": 40, + "content": "var w = rect.getWidth(),\n h = rect.getHeight(),\n m = w / 5;\ncanvas.fillEllipse(rect.x1 + m, rect.y1, rect.x2, rect.y2);\ncanvas.ellipse(rect.x1 + m, rect.y1, rect.x2, rect.y2);\ncanvas.line(rect.x1, rect.y1, rect.x1, rect.y2);\ncanvas.line(rect.x1, rect.y1 + h/2, rect.x1 + m, rect.y1 + h/2);\n" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/app/doc/状态机.mdj b/app/doc/状态机.mdj new file mode 100644 index 0000000..5f1212f --- /dev/null +++ b/app/doc/状态机.mdj @@ -0,0 +1,45155 @@ +{ + "_type": "Project", + "_id": "AAAAAAFElm5XMFNoGY0=", + "name": "Untitled", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFElm6BOFNpegQ=", + "_parent": { + "$ref": "AAAAAAFElm5XMFNoGY0=" + }, + "name": "Model", + "ownedElements": [ + { + "_type": "UMLUseCaseDiagram", + "_id": "AAAAAAF5P5m6Qk1jVXQ=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseDiagram1", + "ownedViews": [ + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5nMr01oLTI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5nMr01pxLs=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01qZlQ=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 4528, + "top": 672, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01rWkA=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "font": "Arial;13;1", + "left": 2284, + "top": 347.5, + "width": 62, + "height": 13, + "text": "check2C" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01srVY=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 4528, + "top": 672, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01tKAI=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 4528, + "top": 672, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2279, + "top": 340.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5nMr01qZlQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5nMr01rWkA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5nMr01srVY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5nMr01tKAI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5nMr01u10s=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5nMr01vn/8=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5nMr01wvTc=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5nMr01xNvU=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5nMr01yEgM=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2264, + "top": 336, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5nMr01u10s=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5nMr01vn/8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5nMr01wvTc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5nMr01xNvU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5nMr01yEgM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P5saWE3J2FY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3K1ts=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "font": "Arial;13;0", + "left": 2186, + "top": 446, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3LIi0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2224, + "top": 458, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3M7xA=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2196, + "top": 423, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3NmNI=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2281, + "top": 393, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3Oy1k=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2287, + "top": 404, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3PZiY=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2267, + "top": 368, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3QKR0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2149, + "top": 500, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3RVpc=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2159, + "top": 509, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3S3i0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2128, + "top": 481, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5saWE3TepE=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2152, + "top": 160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5saWE3U3g4=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2152, + "top": 160, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "tail": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "lineStyle": 1, + "points": "2292:371;2120:511", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P5saWE3K1ts=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5saWE3LIi0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5saWE3M7xA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P5saWE3NmNI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P5saWE3Oy1k=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P5saWE3PZiY=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P5saWE3QKR0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P5saWE3RVpc=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P5saWE3S3i0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P5saWE3TepE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P5saWE3U3g4=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P56LZE6M/G8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P56LZE6NeNY=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6OE2I=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6PKW0=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 205, + "top": 283.5, + "width": 103, + "height": 13, + "text": "【用户选择操作】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6QSXM=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6RMmU=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 200, + "top": 276.5, + "width": 114, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P56LZE6OE2I=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P56LZE6PKW0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P56LZE6QSXM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P56LZE6RMmU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P56LZE6SLIg=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P56LZE6TWFg=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P56LZE6U8ts=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P56LZE6VNIk=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P56LZE6W1sE=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 176, + "top": 272, + "width": 161, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P56LZE6SLIg=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P56LZE6TWFg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P56LZE6U8ts=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P56LZE6VNIk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P56LZE6W1sE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P56tgE7IY7E=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7JO9U=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "font": "Arial;13;0", + "left": 1216, + "top": 36, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7Kkjk=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1252, + "top": 51, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7LlPE=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1251, + "top": 7, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7MSF4=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2273, + "top": 317, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7NsLs=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2261, + "top": 323, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7OBww=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2298, + "top": 304, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7PoMY=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 296, + "top": 253, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7Q0NM=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 308, + "top": 259, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7RtW8=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 271, + "top": 240, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P56tgE7SCeE=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P56tgE7TSmw=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "tail": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "lineStyle": 1, + "points": "2301:335;2064:16;440:40;269:271", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P56tgE7JO9U=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P56tgE7Kkjk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P56tgE7LlPE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P56tgE7MSF4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P56tgE7NsLs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P56tgE7OBww=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P56tgE7PoMY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P56tgE7Q0NM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P56tgE7RtW8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P56tgE7SCeE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P56tgE7TSmw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5/CAk98zZc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5/CAk99r9g=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA09+uJY=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1056, + "top": -208, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA09/h4M=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "font": "Arial;13;1", + "left": 1260, + "top": 395.5, + "width": 62, + "height": 13, + "text": "Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA0+AvMQ=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1056, + "top": -208, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA0+BODA=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1056, + "top": -208, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1255, + "top": 388.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5/CA09+uJY=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5/CA09/h4M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5/CA0+AvMQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5/CA0+BODA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5/CA0+CFD4=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5/CA0+DO7Q=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5/CA0+EZ7w=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5/CA0+FMSM=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5/CA0+GOcA=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1240, + "top": 384, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5/CA0+CFD4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5/CA0+DO7Q=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5/CA0+EZ7w=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5/CA0+FMSM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5/CA0+GOcA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P5/ask/ENuY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/FCi8=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "font": "Arial;13;0", + "left": 514, + "top": 360, + "width": 124.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1, + "text": "+选择忽略or重测目标" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/GmBY=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 580, + "top": 346, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/H9Os=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 567, + "top": 389, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/ITgo=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 347, + "top": 293, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/J3dw=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 353, + "top": 281, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/KH+Q=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 335, + "top": 319, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/LwxI=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 806, + "top": 427, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/MCSM=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 807, + "top": 413, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/N7rw=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 802, + "top": 454, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5/ask/OUQY=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5/ask/P3tM=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "lineStyle": 1, + "points": "318:307;827:455", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P5/ask/FCi8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5/ask/GmBY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5/ask/H9Os=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P5/ask/ITgo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P5/ask/J3dw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P5/ask/KH+Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P5/ask/LwxI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P5/ask/MCSM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P5/ask/N7rw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P5/ask/OUQY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P5/ask/P3tM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P6Btl1DS04s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P6Btl1DTuQ4=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P6Btl1DUbE8=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDVnHI=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 74.5, + "top": 411.5, + "width": 207, + "height": 13, + "text": "【提示用户是否确定删除整个测回】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDW1Rc=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDXJZ4=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 69.5, + "top": 404.5, + "width": 218, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6Btl1DUbE8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P6BtmFDVnHI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P6BtmFDW1Rc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6BtmFDXJZ4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P6BtmFDYzoo=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P6BtmFDZfOA=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P6BtmFDabNE=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P6BtmFDbcVg=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P6BtmFDcrag=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 400, + "width": 308, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P6BtmFDYzoo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P6BtmFDZfOA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P6BtmFDabNE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P6BtmFDbcVg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P6BtmFDcrag=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6ETu1Fw08c=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFx1mw=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "font": "Arial;13;0", + "left": 199, + "top": 354, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1, + "text": "+重测测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFyw0s=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 241, + "top": 362, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFzyRs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 203, + "top": 339, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF0+lY=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 244, + "top": 330, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF1ok8=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 254, + "top": 339, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF2wKI=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 222, + "top": 312, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF3tbw=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 214, + "top": 378, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF4Oc0=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 226, + "top": 383, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF586k=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 188, + "top": 368, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6ETvFF6xek=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6ETvFF7szs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "tail": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "lineStyle": 1, + "points": "245:307;188:399", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6ETvFFx1mw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6ETvFFyw0s=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6ETvFFzyRs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6ETvFF0+lY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6ETvFF1ok8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6ETvFF2wKI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6ETvFF3tbw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6ETvFF4Oc0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6ETvFF586k=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6ETvFF6xek=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6ETvFF7szs=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6HZl1JC23Y=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JDZsQ=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "font": "Arial;13;0", + "left": 509, + "top": 426, + "width": 98.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1, + "text": "+选择忽略or取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JECIw=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 559, + "top": 411, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JF8pk=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 555, + "top": 455, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JG0HA=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 359, + "top": 410, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JHztQ=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 362, + "top": 397, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JIPD0=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 437, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JJLUs=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 758, + "top": 441, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JKFgU=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 757, + "top": 428, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JLM+Y=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 760, + "top": 469, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6HZl1JMru0=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6HZl1JNqZA=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "lineStyle": 1, + "points": "332:429;783:465", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6HZl1JDZsQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6HZl1JECIw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6HZl1JF8pk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6HZl1JG0HA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6HZl1JHztQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6HZl1JIPD0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6HZl1JJLUs=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6HZl1JKFgU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6HZl1JLM+Y=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6HZl1JMru0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6HZl1JNqZA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P6IYDFMMeFQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P6IYDFMNnzQ=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDFMOOjk=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMPgvc=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 125, + "top": 531.5, + "width": 103, + "height": 13, + "text": "【执行删除操作】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMQezU=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMRBdM=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 120, + "top": 524.5, + "width": 114, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6IYDFMOOjk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P6IYDVMPgvc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P6IYDVMQezU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6IYDVMRBdM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P6IYDVMSZQE=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P6IYDVMTe6E=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P6IYDVMUviY=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P6IYDVMVT7Q=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P6IYDVMWeEE=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 96, + "top": 520, + "width": 161, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P6IYDVMSZQE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P6IYDVMTe6E=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P6IYDVMUviY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P6IYDVMVT7Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P6IYDVMWeEE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6Jc6FQAXTQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQBsAA=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "font": "Arial;13;0", + "left": 161, + "top": 470, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1, + "text": "+确认删除" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQCliU=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 205, + "top": 470, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQDs0Y=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 161, + "top": 471, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQErUI=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 455, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQFXc4=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 457, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQGACw=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 450, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQH5rw=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 487, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQIDDY=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 485, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQJXs0=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 163, + "top": 491, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6Jc6VQKiwE=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6Jc6VQLymI=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "tail": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "lineStyle": 1, + "points": "177:435;176:519", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6Jc6FQBsAA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6Jc6FQCliU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6Jc6FQDs0Y=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6Jc6VQErUI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6Jc6VQFXc4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6Jc6VQGACw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6Jc6VQH5rw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6Jc6VQIDDY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6Jc6VQJXs0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6Jc6VQKiwE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6Jc6VQLymI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6KuWFYy590=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFYzBrY=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 995, + "top": 977, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY07+U=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1002, + "top": 964, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY1T2M=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 980, + "top": 1004, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY2uTU=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 237, + "top": 548, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY3Q0s=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 246, + "top": 538, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY4NMQ=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 220, + "top": 570, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY5sZg=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1752, + "top": 1407, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY62Oo=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1757, + "top": 1394, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY78L8=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1743, + "top": 1433, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6KuWFY8wFs=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6KuWVY9b40=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": -144, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "lineStyle": 1, + "points": "208:555;1768:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6KuWFYzBrY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6KuWFY07+U=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6KuWFY1T2M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6KuWFY2uTU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6KuWFY3Q0s=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6KuWFY4NMQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6KuWFY5sZg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6KuWFY62Oo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6KuWFY78L8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6KuWFY8wFs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6KuWVY9b40=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJWvCwgzk0M=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJWvCwg0EPw=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg1NpM=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1920, + "top": 2944, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg2wKE=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "font": "Arial;13;1", + "left": 1752, + "top": 1875.5, + "width": 119, + "height": 13, + "text": "move2NextValidate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg3lvo=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1920, + "top": 2944, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg4tCw=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1920, + "top": 2944, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1747, + "top": 1868.5, + "width": 129, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJWvCwg1NpM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJWvCwg2wKE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJWvCwg3lvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJWvCwg4tCw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJWvCwg5PfY=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJWvDAg6ClE=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJWvDAg7Ros=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJWvDAg8tC0=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJWvDAg9Vl8=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1720, + "top": 1864, + "width": 183, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJWvCwg5PfY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJWvDAg6ClE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJWvDAg7Ros=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJWvDAg8tC0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJWvDAg9Vl8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJesYRAYGmw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAZQUY=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "font": "Arial;13;0", + "left": 1492, + "top": 300, + "width": 189.2279815673828, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1, + "text": "+测站不闭合or半测回归零差正常" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAa+X8=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1589, + "top": 285, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAb41g=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1579, + "top": 329, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAcFHE=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1415, + "top": 260, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAdnH8=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1420, + "top": 247, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAeLA0=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1405, + "top": 286, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAfocQ=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1758, + "top": 340, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAgNDY=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1758, + "top": 327, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAh4Q4=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1756, + "top": 368, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJesYhAiBdg=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJesYhAjzjQ=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": -144, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "tail": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "lineStyle": 1, + "points": "1387:275;1780:367", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJesYRAZQUY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJesYRAa+X8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJesYRAb41g=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJesYhAcFHE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJesYhAdnH8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJesYhAeLA0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJesYhAfocQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJesYhAgNDY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJesYhAh4Q4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJesYhAiBdg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJesYhAjzjQ=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJjLZRML/gk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJjLZRMMO54=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMN0eQ=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 784, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMOGnw=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 820, + "top": 467.5, + "width": 139, + "height": 13, + "text": "switchState2StandStill" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMPJsQ=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 784, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMQZsw=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 784, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 815, + "top": 460.5, + "width": 149.419921875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJjLZRMN0eQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJjLZRMOGnw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJjLZRMPJsQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJjLZRMQZsw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJjLZRMRZxg=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJjLZRMSuGM=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJjLZRMTa74=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJjLZRMUk04=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJjLZRMVcTY=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 784, + "top": 456, + "width": 211, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJjLZRMRZxg=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJjLZRMSuGM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJjLZRMTa74=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJjLZRMUk04=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJjLZRMVcTY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJk5ohVYjKI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJk5ohVZ7LA=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVaBvo=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1040, + "top": -608, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVbtSw=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 925, + "top": 267.5, + "width": 142, + "height": 13, + "text": "提示半测回归零检测失败" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVc1ns=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1040, + "top": -608, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVdnqY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1040, + "top": -608, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 920, + "top": 260.5, + "width": 153, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJk5ohVaBvo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJk5ohVbtSw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJk5ohVc1ns=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJk5ohVdnqY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJk5ohVeC3M=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJk5ohVfd1M=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJk5ohVg6Qc=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJk5ohVh4ZY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJk5ohViitY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 888, + "top": 256, + "width": 216, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJk5ohVeC3M=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJk5ohVfd1M=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJk5ohVg6Qc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJk5ohVh4ZY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJk5ohViitY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJmQwBdwdmk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwBdxb3k=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "font": "Arial;13;0", + "left": 1117, + "top": 272, + "width": 85.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1, + "text": "+没有通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRdyFDg=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1160, + "top": 287, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRdzOi4=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1158, + "top": 243, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd0cxc=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1189, + "top": 272, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd1+jk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1188, + "top": 285, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd2je8=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1192, + "top": 244, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd3aOM=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1130, + "top": 274, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd4cEI=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1133, + "top": 287, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd5h7I=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1125, + "top": 247, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJmQwRd6XO0=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJmQwRd7bPQ=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "tail": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "lineStyle": 1, + "points": "1215:262;1104:267", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJmQwBdxb3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJmQwRdyFDg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJmQwRdzOi4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJmQwRd0cxc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJmQwRd1+jk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJmQwRd2je8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJmQwRd3aOM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJmQwRd4cEI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJmQwRd5h7I=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJmQwRd6XO0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJmQwRd7bPQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJnHsRkO52k=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkPXt4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 955, + "top": 373, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkQg5M=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 968, + "top": 380, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkRfd8=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": 360, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkS/7E=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 986, + "top": 314, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkTUvo=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 996, + "top": 323, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkU2kA=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 963, + "top": 298, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkVrbg=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 924, + "top": 432, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkWL5A=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 937, + "top": 437, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkXIlE=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 897, + "top": 424, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnHsRkYjF0=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnHsRkZRp4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "lineStyle": 1, + "points": "985:291;899:455", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJnHsRkPXt4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJnHsRkQg5M=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJnHsRkRfd8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJnHsRkS/7E=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJnHsRkTUvo=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJnHsRkU2kA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJnHsRkVrbg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJnHsRkWL5A=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJnHsRkXIlE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJnHsRkYjF0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJnHsRkZRp4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJnk3hnngQ0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnoFuM=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1111, + "top": 411, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnpzsU=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1108, + "top": 396, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnqowI=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1116, + "top": 440, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnr2A8=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1011, + "top": 429, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnsPz4=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1011, + "top": 416, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnt7X0=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1012, + "top": 457, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnuPbw=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1210, + "top": 393, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnvOwA=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1206, + "top": 381, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnwvuU=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1219, + "top": 420, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnk3hnxCbA=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnk3hny8xs=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "lineStyle": 1, + "points": "989:455;1239:410", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJnk3hnoFuM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJnk3hnpzsU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJnk3hnqowI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJnk3hnr2A8=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJnk3hnsPz4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJnk3hnt7X0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJnk3hnuPbw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJnk3hnvOwA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJnk3hnwvuU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJnk3hnxCbA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJnk3hny8xs=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ6ahiPXyXI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ6ahiPYzM0=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahiPZdhA=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -544, + "top": -656, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahiPa2BQ=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "font": "Arial;13;1", + "left": 419.5, + "top": 243.5, + "width": 96, + "height": 13, + "text": "checkReadData" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahyPb1CY=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -544, + "top": -656, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahyPcSJM=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -544, + "top": -656, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 414.5, + "top": 236.5, + "width": 106.8271484375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ6ahiPZdhA=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ6ahiPa2BQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ6ahyPb1CY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ6ahyPcSJM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ6ahyPdwvQ=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ6ahyPeius=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ6ahyPfDuE=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ6ahyPgVJE=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ6ahyPhyOw=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 392, + "top": 232, + "width": 151, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ6ahyPdwvQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ6ahyPeius=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ6ahyPfDuE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ6ahyPgVJE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ6ahyPhyOw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ8m8Sf6ofY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ8m8Sf7JBU=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf8/hc=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -1248, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf9x9A=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "font": "Arial;13;1", + "left": 1252, + "top": 123.5, + "width": 175, + "height": 13, + "text": "isHalfCycleZeroCheckReady" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf+ddw=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -1248, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf/cbI=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -1248, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1247, + "top": 116.5, + "width": 186.2998046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ8m8Sf8/hc=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ8m8Sf9x9A=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ8m8Sf+ddw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ8m8Sf/cbI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ8m8SgAs+Y=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ8m8SgBoKU=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ8m8SgCMgY=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ8m8SgDeic=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ8m8SgEIBM=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1208, + "top": 112, + "width": 263, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ8m8SgAs+Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ8m8SgBoKU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ8m8SgCMgY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ8m8SgDeic=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ8m8SgEIBM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ87PCkCJ2c=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkD2ew=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "font": "Arial;13;0", + "left": 817, + "top": 172, + "width": 111.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1, + "text": "+单测量or通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkEHYk=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 870, + "top": 157, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkFD0M=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 877, + "top": 201, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkGBOM=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 566, + "top": 214, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkHciQ=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 567, + "top": 201, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkI53k=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 566, + "top": 242, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkJ5DY=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1180, + "top": 129, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkKd2s=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1176, + "top": 116, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkLnCE=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1188, + "top": 156, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ87PCkMizE=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ87PCkNuH0=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "tail": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "lineStyle": 1, + "points": "543:239;1208:147", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ87PCkD2ew=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ87PCkEHYk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ87PCkFD0M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ87PCkGBOM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ87PCkHciQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ87PCkI53k=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ87PCkJ5DY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ87PCkKd2s=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ87PCkLnCE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ87PCkMizE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ87PCkNuH0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ+mRitZ0H0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ+mRitad0o=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRitbxtk=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 736, + "top": -560, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytcRUc=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 687.5, + "top": 291.5, + "width": 77, + "height": 13, + "text": "提示读数有误" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytdKoM=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 736, + "top": -560, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytecXk=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 736, + "top": -560, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 682.5, + "top": 284.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ+mRitbxtk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ+mRytcRUc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ+mRytdKoM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ+mRytecXk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ+mRytf9wc=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ+mRytgl/8=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ+mRythGBg=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ+mRytiPDo=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ+mRytjdZM=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 664, + "top": 280, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ+mRytf9wc=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ+mRytgl/8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ+mRythGBg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ+mRytiPDo=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ+mRytjdZM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ/UgywlH50=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/Ugywm6Cw=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "font": "Arial;13;0", + "left": 569, + "top": 253, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UgywnNpM=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 608, + "top": 238, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UgywoaZM=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 600, + "top": 282, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwpjOU=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 571, + "top": 246, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwqyBI=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 575, + "top": 234, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwrLDA=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 562, + "top": 273, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCws+Vw=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 640, + "top": 259, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwtL5c=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 640, + "top": 246, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwuYNo=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 639, + "top": 287, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/UhCwvaPk=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/UhCwwUDY=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "tail": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "lineStyle": 1, + "points": "543:263;663:285", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ/Ugywm6Cw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ/UgywnNpM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ/UgywoaZM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ/UhCwpjOU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ/UhCwqyBI=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/UhCwrLDA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ/UhCws+Vw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ/UhCwtL5c=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/UhCwuYNo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/UhCwvaPk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/UhCwwUDY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ/0PC0CShY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0DtlQ=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 817, + "top": 368, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0ETCk=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 828, + "top": 358, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0FS9M=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 796, + "top": 389, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0G2RA=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 770, + "top": 317, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0HEgs=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 781, + "top": 310, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0IKu8=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 747, + "top": 333, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0JtjU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 865, + "top": 419, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0KkBY=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 873, + "top": 409, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0LEUU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 848, + "top": 441, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/0PS0MAmo=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/0PS0Nb0Y=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "lineStyle": 1, + "points": "742:315;872:455", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ/0PS0DtlQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ/0PS0ETCk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0FS9M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ/0PS0G2RA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0HEgs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/0PS0IKu8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ/0PS0JtjU=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0KkBY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/0PS0LEUU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/0PS0MAmo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/0PS0Nb0Y=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKE6Ojfzjv0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKE6Ojf0W9Y=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf12Ns=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 3008, + "top": -336, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf2D5I=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "font": "Arial;13;1", + "left": 2110, + "top": 779.5, + "width": 110, + "height": 13, + "text": "checkSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf3N+g=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 3008, + "top": -336, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf4rrM=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 3008, + "top": -336, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2105, + "top": 772.5, + "width": 120.55712890625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKE6Ojf12Ns=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKE6Ojf2D5I=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKE6Ojf3N+g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKE6Ojf4rrM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKE6Ojf5X6A=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKE6Ojf6i5o=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKE6Ojf7hDo=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKE6Ojf8oq8=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKE6Ojf9edk=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2080, + "top": 768, + "width": 170, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKE6Ojf5X6A=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKE6Ojf6i5o=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKE6Ojf7hDo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKE6Ojf8oq8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKE6Ojf9edk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKIG+T9Y4ko=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKIG+T9Zl2o=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9a7vU=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2160, + "top": -1008, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9bDug=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "font": "Arial;13;1", + "left": 1762, + "top": 523.5, + "width": 129, + "height": 13, + "text": "isAllCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9cIfM=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2160, + "top": -1008, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9dArI=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2160, + "top": -1008, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1757, + "top": 516.5, + "width": 139.314453125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKIG+T9a7vU=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKIG+T9bDug=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKIG+T9cIfM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKIG+T9dArI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKIG+T9e1Wk=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKIG+T9fRvU=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKIG+T9gBhM=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKIG+T9hA48=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKIG+T9inVI=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1728, + "top": 512, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKIG+T9e1Wk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKIG+T9fRvU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKIG+T9gBhM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKIG+T9hA48=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKIG+T9inVI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QKI4zEKHpSc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKIQ1c=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "font": "Arial;13;0", + "left": 1956, + "top": 662, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKJdn8=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1976, + "top": 674, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKKTG0=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2004, + "top": 639, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKL0+I=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2110, + "top": 757, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKMDrE=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2100, + "top": 766, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKNoT0=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2130, + "top": 737, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKOx2g=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1861, + "top": 568, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKP85E=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1855, + "top": 580, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKQLJU=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1874, + "top": 544, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKI4zEKR1Nc=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKI4zEKSZgo=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "tail": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "lineStyle": 1, + "points": "2140:767;1850:547", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QKI4zEKIQ1c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKI4zEKJdn8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKI4zEKKTG0=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QKI4zEKL0+I=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QKI4zEKMDrE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QKI4zEKNoT0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QKI4zEKOx2g=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QKI4zEKP85E=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QKI4zEKQLJU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QKI4zEKR1Nc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QKI4zEKSZgo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKuCwkzY630=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKuCwkzZLtk=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzadw4=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 2704, + "top": 112, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzbRGU=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 1879.5, + "top": 995.5, + "width": 77, + "height": 13, + "text": "提示用户选择" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzc5kQ=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 2704, + "top": 112, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzd3VI=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 2704, + "top": 112, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1874.5, + "top": 988.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKuCwkzadw4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKuCwkzbRGU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKuCwkzc5kQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKuCwkzd3VI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKuCw0zeMMo=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKuCw0zfhJM=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKuCw0zgO20=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKuCw0zhG3k=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKuCw0ziN7I=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1856, + "top": 984, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKuCw0zeMMo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKuCw0zfhJM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKuCw0zgO20=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKuCw0zhG3k=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKuCw0ziN7I=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QKvMIE8ZF/E=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8a1To=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "font": "Arial;13;0", + "left": 2013, + "top": 898, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8bx7Y=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2059, + "top": 909, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8c/MU=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2030, + "top": 875, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8df1Y=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2133, + "top": 825, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8e89E=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2140, + "top": 836, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8frKE=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2118, + "top": 801, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8gpg0=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1967, + "top": 971, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8hUUs=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1977, + "top": 979, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8iPfY=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1946, + "top": 953, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKvMIU8jJRc=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKvMIU8kteI=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "lineStyle": 1, + "points": "2143:803;1938:983", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QKvMIU8a1To=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKvMIU8bx7Y=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKvMIU8c/MU=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QKvMIU8df1Y=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QKvMIU8e89E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QKvMIU8frKE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QKvMIU8gpg0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QKvMIU8hUUs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QKvMIU8iPfY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QKvMIU8jJRc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QKvMIU8kteI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKyR6VB+5F0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKyR6VB/sq8=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCAlIw=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -240, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCBFDc=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 956, + "top": 747.5, + "width": 62, + "height": 13, + "text": "重测方向" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCC81I=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -240, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCDFwk=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -240, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 951, + "top": 740.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKyR6lCAlIw=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKyR6lCBFDc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKyR6lCC81I=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKyR6lCDFwk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKyR6lCEof0=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKyR6lCFl5A=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKyR6lCGLz0=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKyR6lCHKbg=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKyR6lCIqJE=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 936, + "top": 736, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKyR6lCEof0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKyR6lCFl5A=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKyR6lCGLz0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKyR6lCHKbg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKyR6lCIqJE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKysH1F4naw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKysH1F5Vw8=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F6t1U=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 928, + "top": -464, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F7w44=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 1300, + "top": 699.5, + "width": 62, + "height": 13, + "text": "重测测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F8ews=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 928, + "top": -464, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F9CVk=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 928, + "top": -464, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1295, + "top": 692.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKysH1F6t1U=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKysH1F7w44=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKysH1F8ews=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKysH1F9CVk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKysH1F+SbI=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKysH1F/p8w=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKysH1GAwRg=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKysH1GBWy4=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKysH1GC8OE=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1280, + "top": 688, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKysH1F+SbI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKysH1F/p8w=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKysH1GAwRg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKysH1GBWy4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKysH1GC8OE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKzDRVJysxE=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKzDRVJztrc=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ0nsk=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1072, + "top": -928, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ1z+Q=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 1398.5, + "top": 523.5, + "width": 226, + "height": 13, + "text": "resetSurveyorStateAndKeepPosition" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ29Q0=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1072, + "top": -928, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ3D90=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1072, + "top": -928, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1393.5, + "top": 516.5, + "width": 237.5634765625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKzDRVJ0nsk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKzDRVJ1z+Q=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKzDRVJ29Q0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKzDRVJ3D90=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKzDRVJ4vK0=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKzDRVJ5ijM=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKzDRVJ6ScY=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKzDRVJ71p4=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKzDRVJ8l2g=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1344, + "top": 512, + "width": 335, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKzDRVJ4vK0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKzDRVJ5ijM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKzDRVJ6ScY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKzDRVJ71p4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKzDRVJ8l2g=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QK2QmFlvdS8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlwJfE=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "font": "Arial;13;0", + "left": 1686, + "top": 768, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1, + "text": "+忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlxSkY=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1691, + "top": 778, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFly6tM=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1725, + "top": 749, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlzr3g=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1873, + "top": 967, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl0RxM=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1862, + "top": 974, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl1X3o=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1897, + "top": 952, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl29pE=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1531, + "top": 570, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl39y0=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1523, + "top": 580, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl4Ns0=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1549, + "top": 549, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK2QmFl5muU=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK2QmFl6Y7A=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1902:983;1526:547", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QK2QmFlwJfE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QK2QmFlxSkY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QK2QmFly6tM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QK2QmFlzr3g=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QK2QmFl0RxM=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QK2QmFl1X3o=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QK2QmFl29pE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QK2QmFl39y0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QK2QmFl4Ns0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QK2QmFl5muU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QK2QmFl6Y7A=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QK340l0Fv9Q=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0GnqQ=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1392, + "top": 471, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Habc=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1384, + "top": 484, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0IZgE=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1407, + "top": 446, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Jr30=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1450, + "top": 504, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0KziQ=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1441, + "top": 515, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0LSAI=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1467, + "top": 483, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0MEF0=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1335, + "top": 438, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0NAX0=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1331, + "top": 451, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Obj8=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1345, + "top": 413, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK340l0PZLk=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK340l0QvTM=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "lineStyle": 1, + "points": "1480:511;1321:419", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QK340l0GnqQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QK340l0Habc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QK340l0IZgE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QK340l0Jr30=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QK340l0KziQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QK340l0LSAI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QK340l0MEF0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QK340l0NAX0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QK340l0Obj8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QK340l0PZLk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QK340l0QvTM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QLdiXGHqtMU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHrPm0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1442, + "top": 883, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHsNrs=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1438, + "top": 898, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHtajM=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1449, + "top": 854, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHu5Ak=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1826, + "top": 985, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHvESE=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1820, + "top": 998, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHwu2c=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1837, + "top": 960, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHxgP0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1059, + "top": 782, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHyZg0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1058, + "top": 795, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHzjfw=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1062, + "top": 754, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLdiXGH0aoo=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLdiXGH1FM8=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1855:984;1038:767", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QLdiXGHrPm0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLdiXGHsNrs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLdiXGHtajM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QLdiXGHu5Ak=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QLdiXGHvESE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QLdiXGHwu2c=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QLdiXGHxgP0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QLdiXGHyZg0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QLdiXGHzjfw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QLdiXGH0aoo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QLdiXGH1FM8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QLwOJ2bPDnI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QLwOJ2bQ8Ro=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bRPfA=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bSTVM=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "fillColor": "#5656ff", + "font": "Arial;13;1", + "left": 1090.5, + "top": 587.5, + "width": 93, + "height": 13, + "text": "resurveyPoints" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bTKUY=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bUBI4=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 1085.5, + "top": 580.5, + "width": 103.9326171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLwOJ2bRPfA=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QLwOJ2bSTVM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QLwOJ2bTKUY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLwOJ2bUBI4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QLwOJ2bVEa0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QLwOJ2bWae0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QLwOJ2bXEAg=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QLwOKGbYe7A=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QLwOKGbZQqo=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + } + ], + "fillColor": "#5656ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1064, + "top": 576, + "width": 146, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QLwOJ2bVEa0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QLwOJ2bWae0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QLwOJ2bXEAg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QLwOKGbYe7A=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QLwOKGbZQqo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QLx6RGoNnGE=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoOcBM=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1050, + "top": 656, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoPkXM=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1039, + "top": 646, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoQUT8=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1071, + "top": 677, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoRB9A=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1009, + "top": 699, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoSk+A=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1001, + "top": 689, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoT8Lo=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1026, + "top": 721, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoUHro=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1090, + "top": 613, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoVk68=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1079, + "top": 606, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoW9No=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1113, + "top": 629, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLx6RGoXj7U=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLx6RGoYmUk=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "tail": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "lineStyle": 1, + "points": "1003:735;1119:611", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QLx6RGoOcBM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLx6RGoPkXM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLx6RGoQUT8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QLx6RGoRB9A=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QLx6RGoSk+A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QLx6RGoT8Lo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QLx6RGoUHro=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QLx6RGoVk68=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QLx6RGoW9No=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QLx6RGoXj7U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QLx6RGoYmUk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QMaQUG/rlG8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QMaQUG/sv3A=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUG/tkJ4=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1712, + "top": 1488, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUG/umGY=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 1692.5, + "top": 1451.5, + "width": 216, + "height": 13, + "text": "switchState2RestartInCurrentCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUW/vdlU=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1712, + "top": 1488, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUW/w0wQ=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1712, + "top": 1488, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1687.5, + "top": 1444.5, + "width": 227.4580078125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMaQUG/tkJ4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QMaQUG/umGY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QMaQUW/vdlU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMaQUW/w0wQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QMaQUW/x48o=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QMaQUW/yJ84=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QMaQUW/z4XE=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QMaQUW/0u+w=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QMaQUW/13YU=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1640, + "top": 1440, + "width": 321, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QMaQUW/x48o=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QMaQUW/yJ84=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QMaQUW/z4XE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QMaQUW/0u+w=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QMaQUW/13YU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMbzEXNQ00I=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNR/aw=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "font": "Arial;13;0", + "left": 1450, + "top": 1009, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1, + "text": "+开始重测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNSJUg=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1491, + "top": 1000, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNTTKw=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1456, + "top": 1028, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNUT2s=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1177, + "top": 616, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNVmq4=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1189, + "top": 610, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNWUrs=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1153, + "top": 629, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNX73U=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1782, + "top": 1403, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNYoLo=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1791, + "top": 1393, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNZwIQ=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1762, + "top": 1423, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMbzEXNaGMo=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMbzEXNbVPI=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "lineStyle": 1, + "points": "1150:611;1786:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMbzEXNR/aw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMbzEXNSJUg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMbzEXNTTKw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMbzEXNUT2s=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMbzEXNVmq4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMbzEXNWUrs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMbzEXNX73U=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMbzEXNYoLo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMbzEXNZwIQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMbzEXNaGMo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMbzEXNbVPI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMjEp4Xxm70=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4XyXqY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1819, + "top": 1662, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4XzTSE=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1834, + "top": 1662, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X0hBs=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1790, + "top": 1663, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X1sYc=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1815, + "top": 1494, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X2bX4=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1829, + "top": 1496, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X3ebc=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1788, + "top": 1490, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X4oDY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1825, + "top": 1830, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X5UnY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1838, + "top": 1827, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X6pQM=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1797, + "top": 1835, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMjEqIX7oU8=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMjEqIX8oCk=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "tail": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "lineStyle": 1, + "points": "1800:1475;1811:1863", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMjEp4XyXqY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMjEp4XzTSE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMjEp4X0hBs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMjEp4X1sYc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMjEp4X2bX4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMjEp4X3ebc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMjEp4X4oDY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMjEp4X5UnY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMjEp4X6pQM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMjEqIX7oU8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMjEqIX8oCk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMnaf4p31wI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p4YhA=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1532, + "top": 768, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p5heM=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1528, + "top": 782, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p6u/E=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1539, + "top": 739, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p7HWo=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1859, + "top": 975, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p8uO8=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1849, + "top": 985, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p9ZYk=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1877, + "top": 954, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p+8dA=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1403, + "top": 734, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p/pOU=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1402, + "top": 747, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4qAet8=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1406, + "top": 706, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMnaf4qBmzo=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMnaf4qCCtY=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1889:983;1536:760;1382:719", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMnaf4p4YhA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMnaf4p5heM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMnaf4p6u/E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMnaf4p7HWo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMnaf4p8uO8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMnaf4p9ZYk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMnaf4p+8dA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMnaf4p/pOU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMnaf4qAet8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMnaf4qBmzo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMnaf4qCCtY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QNAhapFuI7s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFvVXY=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "font": "Arial;13;0", + "left": 1437, + "top": 796, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1, + "text": "+取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFwVCE=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1459, + "top": 782, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFxPvQ=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1442, + "top": 823, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFyOWw=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1378, + "top": 723, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFz3Mw=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1388, + "top": 715, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapF0mvQ=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1356, + "top": 740, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F1FkI=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1852, + "top": 953, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F2OJ8=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1855, + "top": 940, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F3+WU=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1846, + "top": 980, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNAha5F4AZU=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": -56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNAha5F5UgE=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": -56, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1349:723;1448:816;1871:983", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QNAhapFvVXY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QNAhapFwVCE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QNAhapFxPvQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QNAhapFyOWw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QNAhapFz3Mw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QNAhapF0mvQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QNAha5F1FkI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QNAha5F2OJ8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QNAha5F3+WU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QNAha5F4AZU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QNAha5F5UgE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QNFL66Cbz6k=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CcWkE=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "font": "Arial;13;0", + "left": 1393, + "top": 600, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1, + "text": "+忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CdTo8=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1399, + "top": 589, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Ce+u8=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1430, + "top": 621, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CfR+U=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1357, + "top": 652, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Cg04o=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1349, + "top": 641, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66ChcXw=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1373, + "top": 674, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CipGA=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1462, + "top": 548, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Cj6oQ=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1452, + "top": 540, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Ck0os=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1485, + "top": 565, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNFL66ClLUo=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNFL66Cm8No=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1349:687;1492:547", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QNFL66CcWkE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QNFL66CdTo8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QNFL66Ce+u8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QNFL66CfR+U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QNFL66Cg04o=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QNFL66ChcXw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QNFL66CipGA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QNFL66Cj6oQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QNFL66Ck0os=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QNFL66ClLUo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QNFL66Cm8No=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVTun0vZBv0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vaxdo=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "font": "Arial;13;0", + "left": 1276, + "top": 542, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1, + "text": "+重测失败" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vbxuQ=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1303, + "top": 527, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vcmj8=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1310, + "top": 571, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vdoCc=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1233, + "top": 554, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0ved/I=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1233, + "top": 541, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vfAMs=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1233, + "top": 582, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vg9C0=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1377, + "top": 530, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTuoEvhMzo=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1373, + "top": 517, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTuoEviZLY=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1386, + "top": 556, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVTuoEvjqMY=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVTuoEvkZEE=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "lineStyle": 1, + "points": "1210:580;1406:547", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVTun0vaxdo=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVTun0vbxuQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVTun0vcmj8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVTun0vdoCc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVTun0ved/I=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVTun0vfAMs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVTun0vg9C0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVTuoEvhMzo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVTuoEviZLY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVTuoEvjqMY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVTuoEvkZEE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVWv21Zu6Aw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZvsKs=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1302, + "top": 1897, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZwRzk=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1302, + "top": 1912, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZxCSk=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1301, + "top": 1868, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21Zyej0=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1693, + "top": 1891, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZzuYg=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1691, + "top": 1904, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ0MPo=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1697, + "top": 1863, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ18no=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 912, + "top": 1904, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ21Iw=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 914, + "top": 1917, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ3nLg=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 907, + "top": 1877, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVWv3FZ4weo=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVWv3FZ58yM=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "tail": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "lineStyle": 1, + "points": "1719:1882;886:1896", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVWv21ZvsKs=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVWv21ZwRzk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVWv21ZxCSk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVWv21Zyej0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVWv21ZzuYg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVWv3FZ0MPo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVWv3FZ18no=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVWv3FZ21Iw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVWv3FZ3nLg=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVWv3FZ4weo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVWv3FZ58yM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RVbpp1nKVhc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RVbpp1nLusg=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnM530=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1504, + "top": -656, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnNEWc=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 1007.5, + "top": 843.5, + "width": 77, + "height": 13, + "text": "执行测回删除" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnO5/0=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1504, + "top": -656, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnPMMU=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1504, + "top": -656, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1002.5, + "top": 836.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVbpqFnM530=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RVbpqFnNEWc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RVbpqFnO5/0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVbpqFnPMMU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RVbpqFnQqa0=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RVbpqFnRVaY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RVbpqFnSiyY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RVbpqFnTp/o=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RVbpqFnUeVQ=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 984, + "top": 832, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RVbpqFnQqa0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RVbpqFnRVaY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RVbpqFnSiyY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RVbpqFnTp/o=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RVbpqFnUeVQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVcwNF0lj/I=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0m640=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1193, + "top": 784, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0n9pE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1200, + "top": 797, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0osMg=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1180, + "top": 757, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0pne0=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1277, + "top": 742, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0qTm8=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1281, + "top": 755, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0rLrQ=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1269, + "top": 715, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0s558=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1110, + "top": 826, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0tAew=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1119, + "top": 837, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0uE34=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1094, + "top": 804, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVcwNF0vsAE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVcwNF0w5ls=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1294:723;1081:831", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVcwNF0m640=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVcwNF0n9pE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVcwNF0osMg=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVcwNF0pne0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVcwNF0qTm8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVcwNF0rLrQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVcwNF0s558=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVcwNF0tAew=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVcwNF0uE34=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVcwNF0vsAE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVcwNF0w5ls=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVdEqmBOVoU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBP7Mw=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1431, + "top": 1135, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBQ+G0=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1440, + "top": 1123, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBRwAI=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1412, + "top": 1158, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBSb60=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1096, + "top": 865, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBT13s=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1106, + "top": 856, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBU/V0=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1076, + "top": 884, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBVD2o=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1767, + "top": 1405, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBWru8=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1773, + "top": 1393, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBX1jY=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1753, + "top": 1429, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVdEqmBYqxc=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVdEqmBZh5U=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "lineStyle": 1, + "points": "1067:867;1778:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVdEqmBP7Mw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVdEqmBQ+G0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVdEqmBRwAI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVdEqmBSb60=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVdEqmBT13s=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVdEqmBU/V0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVdEqmBVD2o=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVdEqmBWru8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVdEqmBX1jY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVdEqmBYqxc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVdEqmBZh5U=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWbWiJQ+LqI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWbWiJQ/pQw=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRAz/w=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": 2160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRBIu8=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "font": "Arial;13;1", + "left": 1482, + "top": 1715.5, + "width": 167, + "height": 13, + "text": "doCalScheduleSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRCluw=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": 2160, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRDVic=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": 2160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1477, + "top": 1708.5, + "width": 177.603515625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWbWiJRAz/w=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWbWiJRBIu8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWbWiJRCluw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWbWiJRDVic=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWbWiJRE0bA=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWbWiJRF/Bs=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWbWiJRG03U=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWbWiJRHoKE=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWbWiZRIksM=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1440, + "top": 1704, + "width": 251, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWbWiJRE0bA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWbWiJRF/Bs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWbWiJRG03U=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWbWiJRHoKE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWbWiZRIksM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWiYh6tfjKM=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWiYh6tg64I=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6th8ec=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -352, + "top": 1872, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tiGF8=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 1239.5, + "top": 1659.5, + "width": 116, + "height": 13, + "text": "该测回是否完成测量" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tjmMc=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -352, + "top": 1872, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tktDE=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -352, + "top": 1872, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1234.5, + "top": 1652.5, + "width": 127, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWiYh6th8ec=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWiYh6tiGF8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWiYh6tjmMc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWiYh6tktDE=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWiYh6tlfk4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWiYh6tmr4M=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWiYiKtnqn4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWiYiKtodLM=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWiYiKtpwlU=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1208, + "top": 1648, + "width": 179, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWiYh6tlfk4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWiYh6tmr4M=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWiYiKtnqn4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWiYiKtodLM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWiYiKtpwlU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWkDsK/8U8w=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK/9X9k=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1427, + "top": 1701, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK/+yfw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1424, + "top": 1716, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK//l9E=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1434, + "top": 1672, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAAR6U=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1450, + "top": 1706, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAB24o=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1445, + "top": 1718, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLACKmw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1460, + "top": 1680, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLADQMw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1405, + "top": 1696, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAEjZI=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1404, + "top": 1710, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAFuWM=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1406, + "top": 1669, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWkDsLAGH8s=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1160, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWkDsLAHEmo=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1160, + "top": 208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "tail": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "lineStyle": 1, + "points": "1479:1703;1383:1683", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWkDsK/9X9k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWkDsK/+yfw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWkDsK//l9E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWkDsLAAR6U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWkDsLAB24o=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWkDsLACKmw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWkDsLADQMw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWkDsLAEjZI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWkDsLAFuWM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWkDsLAGH8s=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWkDsLAHEmo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWmAObijdJg=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObikqE4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "font": "Arial;13;0", + "left": 1519, + "top": 1541, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObilnCo=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1536, + "top": 1527, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObima+o=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1553, + "top": 1568, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObinxIM=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1359, + "top": 1617, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObioxZQ=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1356, + "top": 1604, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObip4S4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1365, + "top": 1644, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObiqN8s=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1726, + "top": 1465, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObir6/Y=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1719, + "top": 1453, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObisLv4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1740, + "top": 1488, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWmAObitY30=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -888, + "top": 512, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWmAObiuohI=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -888, + "top": 512, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "lineStyle": 1, + "points": "1341:1647;1756:1475", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWmAObikqE4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWmAObilnCo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWmAObima+o=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWmAObinxIM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWmAObioxZQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWmAObip4S4=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWmAObiqN8s=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWmAObir6/Y=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWmAObisLv4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWmAObitY30=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWmAObiuohI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWo+Isgcitc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWo+Isgdtvs=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isge0Bo=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1072, + "top": -480, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isgf4GU=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 946, + "top": 939.5, + "width": 90, + "height": 13, + "text": "执行单测回检测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isgg0Do=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1072, + "top": -480, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+IsghCRI=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1072, + "top": -480, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 941, + "top": 932.5, + "width": 101, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWo+Isge0Bo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWo+Isgf4GU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWo+Isgg0Do=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWo+IsghCRI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWo+IsgimWA=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWo+IsgjYQU=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWo+I8gkz+0=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWo+I8gl0UM=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWo+I8gmRYk=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 920, + "top": 928, + "width": 142, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWo+IsgimWA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWo+IsgjYQU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWo+I8gkz+0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWo+I8gl0UM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWo+I8gmRYk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWqc88vvIe4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vwQ3o=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "font": "Arial;13;0", + "left": 1113, + "top": 1304, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1, + "text": "+完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vxT8A=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1115, + "top": 1310, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vy9C4=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1156, + "top": 1293, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vzWws=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1265, + "top": 1622, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v0Sh0=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1251, + "top": 1626, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v168Q=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1292, + "top": 1616, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v2l68=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 994, + "top": 986, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v3ThA=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 983, + "top": 994, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v4wsI=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1017, + "top": 972, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWqc88v5V34=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWqc88v6Awc=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "tail": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "lineStyle": 1, + "points": "1289:1647;998:963", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWqc88vwQ3o=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWqc88vxT8A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWqc88vy9C4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWqc88vzWws=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWqc88v0Sh0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWqc88v168Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWqc88v2l68=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWqc88v3ThA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWqc88v4wsI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWqc88v5V34=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWqc88v6Awc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWvJyNWG+ro=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJyNWHf5E=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "font": "Arial;13;0", + "left": 1422, + "top": 952, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWI+RY=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1459, + "top": 937, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWJFaw=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1457, + "top": 981, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWKHVg=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": 929, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWLzSM=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1091, + "top": 916, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWM5GE=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1082, + "top": 956, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWN+wY=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1829, + "top": 974, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWO3W0=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1828, + "top": 961, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWPqsM=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1832, + "top": 1002, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWvJydWQnX8=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWvJydWRolw=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "lineStyle": 1, + "points": "1062:949;1855:997", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWvJyNWHf5E=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWvJydWI+RY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWvJydWJFaw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWvJydWKHVg=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWvJydWLzSM=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWvJydWM5GE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWvJydWN+wY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWvJydWO3W0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWvJydWPqsM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWvJydWQnX8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWvJydWRolw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWzzg+QpJu4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWzzg+QqF0g=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QruaM=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": 880, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QscXo=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "font": "Arial;13;1", + "left": 1021.5, + "top": 1747.5, + "width": 144, + "height": 13, + "text": "doCalScheduleAllCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QtTVY=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": 880, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QuN+0=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": 880, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1016.5, + "top": 1740.5, + "width": 155.208984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWzzg+QruaM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWzzg+QscXo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWzzg+QtTVY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWzzg+QuN+0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWzzg+QvVhA=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWzzhOQwWI4=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWzzhOQxyn0=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWzzhOQy5lE=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWzzhOQzPbk=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 984, + "top": 1736, + "width": 219, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWzzg+QvVhA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWzzhOQwWI4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWzzhOQxyn0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWzzhOQy5lE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWzzhOQzPbk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXS1EJdHVug=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EJdIPgY=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1189, + "top": 1689, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EJdJc8o=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1183, + "top": 1675, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdKavs=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1200, + "top": 1716, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdLggY=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1152, + "top": 1704, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdMTYk=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1149, + "top": 1691, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdNexM=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1159, + "top": 1731, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdOTNQ=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1225, + "top": 1673, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdPiGs=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1217, + "top": 1662, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdQDNw=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1240, + "top": 1697, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXS1EZdR8Jw=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXS1EZdSgUI=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "tail": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "lineStyle": 1, + "points": "1135:1735;1255:1683", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXS1EJdIPgY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXS1EJdJc8o=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXS1EZdKavs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXS1EZdLggY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXS1EZdMTYk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXS1EZdNexM=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXS1EZdOTNQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXS1EZdPiGs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXS1EZdQDNw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXS1EZdR8Jw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXS1EZdSgUI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RXZT37eTFkI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RXZT37eUYGs=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eVlUE=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -64, + "top": -608, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eWL9s=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 427, + "top": 555.5, + "width": 209, + "height": 13, + "text": "是否是doCalScheduleAllCycle状态" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eXM1A=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -64, + "top": -608, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eYXNc=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -64, + "top": -608, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 422, + "top": 548.5, + "width": 220.208984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXZT37eVlUE=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RXZT37eWL9s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RXZT37eXM1A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXZT37eYXNc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RXZT4LeZ09I=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RXZT4LeaFc4=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RXZT4Leb1Fs=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RXZT4Lec37Q=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RXZT4Led934=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 376, + "top": 544, + "width": 311, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RXZT4LeZ09I=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RXZT4LeaFc4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RXZT4Leb1Fs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RXZT4Lec37Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RXZT4Led934=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXgsFM1PXPQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1QsVQ=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "font": "Arial;13;0", + "left": 734, + "top": 758, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1, + "text": "+通过" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1Ra4g=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 740, + "top": 769, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1S7Hk=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 769, + "top": 735, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1TpZY=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 938, + "top": 915, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1UfIs=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": 924, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1VQJk=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 959, + "top": 897, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1WeYo=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 563, + "top": 601, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1XNlM=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 556, + "top": 612, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1Y+GY=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 577, + "top": 577, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXgsFc1ZbPg=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXgsFc1aqC8=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "tail": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "lineStyle": 1, + "points": "968:927;553:579", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXgsFM1QsVQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXgsFM1Ra4g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXgsFM1S7Hk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXgsFM1TpZY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXgsFM1UfIs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXgsFM1VQJk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXgsFM1WeYo=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXgsFM1XNlM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXgsFM1Y+GY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXgsFc1ZbPg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXgsFc1aqC8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXiiXNaNYZA=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaOCjk=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "font": "Arial;13;0", + "left": 690, + "top": 496, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1, + "text": "+不是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaPvOQ=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 702, + "top": 481, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaQrNs=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 713, + "top": 525, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaRjEI=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 625, + "top": 516, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaS5Dg=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 624, + "top": 502, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaT/jE=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 628, + "top": 543, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaUStc=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 787, + "top": 476, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaVtIQ=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 781, + "top": 464, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaWcc8=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 797, + "top": 502, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXiiXNaXeGE=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXiiXNaY4kk=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "lineStyle": 1, + "points": "604:543;816:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXiiXNaOCjk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXiiXNaPvOQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXiiXNaQrNs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXiiXNaRjEI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXiiXNaS5Dg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXiiXNaT/jE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXiiXNaUStc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXiiXNaVtIQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXiiXNaWcc8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXiiXNaXeGE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXiiXNaY4kk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX4IzuDknh4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX4IzuDlZLU=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDmg8A=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDnpIw=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 69, + "top": 1043.5, + "width": 181, + "height": 13, + "text": "检测其他测回是否有待补测数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDoCnY=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDpft0=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 64, + "top": 1036.5, + "width": 192, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX4IzuDmg8A=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX4IzuDnpIw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX4IzuDoCnY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX4IzuDpft0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX4IzuDqBSE=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX4IzuDrpSs=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX4IzuDsUmU=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX4IzuDtPH4=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX4IzuDu2iA=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 1032, + "width": 271, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX4IzuDqBSE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX4IzuDrpSs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX4IzuDsUmU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX4IzuDtPH4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX4IzuDu2iA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX50xuaSWVY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaTzmw=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "font": "Arial;13;0", + "left": 346, + "top": 808, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1, + "text": "+是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaUoZk=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 368, + "top": 817, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaVv9g=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 333, + "top": 789, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaWjUs=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 513, + "top": 602, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaX0wc=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 522, + "top": 612, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaYr8k=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 493, + "top": 582, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaZPzE=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 1013, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaaRl8=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 212, + "top": 1019, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuabK8k=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 176, + "top": 1000, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX50xuac8yw=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX50xuadjR8=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "tail": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "lineStyle": 1, + "points": "517:579;173:1031", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX50xuaTzmw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX50xuaUoZk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX50xuaVv9g=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX50xuaWjUs=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX50xuaX0wc=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX50xuaYr8k=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX50xuaZPzE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX50xuaaRl8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX50xuabK8k=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX50xuac8yw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX50xuadjR8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX8e8+6VSP4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX8e9O6W2xM=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6XR7Q=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -16, + "top": -496, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6YBmI=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 487.5, + "top": 963.5, + "width": 77, + "height": 13, + "text": "提示用户选择" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6ZG1Q=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -16, + "top": -496, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6aHT4=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -16, + "top": -496, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 482.5, + "top": 956.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX8e9O6XR7Q=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX8e9O6YBmI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX8e9O6ZG1Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX8e9O6aHT4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX8e9O6brFw=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX8e9O6chUQ=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX8e9O6d2JQ=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX8e9O6ehSE=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX8e9O6fsgA=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 464, + "top": 952, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX8e9O6brFw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX8e9O6chUQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX8e9O6d2JQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX8e9O6ehSE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX8e9O6fsgA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX9EYPFfH8Q=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFg5zI=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "font": "Arial;13;0", + "left": 338, + "top": 986, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFh+Xw=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 345, + "top": 971, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFiQm8=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 355, + "top": 1015, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFj0XU=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 263, + "top": 1004, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFkHH4=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 262, + "top": 991, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFlEI4=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "top": 1032, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFmXkk=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 434, + "top": 967, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFnjvk=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 429, + "top": 955, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFoLfQ=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 444, + "top": 993, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX9EYPFp0GM=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX9EYPFqX8k=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "tail": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "lineStyle": 1, + "points": "241:1031;463:983", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX9EYPFg5zI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX9EYPFh+Xw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX9EYPFiQm8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX9EYPFj0XU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX9EYPFkHH4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX9EYPFlEI4=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX9EYPFmXkk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX9EYPFnjvk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX9EYPFoLfQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX9EYPFp0GM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX9EYPFqX8k=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX+92/rtdeY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX+92/ru5aU=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rvMVo=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 160, + "top": 32, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rwk7c=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 876, + "top": 1243.5, + "width": 62, + "height": 13, + "text": "切换测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rxBWI=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 160, + "top": 32, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/ryOmk=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 160, + "top": 32, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 871, + "top": 1236.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX+92/rvMVo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX+92/rwk7c=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX+92/rxBWI=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX+92/ryOmk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX+92/rzeck=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX+92/r0UGE=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX+92/r1dEM=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX+92/r24rI=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX+92/r3m0Y=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 856, + "top": 1232, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX+92/rzeck=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX+92/r0UGE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX+92/r1dEM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX+92/r24rI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX+92/r3m0Y=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX/wMv3JNxw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3KAYY=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1343, + "top": 1329, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3L2sA=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1346, + "top": 1314, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3MDuY=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1336, + "top": 1358, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3NMMM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 986, + "top": 1246, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3OaEE=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 991, + "top": 1233, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3P2uw=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 976, + "top": 1272, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3QkNM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1701, + "top": 1412, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3RuyM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1701, + "top": 1399, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3SQ5M=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1699, + "top": 1440, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX/wM/3TMvA=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX/wM/3Udik=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "lineStyle": 1, + "points": "958:1261;1723:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX/wM/3KAYY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX/wM/3L2sA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX/wM/3MDuY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX/wM/3NMMM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX/wM/3OaEE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX/wM/3P2uw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX/wM/3QkNM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX/wM/3RuyM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX/wM/3SQ5M=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX/wM/3TMvA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX/wM/3Udik=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYA6Lgau9u4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgavBvE=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "font": "Arial;13;0", + "left": 674, + "top": 1090, + "width": 98.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1, + "text": "+跳转到相应测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgawDgk=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 732, + "top": 1078, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lgaxot4=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 706, + "top": 1115, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgayEWk=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 578, + "top": 984, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lgazq+M=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 588, + "top": 974, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga0Sio=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 559, + "top": 1003, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga1FSA=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 869, + "top": 1197, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga2vcA=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 1185, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga3b2g=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 857, + "top": 1222, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYA6Lga4c4g=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYA6Lga51go=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "tail": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "lineStyle": 1, + "points": "549:987;882:1231", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYA6LgavBvE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYA6LgawDgk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYA6Lgaxot4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYA6LgayEWk=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYA6Lgazq+M=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYA6Lga0Sio=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYA6Lga1FSA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYA6Lga2vcA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYA6Lga3b2g=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYA6Lga4c4g=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYA6Lga51go=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYRxIyqNVJQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqOsk8=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "font": "Arial;13;0", + "left": 658, + "top": 706, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1, + "text": "+忽略或取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqPdMg=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 682, + "top": 697, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqQWvY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 719, + "top": 723, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqRHT4=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 541, + "top": 915, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqS57E=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 531, + "top": 905, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqTkAo=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 560, + "top": 934, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqUXmw=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 848, + "top": 497, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqVgEY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 836, + "top": 491, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqWNBU=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 873, + "top": 509, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYRxJCqXBjo=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYRxJCqYdsw=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "lineStyle": 1, + "points": "538:951;876:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYRxIyqOsk8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYRxIyqPdMg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYRxIyqQWvY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYRxIyqRHT4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYRxJCqS57E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYRxJCqTkAo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYRxJCqUXmw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYRxJCqVgEY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYRxJCqWNBU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYRxJCqXBjo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYRxJCqYdsw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RYWBNj55r2s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RYWBNj56ll8=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj57vDo=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": 864, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj582Gg=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 151.5, + "top": 1835.5, + "width": 155, + "height": 13, + "text": "检测其他测回是否有空数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj59CIs=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": 864, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj5+a6c=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": 864, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 146.5, + "top": 1828.5, + "width": 166, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYWBNj57vDo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RYWBNj582Gg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RYWBNj59CIs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYWBNj5+a6c=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RYWBNj5/meo=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RYWBNj6ApFY=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RYWBNj6BKos=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RYWBNj6CyfU=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RYWBNj6DzGw=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 112, + "top": 1824, + "width": 234, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RYWBNj5/meo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RYWBNj6ApFY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RYWBNj6BKos=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RYWBNj6CyfU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RYWBNj6DzGw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYXKoUPzfpc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP0Xm4=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "font": "Arial;13;0", + "left": 197, + "top": 1437, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP1/8o=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 222, + "top": 1436, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP2TmE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 178, + "top": 1440, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP3dpE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 178, + "top": 1085, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP4Dks=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 1086, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP5sn0=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 150, + "top": 1083, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP6dKk=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 238, + "top": 1789, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP7hGo=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 251, + "top": 1786, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP8Pbs=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 211, + "top": 1796, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYXKoUP9qJ8=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYXKokP+OFo=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "tail": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "lineStyle": 1, + "points": "161:1067;226:1823", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYXKoUP0Xm4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYXKoUP1/8o=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYXKoUP2TmE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYXKoUP3dpE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYXKoUP4Dks=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYXKoUP5sn0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYXKoUP6dKk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYXKoUP7hGo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYXKoUP8Pbs=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYXKoUP9qJ8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYXKokP+OFo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYbKCEsNrL8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsOHZ0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "font": "Arial;13;0", + "left": 351, + "top": 1394, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsP+kM=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 347, + "top": 1389, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsQdPM=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 390, + "top": 1403, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsRxi0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 228, + "top": 1787, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsSIa0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": 1781, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsTIOs=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 252, + "top": 1800, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsUoUc=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 496, + "top": 1000, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCUsVQTY=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 483, + "top": 998, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCUsWC+U=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 523, + "top": 1005, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYbKCUsX4lU=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYbKCUsYcdA=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "tail": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "lineStyle": 1, + "points": "234:1823;519:987", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYbKCEsOHZ0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYbKCEsP+kM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYbKCEsQdPM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYbKCEsRxi0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYbKCEsSIa0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYbKCEsTIOs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYbKCEsUoUc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYbKCUsVQTY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYbKCUsWC+U=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYbKCUsX4lU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYbKCUsYcdA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RYo1sZrzoek=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RYo1sZr0KlU=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr1HjQ=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -256, + "top": 1584, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr2W5c=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 511.5, + "top": 2147.5, + "width": 116, + "height": 13, + "text": "检测其他测回合法性" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr3XYs=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -256, + "top": 1584, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr4E80=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -256, + "top": 1584, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 506.5, + "top": 2140.5, + "width": 127, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYo1sZr1HjQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RYo1sZr2W5c=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RYo1sZr3XYs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYo1sZr4E80=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RYo1sZr5VvI=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RYo1sZr6Veg=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RYo1sZr7Dv4=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RYo1sZr8TjI=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RYo1sZr9JcM=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 480, + "top": 2136, + "width": 179, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RYo1sZr5VvI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RYo1sZr6Veg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RYo1sZr7Dv4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RYo1sZr8TjI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RYo1sZr9JcM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYqgkqO2MyI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO3BkI=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "font": "Arial;13;0", + "left": 379, + "top": 1979, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1, + "text": "+无空测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO4B50=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 418, + "top": 1968, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO5Eu4=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 387, + "top": 2002, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO6Q3U=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 277, + "top": 1859, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO7HyE=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 287, + "top": 1851, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO8jmg=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 255, + "top": 1876, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO9LA0=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 539, + "top": 2100, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO+vZw=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 547, + "top": 2089, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO/OQc=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 524, + "top": 2123, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYqgkqPAF8U=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYqgkqPBTIk=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "tail": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "lineStyle": 1, + "points": "248:1859;549:2135", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYqgkqO3BkI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYqgkqO4B50=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYqgkqO5Eu4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYqgkqO6Q3U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYqgkqO7HyE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYqgkqO8jmg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYqgkqO9LA0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYqgkqO+vZw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYqgkqO/OQc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYqgkqPAF8U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYqgkqPBTIk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYuGzq0zcW0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq00uWc=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "font": "Arial;13;0", + "left": 2069, + "top": 2029, + "width": 137.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1, + "text": "+发现有测回未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq01kJ4=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2122, + "top": 2032, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq02LjQ=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2166, + "top": 2022, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq03E1k=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 683, + "top": 2123, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq044hU=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 685, + "top": 2109, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq05NGE=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 681, + "top": 2150, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq06xW4=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1912, + "top": 1041, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq07gn8=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1899, + "top": 1046, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq08/Nc=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1938, + "top": 1031, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYuGzq09BO0=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYuGzq0+Fys=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "lineStyle": 1, + "points": "659:2146;2152:2032;1921:1019", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYuGzq00uWc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYuGzq01kJ4=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYuGzq02LjQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYuGzq03E1k=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYuGzq044hU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYuGzq05NGE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYuGzq06xW4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYuGzq07gn8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYuGzq08/Nc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYuGzq09BO0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYuGzq0+Fys=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RY5M47VS/5M=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M47VTDWg=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "font": "Arial;13;0", + "left": 672, + "top": 1304, + "width": 85.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1, + "text": "+全部通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M47VUjKA=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 699, + "top": 1301, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVVTlw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 743, + "top": 1309, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVWBPw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 562, + "top": 2100, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVX2xY=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 549, + "top": 2095, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVYskw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 588, + "top": 2110, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVZo0A=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 866, + "top": 507, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVaI9U=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 852, + "top": 507, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVbdjo=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 894, + "top": 508, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY5M5LVcoPg=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY5M5LVdBDo=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "lineStyle": 1, + "points": "572:2135;886:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RY5M47VTDWg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY5M47VUjKA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY5M5LVVTlw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RY5M5LVWBPw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RY5M5LVX2xY=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RY5M5LVYskw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RY5M5LVZo0A=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RY5M5LVaI9U=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RY5M5LVbdjo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RY5M5LVcoPg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RY5M5LVdBDo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RY+P3cq78x4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RY+P3cq8lrU=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq9UVw=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": 48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq+inU=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 956.5, + "top": 1331.5, + "width": 101, + "height": 13, + "text": "switchState2Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq/1Xo=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": 48, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3crAIoY=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": 48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 951.5, + "top": 1324.5, + "width": 111.8671875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY+P3cq9UVw=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RY+P3cq+inU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RY+P3cq/1Xo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY+P3crAIoY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RY+P3srBu6A=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RY+P3srCnMw=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RY+P3srDTrA=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RY+P3srE+P0=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RY+P3srFRq4=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 928, + "top": 1320, + "width": 158, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RY+P3srBu6A=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RY+P3srCnMw=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RY+P3srDTrA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RY+P3srE+P0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RY+P3srFRq4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RY/lW9HunTY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hvi/A=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1133, + "top": 858, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hw6yM=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1119, + "top": 854, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hx5k8=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1162, + "top": 867, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9HyN1A=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1004, + "top": 1283, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hz89k=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 992, + "top": 1277, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H0J0I=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1029, + "top": 1295, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H1ErY=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1263, + "top": 433, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H23xw=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1249, + "top": 431, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H3Onc=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1290, + "top": 437, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY/lW9H46uE=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY/lW9H5+K0=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "lineStyle": 1, + "points": "1011:1319;1285:419", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RY/lW9Hvi/A=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY/lW9Hw6yM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY/lW9Hx5k8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RY/lW9HyN1A=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RY/lW9Hz89k=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RY/lW9H0J0I=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RY/lW9H1ErY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RY/lW9H23xw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RY/lW9H3Onc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RY/lW9H46uE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RY/lW9H5+K0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZAQqNi9KXs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZAQqNi+U5k=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNi/3K4=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -368, + "top": 1008, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjAnDw=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 770, + "top": 1891.5, + "width": 90, + "height": 13, + "text": "查找待补测数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjB74E=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -368, + "top": 1008, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjCvdQ=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -368, + "top": 1008, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 765, + "top": 1884.5, + "width": 101, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZAQqNi/3K4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZAQqNjAnDw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZAQqNjB74E=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZAQqNjCvdQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZAQqNjDBLs=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZAQqNjEOXs=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZAQqNjF53M=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZAQqNjGCMk=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZAQqNjHp8s=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 744, + "top": 1880, + "width": 142, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZAQqNjDBLs=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZAQqNjEOXs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZAQqNjF53M=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZAQqNjGCMk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZAQqNjHp8s=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZDsue7ftRY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7gCik=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "font": "Arial;13;0", + "left": 885, + "top": 1606, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7h1YU=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 881, + "top": 1601, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7iQis=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 924, + "top": 1615, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7jDYo=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 814, + "top": 1843, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7kyAA=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 802, + "top": 1837, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7ll8Q=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 838, + "top": 1856, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7mtW0=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 977, + "top": 1368, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7n/oo=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 964, + "top": 1366, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7oje8=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1004, + "top": 1373, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZDsue7pTkA=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZDsue7qLNI=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "tail": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "lineStyle": 1, + "points": "820:1879;1000:1355", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZDsue7gCik=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZDsue7h1YU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZDsue7iQis=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZDsue7jDYo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZDsue7kyAA=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZDsue7ll8Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZDsue7mtW0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZDsue7n/oo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZDsue7oje8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZDsue7pTkA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZDsue7qLNI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZEXNfhC2ho=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZEXNfhDeUQ=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhE1JY=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhF08s=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 813, + "top": 1443.5, + "width": 64, + "height": 13, + "text": "查找空数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhGZmc=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -48, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhHCVU=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 808, + "top": 1436.5, + "width": 75, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZEXNfhE1JY=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZEXNfhF08s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZEXNfhGZmc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZEXNfhHCVU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZEXNfhIvoY=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZEXNvhJXeE=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZEXNvhKzwc=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZEXNvhLfS4=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZEXNvhM3lA=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 792, + "top": 1432, + "width": 106, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZEXNfhIvoY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZEXNvhJXeE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZEXNvhKzwc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZEXNvhLfS4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZEXNvhM3lA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZE5Jvvk8+0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vlq9g=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "font": "Arial;13;0", + "left": 804, + "top": 1665, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vm7FE=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 799, + "top": 1664, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vn7vY=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 843, + "top": 1668, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/voHLE=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 801, + "top": 1846, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vpdnU=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 788, + "top": 1842, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vqSPU=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 828, + "top": 1852, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vrD3M=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 826, + "top": 1485, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vslRk=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 812, + "top": 1487, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vtins=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 854, + "top": 1483, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZE5J/vuuHI=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZE5J/vvgB0=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "tail": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "lineStyle": 1, + "points": "815:1879;843:1467", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZE5J/vlq9g=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZE5J/vm7FE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZE5J/vn7vY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZE5J/voHLE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZE5J/vpdnU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZE5J/vqSPU=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZE5J/vrD3M=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZE5J/vslRk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZE5J/vtins=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZE5J/vuuHI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZE5J/vvgB0=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZGEZgj/XLs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkArOw=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "font": "Arial;13;0", + "left": 906, + "top": 1374, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkB2TY=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 907, + "top": 1362, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkChVo=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 933, + "top": 1399, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkDRjc=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 882, + "top": 1397, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkERZ0=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 877, + "top": 1385, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkFONE=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 894, + "top": 1422, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkGzgA=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 950, + "top": 1351, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkHVm4=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 940, + "top": 1341, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkIGXU=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 969, + "top": 1371, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZGEZgkJQgE=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZGEZgkK2ek=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "tail": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "lineStyle": 1, + "points": "870:1431;980:1355", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZGEZgkArOw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZGEZgkB2TY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZGEZgkChVo=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZGEZgkDRjc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZGEZgkERZ0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZGEZgkFONE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZGEZgkGzgA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZGEZgkHVm4=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZGEZgkIGXU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZGEZgkJQgE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZGEZgkK2ek=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZHb+w38rbY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w39z3k=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "font": "Arial;13;0", + "left": 841, + "top": 954, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w3+E8c=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 836, + "top": 953, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w3/cnc=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 880, + "top": 955, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4A7LA=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 831, + "top": 1398, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4BF6A=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 818, + "top": 1395, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4COx0=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 1403, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4DS1Q=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 871, + "top": 510, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4Efb8=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 511, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4Fx+M=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 899, + "top": 507, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZHb+w4GxWE=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZHb+w4HFa8=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "lineStyle": 1, + "points": "845:1431;888:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZHb+w39z3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZHb+w3+E8c=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZHb+w3/cnc=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZHb+w4A7LA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZHb+w4BF6A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZHb+w4COx0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZHb+w4DS1Q=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZHb+w4Efb8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZHb+w4Fx+M=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZHb+w4GxWE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZHb+w4HFa8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZ6XBji6Gjs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZ6XBji742g=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji84Lo=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -672, + "top": 880, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji96yI=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "font": "Arial;13;1", + "left": 776, + "top": 2035.5, + "width": 79, + "height": 13, + "text": "doMoveBack" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji+VvE=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -672, + "top": 880, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji/AjM=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -672, + "top": 880, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 771, + "top": 2028.5, + "width": 90.18994140625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZ6XBji84Lo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZ6XBji96yI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZ6XBji+VvE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZ6XBji/AjM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZ6XBjjASWk=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZ6XBzjBtGc=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZ6XBzjCvBw=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZ6XBzjD9LY=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZ6XBzjEkZ0=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 752, + "top": 2024, + "width": 127, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZ6XBjjASWk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZ6XBzjBtGc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZ6XBzjCvBw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZ6XBzjD9LY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZ6XBzjEkZ0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Sr6mnFdIbRQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Sr6mnFdJQes=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr6mnFdKY5o=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": 96, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr6mnFdL8fY=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "font": "Arial;13;1", + "left": 414, + "top": 1723.5, + "width": 72, + "height": 13, + "text": "doSurveyor" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr6mnFdMXvo=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": 96, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr6mnFdNGZc=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": 96, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 409, + "top": 1716.5, + "width": 82.24267578125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Sr6mnFdKY5o=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Sr6mnFdL8fY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Sr6mnFdMXvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Sr6mnFdNGZc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Sr6mnVdOubo=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Sr6mnVdPN3o=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Sr6mnVdQi1o=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Sr6mnVdRDJw=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Sr6mnVdS2zY=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 392, + "top": 1712, + "width": 116, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Sr6mnVdOubo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Sr6mnVdPN3o=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Sr6mnVdQi1o=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Sr6mnVdRDJw=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Sr6mnVdS2zY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Sr+CM2cB5us=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Sr+CM2cCGRA=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr+CM2cDzn0=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1104, + "top": -480, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr+CNGcEr4Q=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 303.5, + "top": 1531.5, + "width": 194, + "height": 13, + "text": "检测其他测回是否有正在测量数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr+CNGcFDPg=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1104, + "top": -480, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr+CNGcG0MQ=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1104, + "top": -480, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 298.5, + "top": 1524.5, + "width": 205, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Sr+CM2cDzn0=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Sr+CNGcEr4Q=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Sr+CNGcFDPg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Sr+CNGcG0MQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Sr+CNGcHJ2Y=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Sr+CNGcILlE=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Sr+CNGcJ/gk=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Sr+CNGcKL4U=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Sr+CNGcLiZA=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 256, + "top": 1520, + "width": 289, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Sr+CNGcHJ2Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Sr+CNGcILlE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Sr+CNGcJ/gk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Sr+CNGcKL4U=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Sr+CNGcLiZA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsC4MnfxyFI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3fycW0=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 409, + "top": 1630, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3fz5ec=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 394, + "top": 1634, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f06c0=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 438, + "top": 1623, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f1ynk=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfuteg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 423, + "top": 1683, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f212E=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfuteg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 409, + "top": 1684, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f3s5c=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfuteg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 450, + "top": 1680, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f4ln4=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfv/lw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 396, + "top": 1577, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f5q6U=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfv/lw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 384, + "top": 1583, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f6cyo=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfv/lw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 422, + "top": 1566, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsC4M3f7Urg=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfuteg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsC4M3f8wRw=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfv/lw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "tail": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "lineStyle": 1, + "points": "444:1711;405:1555", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsC4M3fycW0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsC4M3fz5ec=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsC4M3f06c0=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsC4M3f1ynk=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsC4M3f212E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsC4M3f3s5c=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsC4M3f4ln4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsC4M3f5q6U=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsC4M3f6cyo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsC4M3f7Urg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsC4M3f8wRw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5SsEjzYKBxwU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5SsEjzYKCPow=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5SsEjzYKD6b8=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -976, + "top": -688, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsEjzYKE6p4=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 458, + "top": 1363.5, + "width": 129, + "height": 13, + "text": "提示用户是否删除数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsEjzYKFVEY=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -976, + "top": -688, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsEjzoKGCs4=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -976, + "top": -688, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 453, + "top": 1356.5, + "width": 140, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsEjzYKD6b8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5SsEjzYKE6p4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5SsEjzYKFVEY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsEjzoKGCs4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5SsEjzoKHLwk=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5SsEjzoKIZyQ=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5SsEjzoKJIsU=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5SsEjzoKKdw8=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5SsEjzoKLM3w=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 424, + "top": 1352, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5SsEjzoKHLwk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5SsEjzoKIZyQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5SsEjzoKJIsU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5SsEjzoKKdw8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5SsEjzoKLM3w=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsGTy4vXB4s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vYy/Y=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "font": "Arial;13;0", + "left": 425, + "top": 1438, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 1, + "text": "+有数据" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vZaQY=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 436, + "top": 1429, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4va5YE=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 473, + "top": 1455, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vbO0E=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vUxm0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 416, + "top": 1483, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vcDBs=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vUxm0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 406, + "top": 1473, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vdZI0=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vUxm0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 435, + "top": 1502, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4veUmo=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vVaZ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 481, + "top": 1393, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vfcb0=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vVaZ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 469, + "top": 1387, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vgVyo=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vVaZ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 506, + "top": 1405, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsGTy4vhc58=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vUxm0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsGTy4vi4qg=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vVaZ0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "tail": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "lineStyle": 1, + "points": "413:1519;509:1387", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsGTy4vYy/Y=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsGTy4vZaQY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsGTy4va5YE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsGTy4vbO0E=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsGTy4vcDBs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsGTy4vdZI0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsGTy4veUmo=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsGTy4vfcb0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsGTy4vgVyo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsGTy4vhc58=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsGTy4vi4qg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsIvCJpX8B4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpYDgw=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 691, + "top": 909, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpZ1dU=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 677, + "top": 903, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpaoIQ=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 718, + "top": 920, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpb9qM=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pUHxM=" + }, + "font": "Arial;13;0", + "left": 488, + "top": 1315, + "width": 72.22798156738281, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 2, + "text": "+忽略or取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpcPdE=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pUHxM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 513, + "top": 1308, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpd7pc=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pUHxM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 548, + "top": 1329, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpeUhk=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pVSwc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 503, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpfq/M=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pVSwc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 845, + "top": 500, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpgY1s=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pVSwc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 885, + "top": 509, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsIvCJphgMc=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pUHxM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsIvCJpi0FU=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pVSwc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "lineStyle": 1, + "points": "529:1351;882:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsIvCJpYDgw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsIvCJpZ1dU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsIvCJpaoIQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsIvCJpb9qM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsIvCJpcPdE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsIvCJpd7pc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsIvCJpeUhk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsIvCJpfq/M=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsIvCJpgY1s=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsIvCJphgMc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsIvCJpi0FU=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5SsKfZ6cz6GA=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5SsKfZ6c0cw0=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5SsKfZ6c1If0=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1504, + "top": -1264, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsKfZ6c22jM=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 188, + "top": 1195.5, + "width": 62, + "height": 13, + "text": "执行测量" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsKfZ6c3y80=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1504, + "top": -1264, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsKfZ6c4/6w=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1504, + "top": -1264, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 183, + "top": 1188.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsKfZ6c1If0=" + }, + "nameLabel": { + "$ref": "AAAAAAF5SsKfZ6c22jM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5SsKfZ6c3y80=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsKfZ6c4/6w=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5SsKfZ6c53s4=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5SsKfZ6c6ce4=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5SsKfZ6c7vSY=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5SsKfZ6c8vrI=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5SsKfZ6c9w5g=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 168, + "top": 1184, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5SsKfZ6c53s4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5SsKfZ6c6ce4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5SsKfZ6c7vSY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5SsKfZ6c8vrI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5SsKfZ6c9w5g=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsLOnqvSnF4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvT9Zc=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "font": "Arial;13;0", + "left": 272, + "top": 1370, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 1, + "text": "+无数据" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvUkow=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 282, + "top": 1377, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvVLTQ=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 322, + "top": 1355, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvWnnM=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvP3jk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 364, + "top": 1497, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvXr5I=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvP3jk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 351, + "top": 1501, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvYxHA=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvP3jk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 390, + "top": 1488, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOn6vZ9lI=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvQ0Oc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 227, + "top": 1242, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOn6vaP/I=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvQ0Oc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": 1251, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOn6vbXrc=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvQ0Oc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 249, + "top": 1226, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsLOn6vcdQk=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvP3jk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsLOn6vdxGs=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvQ0Oc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "tail": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "lineStyle": 1, + "points": "390:1519;228:1219", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsLOnqvT9Zc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsLOnqvUkow=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsLOnqvVLTQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsLOnqvWnnM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsLOnqvXr5I=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsLOnqvYxHA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsLOn6vZ9lI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsLOn6vaP/I=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsLOn6vbXrc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsLOn6vcdQk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsLOn6vdxGs=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsLnBK6bZAc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6cpAA=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "font": "Arial;13;0", + "left": 333, + "top": 1292, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 1, + "text": "+确定删除" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6d5AU=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 355, + "top": 1305, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6eFBA=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 377, + "top": 1265, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6fMJY=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6Y5d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 459, + "top": 1345, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6gP4A=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6Y5d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 450, + "top": 1356, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6hs3M=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6Y5d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 476, + "top": 1323, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6ibt8=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6ZnVU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 266, + "top": 1238, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6j9qo=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6ZnVU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 262, + "top": 1251, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6kw2A=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6ZnVU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 275, + "top": 1212, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsLnBK6lciw=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6Y5d4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsLnBK6mW+g=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6ZnVU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "tail": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "lineStyle": 1, + "points": "489:1351;251:1219", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsLnBK6cpAA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsLnBK6d5AU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsLnBK6eFBA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsLnBK6fMJY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsLnBK6gP4A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsLnBK6hs3M=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsLnBK6ibt8=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsLnBK6j9qo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsLnBK6kw2A=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsLnBK6lciw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsLnBK6mW+g=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Ssd41L4Ykm8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4Zqt8=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "font": "Arial;13;0", + "left": 298, + "top": 715, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 1, + "text": "+测量成功" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4aA68=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 312, + "top": 711, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4bzG4=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 356, + "top": 722, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4cBd0=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4V+18=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 215, + "top": 1148, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4dOJQ=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4V+18=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 202, + "top": 1142, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4eN6A=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4V+18=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 240, + "top": 1159, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4fb84=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4WIjg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 440, + "top": 282, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4gSW0=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4WIjg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 427, + "top": 281, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4hw20=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4WIjg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 468, + "top": 285, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ssd41L4iA10=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4V+18=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ssd41L4jXng=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4WIjg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "tail": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "lineStyle": 1, + "points": "223:1183;462:267", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Ssd41L4Zqt8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ssd41L4aA68=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ssd41L4bzG4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Ssd41L4cBd0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Ssd41L4dOJQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Ssd41L4eN6A=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Ssd41L4fb84=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Ssd41L4gSW0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Ssd41L4hw20=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Ssd41L4iA10=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Ssd41L4jXng=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Sseu4cD3uPk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Sseu4cD4dEc=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Sseu4sD5D+g=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1472, + "top": -1600, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sseu4sD6WNI=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "font": "Arial;13;1", + "left": 340, + "top": 1067.5, + "width": 98, + "height": 13, + "text": "SurveyorFailure" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sseu4sD7TeQ=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1472, + "top": -1600, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sseu4sD8OGM=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1472, + "top": -1600, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 335, + "top": 1060.5, + "width": 108.9853515625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Sseu4sD5D+g=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Sseu4sD6WNI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Sseu4sD7TeQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Sseu4sD8OGM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Sseu4sD98rM=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Sseu4sD+mh8=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Sseu4sD/yw4=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Sseu4sEAhqQ=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Sseu4sEB2Lc=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 312, + "top": 1056, + "width": 154, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Sseu4sD98rM=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Sseu4sD+mh8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Sseu4sD/yw4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Sseu4sEAhqQ=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Sseu4sEB2Lc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsfL8MfWulU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfXyQI=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "font": "Arial;13;0", + "left": 264, + "top": 1119, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 1, + "text": "+测量失败" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfYdR0=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 284, + "top": 1107, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfZubw=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 312, + "top": 1142, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfaQ2g=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fTiS4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 253, + "top": 1149, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfbsfE=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fTiS4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 247, + "top": 1137, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfcKqA=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fTiS4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 266, + "top": 1173, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfdMu0=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fU9Fc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 334, + "top": 1088, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfexH0=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fU9Fc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 324, + "top": 1079, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MffFqI=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fU9Fc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 354, + "top": 1108, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsfL8Mfg/Q0=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fTiS4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsfL8MfhnlI=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fU9Fc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "tail": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "lineStyle": 1, + "points": "242:1183;364:1091", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsfL8MfXyQI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsfL8MfYdR0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsfL8MfZubw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsfL8MfaQ2g=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsfL8MfbsfE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsfL8MfcKqA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsfL8MfdMu0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsfL8MfexH0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsfL8MffFqI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsfL8Mfg/Q0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsfL8MfhnlI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Sst98wwqqgM=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Sst98wwrk5U=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Sst98wwsBT0=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 48, + "top": -160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sst98wwtbtQ=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 1652, + "top": 51.5, + "width": 62, + "height": 13, + "text": "是否闭合" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sst98wwumLc=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 48, + "top": -160, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sst98wwvQ7M=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 48, + "top": -160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1647, + "top": 44.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Sst98wwsBT0=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Sst98wwtbtQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Sst98wwumLc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Sst98wwvQ7M=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Sst98www8Oc=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Sst98wwx3u0=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Sst98wwya8E=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Sst98wwzlK8=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Sst98ww0Wjc=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1632, + "top": 40, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Sst98www8Oc=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Sst98wwx3u0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Sst98wwya8E=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Sst98wwzlK8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Sst98ww0Wjc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsvDEBJ5KNQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ65LU=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1525, + "top": 68, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ7LZg=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1522, + "top": 53, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ8W1Y=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1530, + "top": 97, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ9rec=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ2t9o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1447, + "top": 85, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ+YlY=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ2t9o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1446, + "top": 71, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ/9rs=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ2t9o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1448, + "top": 112, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBKANc8=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ3GSY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1602, + "top": 52, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBKBIh8=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ3GSY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1597, + "top": 40, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDERKCEpk=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ3GSY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1612, + "top": 78, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsvDERKDUNc=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ2t9o=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsvDERKE66g=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ3GSY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "tail": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "lineStyle": 1, + "points": "1425:111;1631:68", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsvDEBJ65LU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsvDEBJ7LZg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsvDEBJ8W1Y=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsvDEBJ9rec=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsvDEBJ+YlY=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsvDEBJ/9rs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsvDEBKANc8=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsvDEBKBIh8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsvDERKCEpk=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsvDERKDUNc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsvDERKE66g=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Ssw/NBbRxlk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Ssw/NBbSF2M=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Ssw/NBbTP+M=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1440, + "top": 192, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ssw/NBbUxMs=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "font": "Arial;13;1", + "left": 1249, + "top": 251.5, + "width": 124, + "height": 13, + "text": "checkHalfCycleZero" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ssw/NBbVQpo=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1440, + "top": 192, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ssw/NBbW1cU=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1440, + "top": 192, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1244, + "top": 244.5, + "width": 134.28076171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ssw/NBbTP+M=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Ssw/NBbUxMs=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Ssw/NBbVQpo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ssw/NBbW1cU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Ssw/NBbXko4=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Ssw/NBbYUF0=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Ssw/NBbZSlY=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Ssw/NBbaO/g=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Ssw/NBbbK8k=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1216, + "top": 240, + "width": 190, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Ssw/NBbXko4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Ssw/NBbYUF0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Ssw/NBbZSlY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Ssw/NBbaO/g=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Ssw/NBbbK8k=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsxY9RsnmvY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9Rso3zw=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "font": "Arial;13;0", + "left": 1493, + "top": 164, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 1, + "text": "+否" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RspvS0=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1510, + "top": 177, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9Rsq3L8=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1488, + "top": 137, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9Rsrf8M=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BskgpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1633, + "top": 94, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RssvXQ=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BskgpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1637, + "top": 107, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9Rstlgw=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BskgpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1624, + "top": 68, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RsuHms=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9Bsl5Tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1372, + "top": 233, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RsvAmg=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9Bsl5Tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1381, + "top": 244, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RswFu4=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9Bsl5Tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1356, + "top": 211, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsxY9Rsx3zc=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BskgpI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsxY9Rsy0lU=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9Bsl5Tg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "tail": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "lineStyle": 1, + "points": "1649:75;1343:239", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsxY9Rso3zw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsxY9RspvS0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsxY9Rsq3L8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsxY9Rsrf8M=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsxY9RssvXQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsxY9Rstlgw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsxY9RsuHms=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsxY9RsvAmg=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsxY9RswFu4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsxY9Rsx3zc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsxY9Rsy0lU=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5SsyaiR+SygU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5SsyaiR+Tni4=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5SsyaiR+UDd8=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 256, + "top": -288, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsyaiR+VLzI=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 1775.5, + "top": 147.5, + "width": 77, + "height": 13, + "text": "执行归零检测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsyaiR+WGNM=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 256, + "top": -288, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsyaiR+XOgU=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 256, + "top": -288, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1770.5, + "top": 140.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsyaiR+UDd8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5SsyaiR+VLzI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5SsyaiR+WGNM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsyaiR+XOgU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5SsyaiR+YmEc=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5SsyaiR+ZFcg=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5SsyaiR+aG70=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5SsyaiR+bvEY=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5SsyaiR+c1cI=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1752, + "top": 136, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5SsyaiR+YmEc=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5SsyaiR+ZFcg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5SsyaiR+aG70=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5SsyaiR+bvEY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5SsyaiR+c1cI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SszpXCjo1EY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXCjpTBg=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "font": "Arial;13;0", + "left": 1745, + "top": 86, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 1, + "text": "+是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXCjqUQ0=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1764, + "top": 74, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjrtE4=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1738, + "top": 111, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjsrPY=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjl/+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1736, + "top": 72, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjtl3A=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjl/+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1746, + "top": 63, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjuzIY=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjl/+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1716, + "top": 91, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjvn8g=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjmncs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1776, + "top": 101, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjwGS4=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjmncs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1782, + "top": 89, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjx7DE=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjmncs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1763, + "top": 126, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SszpXSjytaQ=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjl/+8=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SszpXSjzLNw=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjmncs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "tail": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "lineStyle": 1, + "points": "1707:75;1788:135", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SszpXCjpTBg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SszpXCjqUQ0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SszpXSjrtE4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SszpXSjsrPY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SszpXSjtl3A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SszpXSjuzIY=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SszpXSjvn8g=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SszpXSjwGS4=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SszpXSjx7DE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SszpXSjytaQ=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SszpXSjzLNw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Ss0jcC4eMnU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4f1SI=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "font": "Arial;13;0", + "left": 1561, + "top": 210, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 1, + "text": "+成功" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4gpjw=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1580, + "top": 225, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4hyOQ=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1570, + "top": 181, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4ik1U=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4bSQM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1728, + "top": 179, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4j7WE=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4bSQM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1729, + "top": 193, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4kJQ0=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4bSQM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1727, + "top": 152, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4lZO0=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4cI98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1425, + "top": 242, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4mJoI=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4cI98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1430, + "top": 254, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4nP2o=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4cI98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1415, + "top": 216, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ss0jcC4oHMs=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4bSQM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ss0jcC4pyOo=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4cI98=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "tail": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "lineStyle": 1, + "points": "1751:166;1397:239", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Ss0jcC4f1SI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ss0jcC4gpjw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ss0jcC4hyOQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Ss0jcC4ik1U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Ss0jcC4j7WE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Ss0jcC4kJQ0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Ss0jcC4lZO0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Ss0jcC4mJoI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Ss0jcC4nP2o=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Ss0jcC4oHMs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Ss0jcC4pyOo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Ss1QmDKthXI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Ss1QmDKuZC4=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Ss1QmDKvWlI=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 80, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ss1QmDKwG90=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "font": "Arial;13;1", + "left": 1805, + "top": 379.5, + "width": 105, + "height": 13, + "text": "isReady2CCheck" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ss1QmDKxdQY=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 80, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ss1QmDKy1Jk=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 80, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1800, + "top": 372.5, + "width": 115.498046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ss1QmDKvWlI=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Ss1QmDKwG90=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Ss1QmDKxdQY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ss1QmDKy1Jk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Ss1QmDKzPd4=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Ss1QmDK0rgM=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Ss1QmDK1URs=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Ss1QmDK27BM=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Ss1QmTK3KzQ=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1776, + "top": 368, + "width": 163, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Ss1QmDKzPd4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Ss1QmDK0rgM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Ss1QmDK1URs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Ss1QmDK27BM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Ss1QmTK3KzQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Ss1sYzc57Aw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc6gkg=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "font": "Arial;13;0", + "left": 1826, + "top": 260, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 1, + "text": "+未成功" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc7Ydc=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1864, + "top": 257, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc8aaQ=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1820, + "top": 265, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc9oVQ=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc28DU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1835, + "top": 187, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc+1mo=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc28DU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1849, + "top": 187, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc/qfo=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc28DU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1807, + "top": 188, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzdAwEk=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc3JbA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1863, + "top": 332, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzdBh5I=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc3JbA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1876, + "top": 327, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzdCSbM=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc3JbA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1837, + "top": 342, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ss1sYzdDZ80=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc28DU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ss1sYzdEJ2M=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc3JbA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "tail": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "lineStyle": 1, + "points": "1816:171;1854:367", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Ss1sYzc6gkg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ss1sYzc7Ydc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ss1sYzc8aaQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Ss1sYzc9oVQ=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Ss1sYzc+1mo=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Ss1sYzc/qfo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Ss1sYzdAwEk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Ss1sYzdBh5I=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Ss1sYzdCSbM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Ss1sYzdDZ80=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Ss1sYzdEJ2M=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StBNjXab2vs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnack3k=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "font": "Arial;13;0", + "left": 2070, + "top": 347, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 1, + "text": "+满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnadVQY=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2098, + "top": 332, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnaesNQ=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2102, + "top": 376, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnafXzY=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaYthc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1963, + "top": 356, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnagLn4=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaYthc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1965, + "top": 342, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnah5RQ=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaYthc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1961, + "top": 384, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnaisDA=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaZel4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2236, + "top": 337, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnaj34U=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaZel4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2232, + "top": 324, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnakOhM=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaZel4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2242, + "top": 364, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StBNjnalJvg=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaYthc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StBNjnamkmI=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaZel4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "tail": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "lineStyle": 1, + "points": "1939:379;2263:357", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StBNjnack3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StBNjnadVQY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StBNjnaesNQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StBNjnafXzY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StBNjnagLn4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StBNjnah5RQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StBNjnaisDA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StBNjnaj34U=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StBNjnakOhM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StBNjnalJvg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StBNjnamkmI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5StIJ55ESsdQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5StIJ6JETau4=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5StIJ6JEUhEM=", + "_parent": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "visible": false, + "font": "Arial;13;0", + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StIJ6JEVqnE=", + "_parent": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "font": "Arial;13;1", + "left": 2051, + "top": 523.5, + "width": 96, + "height": 13, + "text": "doRecordClean" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StIJ6JEWP7E=", + "_parent": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StIJ6JEXgV0=", + "_parent": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "visible": false, + "font": "Arial;13;0", + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2046, + "top": 516.5, + "width": 106.07177734375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5StIJ6JEUhEM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5StIJ6JEVqnE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5StIJ6JEWP7E=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StIJ6JEXgV0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5StIJ6JEYF5o=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5StIJ6JEZA8U=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5StIJ6JEaYwU=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5StIJ6JEb/UM=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5StIJ6JEcyow=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2024, + "top": 512, + "width": 150, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5StIJ6JEYF5o=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5StIJ6JEZA8U=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5StIJ6JEaYwU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5StIJ6JEb/UM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5StIJ6JEcyow=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StIhp5XCuNU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XDSVA=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "font": "Arial;13;0", + "left": 1961, + "top": 438, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 1, + "text": "+不满足" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XEOe8=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1992, + "top": 425, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XFIgE=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1969, + "top": 463, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XGV44=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW/3D0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1916, + "top": 397, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XH9Wk=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW/3D0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1925, + "top": 387, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XIoUY=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW/3D0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1899, + "top": 418, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XJabQ=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppXAozs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2053, + "top": 478, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XKQI8=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppXAozs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2058, + "top": 466, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XLdHE=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppXAozs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2043, + "top": 504, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StIhp5XMnHk=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW/3D0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StIhp5XNKZI=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppXAozs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "tail": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "lineStyle": 1, + "points": "1887:403;2068:511", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StIhp5XDSVA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StIhp5XEOe8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StIhp5XFIgE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StIhp5XGV44=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StIhp5XH9Wk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StIhp5XIoUY=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StIhp5XJabQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StIhp5XKQI8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StIhp5XLdHE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StIhp5XMnHk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StIhp5XNKZI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StWKjad/ao4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjaeAOMw=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "font": "Arial;13;0", + "left": 1526, + "top": 470, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 1, + "text": "+完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjaeB8T4=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1538, + "top": 485, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeCMfI=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1549, + "top": 441, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeD8dI=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad8hyI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1722, + "top": 513, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeENZo=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad8hyI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1716, + "top": 525, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeFObw=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad8hyI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1732, + "top": 487, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeGRb0=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad96kQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1363, + "top": 427, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeHI70=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad96kQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1362, + "top": 441, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeIy1Y=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad96kQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1365, + "top": 399, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StWKjqeJDvE=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad8hyI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StWKjqeKjN0=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad96kQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "lineStyle": 1, + "points": "1751:511;1342:413", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StWKjaeAOMw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StWKjaeB8T4=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StWKjqeCMfI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StWKjqeD8dI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StWKjqeENZo=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StWKjqeFObw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StWKjqeGRb0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StWKjqeHI70=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StWKjqeIy1Y=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StWKjqeJDvE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StWKjqeKjN0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5StaqW9rGSo4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5StaqW9rHsAM=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5StaqW9rIMvI=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -448, + "top": -496, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StaqW9rJ3VU=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "fillColor": "#ffc1ad", + "font": "Arial;13;1", + "left": 1738.5, + "top": 715.5, + "width": 168, + "height": 13, + "text": "用户选择是否跳转到其他测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StaqW9rK5Uk=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -448, + "top": -496, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StaqW9rLlM4=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -448, + "top": -496, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": 1733.5, + "top": 708.5, + "width": 179, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5StaqW9rIMvI=" + }, + "nameLabel": { + "$ref": "AAAAAAF5StaqW9rJ3VU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5StaqW9rK5Uk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StaqW9rLlM4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5StaqW9rMapE=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5StaqW9rNzzg=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5StaqW9rON6o=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5StaqW9rPWX8=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5StaqW9rQ9mc=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1696, + "top": 704, + "width": 253, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5StaqW9rMapE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5StaqW9rNzzg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5StaqW9rON6o=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5StaqW9rPWX8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5StaqW9rQ9mc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StcY69+auow=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY69+bJyw=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "font": "Arial;13;0", + "left": 1815, + "top": 619, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY69+crMs=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1853, + "top": 619, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY69+d1N0=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1809, + "top": 618, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+esYw=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+XtIs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1840, + "top": 567, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+f1JY=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+XtIs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1853, + "top": 569, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+gGlM=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+XtIs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1812, + "top": 562, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+hLtM=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Yoz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1837, + "top": 671, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+i0N0=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Yoz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1850, + "top": 669, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+jJRk=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Yoz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1810, + "top": 675, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StcY7N+k7Ks=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+XtIs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StcY7N+lWqU=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Yoz0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "tail": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "lineStyle": 1, + "points": "1826:547;1822:703", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StcY69+bJyw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StcY69+crMs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StcY69+d1N0=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StcY7N+esYw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StcY7N+f1JY=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StcY7N+gGlM=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StcY7N+hLtM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StcY7N+i0N0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StcY7N+jJRk=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StcY7N+k7Ks=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StcY7N+lWqU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StecvuuYlQs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuuZ8Fw=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "font": "Arial;13;0", + "left": 1776, + "top": 1083, + "width": 98.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 1, + "text": "+跳转测回后补测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuuawiY=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1840, + "top": 1083, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuubliA=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1796, + "top": 1082, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuucS6Y=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuVcKw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1835, + "top": 759, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuudsIs=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuVcKw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1848, + "top": 762, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuueFws=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuVcKw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1807, + "top": 754, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuufPVU=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuWIOM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1816, + "top": 1407, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuugcGo=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuWIOM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1830, + "top": 1405, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuuhAqk=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuWIOM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1789, + "top": 1411, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StecvuuiooQ=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuVcKw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Stecv+uj9kw=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuWIOM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "lineStyle": 1, + "points": "1821:739;1801:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StecvuuZ8Fw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StecvuuawiY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StecvuubliA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StecvuucS6Y=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StecvuudsIs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StecvuueFws=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StecvuufPVU=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StecvuugcGo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StecvuuhAqk=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StecvuuiooQ=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Stecv+uj9kw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Stg/Ofb2A68=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb3nog=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "font": "Arial;13;0", + "left": 1315, + "top": 605, + "width": 72.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 1, + "text": "+取消or忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb45tw=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1347, + "top": 619, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb5GmI=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1358, + "top": 576, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb6tf0=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/bz2/4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1725, + "top": 704, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb78vU=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/bz2/4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1719, + "top": 717, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb8Jmw=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/bz2/4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1736, + "top": 679, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb9zNg=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/b0VQA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 978, + "top": 506, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb+I1M=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/b0VQA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 977, + "top": 519, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb/AoU=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/b0VQA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 981, + "top": 478, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Stg/OfcA1lA=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/bz2/4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Stg/OfcBL2A=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/b0VQA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "lineStyle": 1, + "points": "1754:703;957:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Stg/Ofb3nog=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Stg/Ofb45tw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Stg/Ofb5GmI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Stg/Ofb6tf0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Stg/Ofb78vU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Stg/Ofb8Jmw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Stg/Ofb9zNg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Stg/Ofb+I1M=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Stg/Ofb/AoU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Stg/OfcA1lA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Stg/OfcBL2A=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Stp87Q6fs2Y=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Stp87g6gqlw=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Stp87g6h+fQ=", + "_parent": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 864, + "top": 48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Stp87g6iB2Y=", + "_parent": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "font": "Arial;13;1", + "left": 2518.5, + "top": 819.5, + "width": 151, + "height": 13, + "text": "isSingleCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Stp87g6jrfo=", + "_parent": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 864, + "top": 48, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Stp87g6koqM=", + "_parent": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 864, + "top": 48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2513.5, + "top": 812.5, + "width": 161.708984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Stp87g6h+fQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Stp87g6iB2Y=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Stp87g6jrfo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Stp87g6koqM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Stp87g6lk/c=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Stp87g6mFIA=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Stp87g6nmy0=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Stp87g6oJMI=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Stp87g6p63M=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2480, + "top": 808, + "width": 228, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Stp87g6lk/c=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Stp87g6mFIA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Stp87g6nmy0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Stp87g6oJMI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Stp87g6p63M=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StrWhROp4Oc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROqofY=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2352, + "top": 658, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROrA94=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2360, + "top": 645, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROs2b4=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2337, + "top": 683, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROtkZ8=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOmfyU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2157, + "top": 541, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROu87A=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOmfyU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2166, + "top": 531, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROvpPg=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOmfyU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2140, + "top": 562, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROw9lc=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOnvuo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2548, + "top": 774, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROxGek=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOnvuo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2553, + "top": 762, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROy9qY=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOnvuo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2538, + "top": 800, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StrWhROzgAM=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOmfyU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StrWhRO0+cw=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOnvuo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "tail": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "lineStyle": 1, + "points": "2128:547;2563:807", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StrWhROqofY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StrWhROrA94=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StrWhROs2b4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StrWhROtkZ8=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StrWhROu87A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StrWhROvpPg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StrWhROw9lc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StrWhROxGek=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StrWhROy9qY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StrWhROzgAM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StrWhRO0+cw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Styi5hf3vEY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf45gs=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "font": "Arial;13;0", + "left": 2339, + "top": 811, + "width": 46.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 1, + "text": "+完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf51HU=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2361, + "top": 826, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf6gvA=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2365, + "top": 782, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf7rXE=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf0fJk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2451, + "top": 820, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf8B7M=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf0fJk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2448, + "top": 833, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf95Ew=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf0fJk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2458, + "top": 793, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf+T+w=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf1+Tk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2274, + "top": 804, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf/4I4=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf1+Tk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2275, + "top": 817, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hgAAcY=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf1+Tk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2272, + "top": 776, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Styi5hgBznc=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf0fJk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Styi5hgCPb4=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf1+Tk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "tail": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "lineStyle": 1, + "points": "2479:814;2250:793", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Styi5hf45gs=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Styi5hf51HU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Styi5hf6gvA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Styi5hf7rXE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Styi5hf8B7M=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Styi5hf95Ew=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Styi5hf+T+w=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Styi5hf/4I4=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Styi5hgAAcY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Styi5hgBznc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Styi5hgCPb4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5St1uUR+q0qc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+rshY=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "font": "Arial;13;0", + "left": 2182, + "top": 1146, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+sGjw=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2214, + "top": 1158, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+t4JQ=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2186, + "top": 1123, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+uiWE=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+nHko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2559, + "top": 864, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+v1Ig=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+nHko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2565, + "top": 876, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+wJBc=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+nHko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2545, + "top": 840, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+xuEc=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+oJAQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1852, + "top": 1428, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+yEoo=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+oJAQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1862, + "top": 1437, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+zGSA=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+oJAQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1832, + "top": 1409, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5St1uUR+02pE=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+nHko=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5St1uUR+1/EE=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+oJAQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "lineStyle": 1, + "points": "2570:843;1823:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5St1uUR+rshY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5St1uUR+sGjw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5St1uUR+t4JQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5St1uUR+uiWE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5St1uUR+v1Ig=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5St1uUR+wJBc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5St1uUR+xuEc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5St1uUR+yEoo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5St1uUR+zGSA=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5St1uUR+02pE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5St1uUR+1/EE=" + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5nMrk1mLCw=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "check2C", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P5saV03F9So=", + "_parent": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5saV03GReQ=", + "_parent": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5saV03HrLQ=", + "_parent": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "reference": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P56tf07Epig=", + "_parent": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P56tgE7F7Yk=", + "_parent": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P56tgE7GNNA=", + "_parent": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5rmBE2WOV0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "recordClean" + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5P5vlT04vpIc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "用户选择操作" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P56LY06KFIA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【用户选择操作】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P5/ask/ASWM=", + "_parent": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "name": "选择忽略or重测目标", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5/ask/BASE=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5/ask/CwwU=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6ETu1Fsgo0=", + "_parent": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "name": "重测测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6ETu1FtUvs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6ETu1Fuzfc=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5/CAk96MB0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "Idle" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6Btl1DQYFs=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【提示用户是否确定删除整个测回】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6HZl1I+eIg=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "name": "选择忽略or取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6HZl1I/u/s=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6HZl1JAt1Q=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6Jc6FP89fs=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "name": "确认删除", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6Jc6FP9Ay0=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6Jc6FP+W/w=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "reference": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6IYDFMK28k=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【执行删除操作】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6KuWFYuLA4=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6KuWFYvXto=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "reference": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6KuWFYwtmg=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6I/oFN00qM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重新搜索目标开启新一轮测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJXgiQky2RI=", + "_parent": { + "$ref": "AAAAAAF5P6I/oFN00qM=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJXgiQkzVQM=", + "_parent": { + "$ref": "AAAAAAF5QJXgiQky2RI=" + }, + "reference": { + "$ref": "AAAAAAF5P6I/oFN00qM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJXgiQk0kU4=", + "_parent": { + "$ref": "AAAAAAF5QJXgiQky2RI=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJWvCggxZrM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "move2NextValidate", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVWv2lZqu2A=", + "_parent": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVWv2lZro+8=", + "_parent": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVWv2lZs/XI=", + "_parent": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJc4CA2m0sA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkHalfCycleZero", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJesYRAUeZI=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "name": "测站不闭合or半测回归零差正常", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJesYRAV/Pw=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "reference": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJesYRAWIno=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "reference": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJmQwBdscKg=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "name": "没有通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJmQwBdt/Nk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "reference": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJmQwBdu0wk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "reference": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJeXAw9WAQQ=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isReady2CCheck" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJjLZBMJQJ8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2StandStill", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJnk3RnjFKU=", + "_parent": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnk3Rnk4S8=", + "_parent": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnk3Rnlvxc=", + "_parent": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJk5ohVWyGc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示半测回归零检测失败", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJnHsRkKHYc=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnHsRkLdTo=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "reference": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnHsRkM5N4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ6ahSPVJNg=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkReadData", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ87Oyj+dCg=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "name": "单测量or通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ87Oyj/TJQ=", + "_parent": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ87OykA4RY=", + "_parent": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "reference": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ/Ugywh52g=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/Ugywiha4=", + "_parent": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/UgywjRPE=", + "_parent": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "reference": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ8m8Sf4R1w=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isHalfCycleZeroCheckReady", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsvDEBJ10hk=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsvDEBJ2t9o=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "reference": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsvDEBJ3GSY=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "reference": { + "$ref": "AAAAAAF5Sst98gwopLY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ+mRitXafY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示读数有误", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ/0PCz+xYo=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/0PCz/2CU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "reference": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/0PC0AjHo=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKE6OTfx/D4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QKI4y0KDGow=", + "_parent": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKI4zEKEuw8=", + "_parent": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKI4zEKFtZg=", + "_parent": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "reference": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QKvMIE8VEZE=", + "_parent": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKvMIE8WKCE=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKvMIE8XsG8=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKIG+T9Wjdo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isAllCycleCompleted", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StWKjad7sNs=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "name": "完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StWKjad8hyI=", + "_parent": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "reference": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StWKjad96kQ=", + "_parent": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StcY69+Wpu4=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StcY69+XtIs=", + "_parent": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "reference": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StcY69+Yoz0=", + "_parent": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "reference": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + } + } + } + ] + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5QKJM6UPX41c=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseSubject1" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKuCwkzWMuI=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户选择", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QK2Ql1lrW/0=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "name": "忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK2Ql1lsCzU=", + "_parent": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK2Ql1ltUBY=", + "_parent": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QLdiW2HmZcI=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLdiW2HnzLc=", + "_parent": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLdiW2HodP8=", + "_parent": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "reference": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMnaf4pzXpA=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMnaf4p0R7o=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMnaf4p1n0A=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKyR6VB8Gq8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重测方向", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QLx6RGoJ91g=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLx6RGoKxZI=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "reference": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLx6RGoLs1U=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKysH1F2Xh8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重测测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QNAhapFq3kM=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "name": "取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNAhapFrudc=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNAhapFsZZ8=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QNFL6qCXEtU=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "name": "忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNFL6qCY2AQ=", + "_parent": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNFL6qCZ01s=", + "_parent": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVcwNF0hcaI=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVcwNF0iVWE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVcwNF0jQf0=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "reference": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKzDRVJwpI4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "resetSurveyorStateAndKeepPosition", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QK340l0BzRk=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK340l0ChAw=", + "_parent": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK340l0D79M=", + "_parent": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QLwOJ2bN7N0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "resurveyPoints", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMbzEHNMUo0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "开始重测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMbzEHNNh8o=", + "_parent": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMbzEHNOm6M=", + "_parent": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLGeneralization", + "_id": "AAAAAAF5QMevPnTKBWs=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "重测失败", + "source": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "target": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVTunkvVKUs=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "重测失败", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVTun0vWQ0U=", + "_parent": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVTun0vXr0g=", + "_parent": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QMaQUG/pf+g=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2RestartInCurrentCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMjEpoXtFac=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMjEpoXuicM=", + "_parent": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMjEpoXvKNs=", + "_parent": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RVbpp1nIOnU=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行测回删除", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVdEqWBKDgY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVdEqWBL2Ro=", + "_parent": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "reference": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVdEqWBMaWs=", + "_parent": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWbWh5Q82SE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doCalScheduleSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWkDr6/4piw=", + "_parent": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWkDr6/5hKI=", + "_parent": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "reference": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWkDr6/6Fyk=", + "_parent": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + } + } + } + ] + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5RWdznZ2YK/Q=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseSubject2" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWiYh6tdXHE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "该测回是否完成测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWmAObifwr4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWmAObigyuY=", + "_parent": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWmAObih5u0=", + "_parent": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWqc8svr3pE=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "name": "完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWqc8svs8AE=", + "_parent": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWqc8svtE1U=", + "_parent": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWo+Icga7No=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行单测回检测", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWvJyNWC314=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWvJyNWDYLg=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWvJyNWEI/s=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWxGx9n5fHg=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWxGx9n6uSs=", + "_parent": { + "$ref": "AAAAAAF5RWxGx9n5fHg=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWxGx9n7A0k=", + "_parent": { + "$ref": "AAAAAAF5RWxGx9n5fHg=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXgsE81LcLM=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "通过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXgsE81Ml9Y=", + "_parent": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXgsE81Ncj4=", + "_parent": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWzzg+QnXQo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doCalScheduleAllCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXS1D5dDHCY=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXS1D5dEJJs=", + "_parent": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "reference": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXS1D5dF2N4=", + "_parent": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RXZT3reRJjE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "是否是doCalScheduleAllCycle状态", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXiiW9aJDaw=", + "_parent": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "name": "不是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXiiW9aKkno=", + "_parent": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXiiW9aL3M4=", + "_parent": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX50xeaOm84=", + "_parent": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "name": "是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX50xeaPW6s=", + "_parent": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX50xeaQJxA=", + "_parent": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX4IzeDinbw=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有待补测数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX9EYPFbm2U=", + "_parent": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX9EYPFcd3k=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX9EYPFdtmc=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYXKoEPvmVE=", + "_parent": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYXKoUPwWeY=", + "_parent": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYXKoUPxCsE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX8e8+6Tpi8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户选择", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYA6LQaqG8I=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "name": "跳转到相应测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYA6LQaryvU=", + "_parent": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYA6LQashgM=", + "_parent": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "reference": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYRxIiqJIUE=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "name": "忽略或取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYRxIyqKuUY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYRxIyqLN6Y=", + "_parent": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX+92vrrsgo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "切换测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX/wMv3F6d4=", + "_parent": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX/wMv3GM64=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "reference": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX/wMv3HIz8=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RYWBNT536bM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有空数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYbKCEsJsiQ=", + "_parent": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYbKCEsKkG0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYbKCEsLR+0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYqgkaOybww=", + "_parent": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "name": "无空测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYqgkaOzOcA=", + "_parent": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYqgkaO0Gyw=", + "_parent": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RYo1sJrxVxU=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回合法性", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYuGza0vDqU=", + "_parent": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "name": "发现有测回未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYuGza0wl4I=", + "_parent": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYuGza0xzjs=", + "_parent": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RY5M4rVOVIM=", + "_parent": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "name": "全部通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY5M4rVPReU=", + "_parent": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY5M4rVQGdM=", + "_parent": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RY+P3cq56es=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2Idle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RY/lWtHqafY=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY/lW9Hrql4=", + "_parent": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY/lW9HsN84=", + "_parent": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZAQp9i7BLM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "查找待补测数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZDsue7baAw=", + "_parent": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZDsue7cAPs=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZDsue7dBLs=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZE5JvvgNmk=", + "_parent": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZE5Jvvh7eI=", + "_parent": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZE5JvviTz0=", + "_parent": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZEXNfhA9nA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "查找空数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZGEZgj773A=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZGEZgj8gpI=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZGEZgj9p0E=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZHb+g34JOw=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZHb+g35LNk=", + "_parent": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZHb+g36Mvo=", + "_parent": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZ6XBTi4yu4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doMoveBack" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Sr6mm1dGVLo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doSurveyor", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsC4Mnft0S4=", + "_parent": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsC4Mnfuteg=", + "_parent": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "reference": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsC4Mnfv/lw=", + "_parent": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "reference": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Sr+CM2b/I6Q=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有正在测量数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsGTyovTQIg=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "name": "有数据", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsGTy4vUxm0=", + "_parent": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "reference": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsGTy4vVaZ0=", + "_parent": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "reference": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsLOnqvOHTI=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "name": "无数据", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsLOnqvP3jk=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "reference": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsLOnqvQ0Oc=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "reference": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5SsEjzYJ/d3I=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户是否删除数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsIvB5pTO8k=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsIvB5pUHxM=", + "_parent": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "name": "忽略or取消", + "reference": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsIvB5pVSwc=", + "_parent": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsLnA66XUCE=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "name": "确定删除", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsLnBK6Y5d4=", + "_parent": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "reference": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsLnBK6ZnVU=", + "_parent": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "reference": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5SsKfZqcx8QM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Ssd4074UW6o=", + "_parent": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "name": "测量成功", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ssd41L4V+18=", + "_parent": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "reference": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ssd41L4WIjg=", + "_parent": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsfL78fSWbs=", + "_parent": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "name": "测量失败", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsfL78fTiS4=", + "_parent": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "reference": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsfL78fU9Fc=", + "_parent": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "reference": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5SsdYcrYFUTc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkReadData" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Sseu4cD1ALY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "SurveyorFailure" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Sst98gwopLY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "是否闭合", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsxY9BsjL0w=", + "_parent": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "name": "否", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsxY9BskgpI=", + "_parent": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "reference": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsxY9Bsl5Tg=", + "_parent": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "reference": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SszpXCjkGRI=", + "_parent": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "name": "是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SszpXCjl/+8=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "reference": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SszpXCjmncs=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "reference": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Ssw/MxbPNVc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkHalfCycleZero" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5SsyaiR+Q8s8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行归零检测", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Ss0jcC4aijg=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "name": "成功", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ss0jcC4bSQM=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "reference": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ss0jcC4cI98=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "reference": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Ss1sYzc1nBg=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "name": "未成功", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ss1sYzc28DU=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "reference": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ss1sYzc3JbA=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "reference": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Ss1QlzKrDlo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isReady2CCheck", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StBNjXaXraA=", + "_parent": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StBNjXaYthc=", + "_parent": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "reference": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StBNjXaZel4=", + "_parent": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StIhppW+/2s=", + "_parent": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "name": "不满足", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StIhppW/3D0=", + "_parent": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "reference": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StIhppXAozs=", + "_parent": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "reference": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Ss//822MKvk=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "check2C" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5StIJ5pEQ/FY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doRecordClean", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StrWhBOl298=", + "_parent": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StrWhBOmfyU=", + "_parent": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "reference": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StrWhBOnvuo=", + "_parent": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "reference": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5StaqWtrE9ro=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "用户选择是否跳转到其他测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StecvuuUiTw=", + "_parent": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "name": "跳转测回后补测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StecvuuVcKw=", + "_parent": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "reference": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StecvuuWIOM=", + "_parent": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Stg/N/byEbA=", + "_parent": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "name": "取消or忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Stg/N/bz2/4=", + "_parent": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "reference": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Stg/N/b0VQA=", + "_parent": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Stp87A6d2HY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isSingleCycleCompleted", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Styi5Rfz3o0=", + "_parent": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "name": "完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Styi5Rf0fJk=", + "_parent": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "reference": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Styi5Rf1+Tk=", + "_parent": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5St1uUR+mHuk=", + "_parent": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5St1uUR+nHko=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "reference": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5St1uUR+oJAQ=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + } + ] + }, + { + "_type": "UMLProfile", + "_id": "AAAAAAFElnEzslS1AuE=", + "_parent": { + "$ref": "AAAAAAFElm5XMFNoGY0=" + }, + "name": "UMLStandardProfile", + "ownedElements": [ + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFElnFUQFS4mT4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "StandardProfileL2", + "ownedViews": [ + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFElnFrT1S8vVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnFrT1S9WOE=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "model": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1S+aHM=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1S/1HM=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 57, + "top": 59, + "width": 81, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TAD0M=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 57, + "top": 73, + "width": 81, + "height": 12, + "text": "UMLClassifier" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TBaUI=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TCF/Y=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 52, + "top": 52, + "width": 91, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnFrT1S/1HM=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnFrT1TAD0M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnFrT1TBaUI=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnFrT1TCF/Y=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 52, + "top": 52, + "width": 91, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFElnF1nFTadPw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqCEfLOas=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnF1nFTbplQ=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTcCng=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTd3xg=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 213, + "top": 55, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTewJM=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 213, + "top": 69, + "width": 83, + "height": 12, + "text": "Realization" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTfQRQ=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTgrV8=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 48, + "width": 93, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnF1nVTd3xg=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnF1nVTewJM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnF1nVTfQRQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnF1nVTgrV8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFElnF1nVThfqA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 86, + "width": 93, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFElnF1nVTiFXA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 96, + "width": 93, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFElnF1nVTjasU=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 48, + "width": 93, + "height": 38, + "nameCompartment": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFElnF1nVThfqA=" + }, + "operationCompartment": { + "$ref": "AAAAAAFElnF1nVTiFXA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqCEfLOas=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFElnF1nVTjasU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFElnGGLFUGHnM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUH+8s=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 174, + "top": 73, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUIOR8=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": null, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 174, + "top": 88, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUJv6k=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 175, + "top": 43, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "head": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "tail": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "points": "208:64;142:64", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFElnGGLFUH+8s=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFElnGGLFUIOR8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnGGLFUJv6k=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFElnJRglVMyB8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqCkfpKls=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnJRglVN/RI=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVO7ow=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVPiBM=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 217, + "top": 119, + "width": 74.73593139648438, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVQT1k=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 217, + "top": 133, + "width": 74.73593139648438, + "height": 12, + "text": "Specification" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVRdk8=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVSFic=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 112, + "width": 84.73593139648438, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnJRglVPiBM=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnJRglVQT1k=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnJRglVRdk8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnJRglVSFic=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFElnJRglVTXPE=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 150, + "width": 84, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFElnJRglVUe0c=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 160, + "width": 84, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFElnJRg1VVWNU=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 112, + "width": 84.73593139648438, + "height": 38, + "nameCompartment": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFElnJRglVTXPE=" + }, + "operationCompartment": { + "$ref": "AAAAAAFElnJRglVUe0c=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqCkfpKls=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFElnJRg1VVWNU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFElnKVuVV5hVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV6VLo=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 176, + "top": 141, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV7m9U=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 176, + "top": 156, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV8bvU=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 177, + "top": 111, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "head": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "tail": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "points": "212:132;142:132", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFElnKVuVV6VLo=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFElnKVuVV7m9U=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnKVuVV8bvU=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFJsZbpDNpnkE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFJsZbpTNq6XM=", + "_parent": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNrbHw=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 561, + "top": 209, + "width": 87, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNsdGc=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 561, + "top": 223, + "width": 87, + "height": 12, + "text": "UMLClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNtikk=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 1500, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNuOXU=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 1500, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 556, + "top": 204, + "width": 97, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFJsZbpTNrbHw=" + }, + "nameLabel": { + "$ref": "AAAAAAFFJsZbpTNsdGc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFJsZbpTNtikk=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFJsZbpTNuOXU=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 556, + "top": 204, + "width": 97, + "height": 305, + "nameCompartment": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwKqhJFq1z2Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKqhJFq2eQM=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "model": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq3hUU=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 57, + "top": 209, + "width": 79, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq4Vb4=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 57, + "top": 223, + "width": 79, + "height": 12, + "text": "UMLArtifact" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq5GlQ=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq6Fls=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 52, + "top": 204, + "width": 89, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKqhJFq3hUU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKqhJFq4Vb4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKqhJFq5GlQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKqhJFq6Fls=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 52, + "top": 204, + "width": 89, + "height": 329, + "nameCompartment": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKsvdVrTyNI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDUglDBo=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKsvdVrUE8w=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrVvYg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 237, + "top": 209, + "width": 119, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrW/Dg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "font": "Arial;12;3", + "containerExtending": true, + "left": 237, + "top": 223, + "width": 119, + "height": 12, + "text": "File" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrXXrQ=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 48, + "top": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrYnv8=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 48, + "top": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 232, + "top": 204, + "width": 129, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKsvdVrVvYg=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKsvdVrW/Dg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKsvdVrXXrQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKsvdVrYnv8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKsvdVrZA0U=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 248, + "top": 236, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKsvdlraVvA=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 248, + "top": 236, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKsvdlrbd2U=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 32, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 232, + "top": 204, + "width": 129, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKsvdVrZA0U=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKsvdlraVvA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDUglDBo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKsvdlrbd2U=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKtwS1r8DQQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDUg7My0=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKtwS1r9YJ4=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1r+fw8=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 313, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1r/Lsw=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 189, + "top": 327, + "width": 72.51593017578125, + "height": 12, + "text": "Document" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1sAGYA=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 24, + "top": 24, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1sB7y4=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 24, + "top": 24, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKtwS1r+fw8=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKtwS1r/Lsw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKtwS1sAGYA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKtwS1sB7y4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKtwTFsC02k=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 192, + "top": 352, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKtwTFsD5lc=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 192, + "top": 352, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKtwTFsEQlE=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 16, + "top": 16, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKtwTFsC02k=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKtwTFsD5lc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDUg7My0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKtwTFsEQlE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuBulskCVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDkhRFFg=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuBulsld0g=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBulsmb/s=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 257, + "top": 357, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBulsnKBI=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 257, + "top": 371, + "width": 72.51593017578125, + "height": 12, + "text": "Executable" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBu1soKF0=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBu1spOXA=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "top": 352, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuBulsmb/s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuBulsnKBI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuBu1soKF0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuBu1spOXA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuBu1sqPhk=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 284, + "top": 372, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuBu1srnoE=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 284, + "top": 372, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuBu1ssVVg=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 64, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "top": 352, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuBu1sqPhk=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuBu1srnoE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDkhRFFg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuBu1ssVVg=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuIMltMJw4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqD0hnnhc=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuIMltNJK8=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tO63M=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 321, + "top": 405, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tPj60=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 321, + "top": 419, + "width": 72.51593017578125, + "height": 12, + "text": "Library" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tQD7A=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 132, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tRSSY=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 132, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 316, + "top": 400, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuIM1tO63M=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuIM1tPj60=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuIM1tQD7A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuIM1tRSSY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuIM1tSiN4=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 360, + "top": 400, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuIM1tTPjo=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 360, + "top": 400, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuIM1tUHbM=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 88, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 316, + "top": 400, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuIM1tSiN4=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuIM1tTPjo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqD0hnnhc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuIM1tUHbM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuS0lt0dAE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqEEh93KM=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuS0lt1+MM=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt2XgE=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 385, + "top": 453, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt36r8=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 385, + "top": 467, + "width": 72.51593017578125, + "height": 12, + "text": "Script" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt4pP4=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 180, + "top": -180, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt5mi4=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 180, + "top": -180, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 448, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuS0lt2XgE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuS0lt36r8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuS0lt4pP4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuS0lt5mi4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuS0lt6gjg=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 424, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuS0lt7fo0=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 424, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuS0lt8w2A=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -120, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 448, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuS0lt6gjg=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuS0lt7fo0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqEEh93KM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuS0lt8w2A=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKueMluc5bE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqEUiTykw=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKueMludFfk=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMlueAco=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 445, + "top": 501, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMluflfo=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 445, + "top": 515, + "width": 72.51593017578125, + "height": 12, + "text": "Source" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMlughos=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMluhfws=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 496, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKueMlueAco=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKueMluflfo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKueMlughos=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKueMluhfws=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKueMluihu4=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 500, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKueMlujEyo=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 500, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKueMlukJo8=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 496, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKueMluihu4=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKueMlujEyo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqEUiTykw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKueMlukJo8=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzkslvYVdw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzkslvZbd0=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 267, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzks1vasdU=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 252, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzks1vby/c=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 297, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "points": "216:308;216:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzkslvZbd0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzks1vasdU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzks1vby/c=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzsCVvpt2A=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvqAUg=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 285, + "top": 289, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvrTi8=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 270, + "top": 289, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvsewQ=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 314, + "top": 290, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "points": "300:352;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzsCVvqAUg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzsCVvrTi8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzsCVvsewQ=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzxcVv6A2c=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv7wpA=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 327, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv8NxM=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 327, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv9X58=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 328, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "points": "356:400;356:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzxcVv7wpA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzxcVv8NxM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzxcVv9X58=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKz3OVwLl+8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwMNB4=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 357, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwNd3E=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 357, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwODiI=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 358, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "points": "416:448;416:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKz3OVwMNB4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKz3OVwNd3E=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKz3OVwODiI=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKz9mVwcos8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVwdsGc=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 391, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVweYvs=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 391, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVwfOSk=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 392, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "points": "484:496;484:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKz9mVwdsGc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKz9mVweYvs=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKz9mVwfOSk=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4k1VxFxwI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxGUvg=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 161, + "top": 333, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxHABk=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 161, + "top": 348, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxIpIg=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 162, + "top": 303, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "points": "184:324;140:324", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4k1lxGUvg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4k1lxHABk=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4k1lxIpIg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4o4VxWQBI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxXVGc=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 195, + "top": 378, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxYgZc=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 195, + "top": 393, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxZqsQ=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 196, + "top": 348, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "points": "252:369;140:369", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4o4VxXVGc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4o4VxYgZc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4o4VxZqsQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4tiVxnpno=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxoTEk=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 227, + "top": 429, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxpG0I=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 227, + "top": 444, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxqKIY=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 228, + "top": 399, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "points": "316:420;140:420", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4tiVxoTEk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4tiVxpG0I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4tiVxqKIY=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK41YVx4sZw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx5rZ4=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 259, + "top": 473, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx6mfE=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 259, + "top": 488, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx7lFo=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 443, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "points": "380:464;140:464", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK41YVx5rZ4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK41YVx6mfE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK41YVx7lFo=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK47MFyJhkk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MFyKeH8=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 289, + "top": 521, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MVyL2Gg=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 289, + "top": 536, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MVyMJyk=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 290, + "top": 491, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "points": "440:512;140:512", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK47MFyKeH8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK47MVyL2Gg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK47MVyMJyk=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK5AeFyarms=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeFybX8s=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 185, + "top": 229, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeFycm2c=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 185, + "top": 244, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeVydbSU=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 186, + "top": 199, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "points": "232:220;140:220", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK5AeFybX8s=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK5AeFycm2c=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK5AeVydbSU=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwK/k1ly1mNU=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwK/k1ly236Y=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "model": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k1ly3kes=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 385, + "top": 585, + "width": 132, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k1ly4Kb0=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 385, + "top": 599, + "width": 132, + "height": 12, + "text": "UMLBehavioralFeature" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k11y5jis=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 972, + "top": 60, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k11y6pH4=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 972, + "top": 60, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 580, + "width": 142, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK/k1ly3kes=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwK/k1ly4Kb0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwK/k11y5jis=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK/k11y6pH4=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 580, + "width": 142, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLBdPFzSzQk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqFkkF9pQ=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLBdPFzT/sk=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzUtqg=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 589, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzVTVM=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 603, + "width": 72.51593017578125, + "height": 12, + "text": "Destroy" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzWXGg=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": 24, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzX7Kw=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": 24, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 584, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLBdPFzUtqg=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLBdPFzVTVM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLBdPFzWXGg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLBdPFzX7Kw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLBdPFzYl0A=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 632, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLBdPFzZMKQ=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 632, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLBdPFzaqUA=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 80, + "top": 16, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 584, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLBdPFzYl0A=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLBdPFzZMKQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqFkkF9pQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLBdPFzaqUA=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLDMaFz6CG0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz7zuA=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 579, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz8JJ4=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 564, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz92bU=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 609, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "tail": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "points": "318:600;380:600", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLDMaFz7zuA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLDMaFz8JJ4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLDMaFz92bU=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLFUbV0ScDI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqF0kiyCM=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLFUbV0TTdY=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0UvYs=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 209, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0V4oU=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 223, + "width": 72.51593017578125, + "height": 12, + "text": "Auxiliary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0WLEA=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -336, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0XEPg=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -336, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 204, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLFUbV0UvYs=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLFUbV0V4oU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLFUbV0WLEA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLFUbV0XEPg=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLFUbV0YxWc=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 128, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLFUbV0Z3Xk=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 128, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLFUbV0aLJo=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -224, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 204, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLFUbV0YxWc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLFUbV0Z3Xk=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqF0kiyCM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLFUbV0aLJo=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLFu9F06sWk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGEk49nc=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLFu9F07mo0=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F08FIY=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 261, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F09Ig0=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 275, + "width": 72.51593017578125, + "height": 12, + "text": "Focus" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F0+sYU=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -420, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F0/2cA=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -420, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 256, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLFu9F08FIY=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLFu9F09Ig0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLFu9F0+sYU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLFu9F0/2cA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLFu9F1A690=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 152, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLFu9F1BAsU=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 152, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLFu9F1CLR8=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -280, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 256, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLFu9F1A690=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLFu9F1BAsU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGEk49nc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLFu9F1CLR8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLF4tF1iftI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGUlOO9I=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLF4tF1jr/w=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1kg2Y=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 313, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1la4E=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 327, + "width": 72.51593017578125, + "height": 12, + "text": "Metaclass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1mW9o=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -480, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1ngPk=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -480, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLF4tF1kg2Y=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLF4tF1la4E=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLF4tF1mW9o=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLF4tF1ngPk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLF4tF1oP5U=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 184, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLF4tF1pEYI=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 184, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLF4tF1qaMM=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -320, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLF4tF1oP5U=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLF4tF1pEYI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGUlOO9I=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLF4tF1qaMM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLF/G12KFPg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGUlk1Tc=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLF/G12LESY=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12MFWs=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 365, + "width": 121, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12Nq6M=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 379, + "width": 121, + "height": 12, + "text": "ImplementationClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12OWK0=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -564, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12PipY=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -564, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 360, + "width": 131, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLF/G12MFWs=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLF/G12Nq6M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLF/G12OWK0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLF/G12PipY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLF/G12QJs8=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 208, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLF/G12Rf8c=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 208, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLF/HF2Sm8E=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -376, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 360, + "width": 131, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLF/G12QJs8=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLF/G12Rf8c=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGUlk1Tc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLF/HF2Sm8E=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLGEPF2y6SI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqHEl6Zbo=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLGEPF2zyUI=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF20OuI=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 421, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF21TcM=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 435, + "width": 72.51593017578125, + "height": 12, + "text": "Type" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF22f/8=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -624, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF23oz0=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -624, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 416, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLGEPF20OuI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLGEPF21TcM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLGEPF22f/8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLGEPF23oz0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLGEPF24D5Y=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 244, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLGEPF252Tg=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 244, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLGEPF26r38=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -416, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 416, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLGEPF24D5Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLGEPF252Tg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqHEl6Zbo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLGEPF26r38=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLGI813a/Lo=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqHEmQAJ4=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLGI813bmDw=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3c6dc=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 477, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3dgjo=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 491, + "width": 72.51593017578125, + "height": 12, + "text": "Utility" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3eWQw=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -672, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3fVUI=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -672, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 472, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLGI9F3c6dc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLGI9F3dgjo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLGI9F3eWQw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLGI9F3fVUI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLGI9F3g9+w=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 284, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLGI9F3hmIE=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 284, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLGI9F3i+8k=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -448, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 472, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLGI9F3g9+w=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLGI9F3hmIE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqHEmQAJ4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLGI9F3i+8k=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNej158NLk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej1590I0=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 233, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej15+8jc=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 248, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej15/BRY=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 203, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "points": "720:224;652:224", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNej1590I0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNej15+8jc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNej15/BRY=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNkZ16NQ/Q=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16OhBQ=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 281, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16PBtY=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 296, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16QvLQ=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 251, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "points": "720:272;652:272", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNkZ16OhBQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNkZ16PBtY=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNkZ16QvLQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNn916eDZQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916fvYQ=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 333, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916guUU=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 348, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916hjhM=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 303, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "points": "720:324;652:324", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNn916fvYQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNn916guUU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNn916hjhM=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNr116vKpE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116weUM=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 385, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116xjvo=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 400, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116yGN0=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 355, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "points": "720:376;652:376", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNr116weUM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNr116xjvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNr116yGN0=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNvdl7AF7U=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17Byl0=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 442, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17Cmyo=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 457, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17DduQ=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 412, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "points": "720:433;652:433", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNvd17Byl0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNvd17Cmyo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNvd17DduQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLN0fl7RscA=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0fl7SzeE=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 498, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0fl7Tq3c=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 513, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0f17UptI=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 468, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "points": "720:489;652:489", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLN0fl7SzeE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLN0fl7Tq3c=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLN0f17UptI=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwLRECl7stC8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLRECl7tsQE=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7u5vE=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 545, + "width": 92.85594177246094, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7vrCk=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 559, + "width": 92.85594177246094, + "height": 12, + "text": "UMLComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7wqHs=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7xJrI=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 540, + "width": 102.85594177246094, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLRECl7u5vE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLRECl7vrCk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLRECl7wqHs=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLRECl7xJrI=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 540, + "width": 102.85594177246094, + "height": 261, + "nameCompartment": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLR8CV8I99Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqH0nfZIU=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLR8CV8JFWY=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8Knxc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 549, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8LWIw=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 563, + "width": 72.51593017578125, + "height": 12, + "text": "Entity" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8Mvqc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8NdIc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 544, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLR8CV8Knxc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLR8CV8LWIw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLR8CV8Mvqc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLR8CV8NdIc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLR8CV8OpVY=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 748, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLR8CV8PW8k=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 748, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLR8Cl8QCTM=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 336, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 544, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLR8CV8OpVY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLR8CV8PW8k=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqH0nfZIU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLR8Cl8QCTM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSByF8w+gI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIEn1Irc=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSByF8x/Yc=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF8yMLo=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 597, + "width": 88.67578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF8zspI=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 611, + "width": 88.67578125, + "height": 12, + "text": "Implementation" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF80AnU=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 420, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF81b24=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 420, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 592, + "width": 98.67578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSByF8yMLo=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSByF8zspI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSByF80AnU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSByF81b24=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSByF82e10=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 768, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSByF83aE4=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 768, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSByF84G88=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 280, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 592, + "width": 98.67578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSByF82e10=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSByF83aE4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIEn1Irc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSByF84G88=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSIN19Ytdk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIUoLdrY=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSIN19ZQ0U=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9a8kE=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 653, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9bYBg=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 667, + "width": 72.51593017578125, + "height": 12, + "text": "Process" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9cqZQ=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 348, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9dI5U=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 348, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 648, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSIOF9a8kE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSIOF9bYBg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSIOF9cqZQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSIOF9dI5U=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSIOF9ekq0=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 800, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSIOF9fibc=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 800, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSIOF9gUN0=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 232, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 648, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSIOF9ekq0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSIOF9fibc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIUoLdrY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSIOF9gUN0=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSO/1+AoeQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIkohl1g=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSO/1+BWGA=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSO/1+CG1s=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 709, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSO/1+DoUc=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 723, + "width": 72.51593017578125, + "height": 12, + "text": "Service" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSPAF+EVIo=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 312, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSPAF+FZR8=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 312, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 704, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSO/1+CG1s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSO/1+DoUc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSPAF+EVIo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSPAF+FZR8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSPAF+GnaI=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 844, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSPAF+Ho/s=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 844, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSPAF+I3E8=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 704, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSPAF+GnaI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSPAF+Ho/s=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIkohl1g=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSPAF+I3E8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSXP1+o0Kw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIko3HYE=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSXP1+peko=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+qR3g=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 765, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+rnfg=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 779, + "width": 72.51593017578125, + "height": 12, + "text": "Subsystem" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+sqCM=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+t4Mc=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 760, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSXP1+qR3g=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSXP1+rnfg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSXP1+sqCM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSXP1+t4Mc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSXP1+uKrA=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 880, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSXP1+vdxM=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 880, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSXP1+woFc=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 760, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSXP1+uKrA=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSXP1+vdxM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIko3HYE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSXP1+woFc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLV9gV/Ybio=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gV/Z8CU=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 569, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gl/a23I=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 584, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gl/b3BU=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 539, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "points": "720:560;658:560", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLV9gV/Z8CU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLV9gl/a23I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLV9gl/b3BU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWA0V/pWEg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/q2AI=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 621, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/rrYc=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 636, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/spgM=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 591, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "points": "720:612;658:612", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWA0V/q2AI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWA0V/rrYc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWA0V/spgM=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWEUV/6d1E=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/78Ig=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 677, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/8eIM=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 692, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/9T0A=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 647, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "points": "720:668;658:668", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWEUV/78Ig=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWEUV/8eIM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWEUV/9T0A=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWIQWALE8M=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWAMDo8=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 737, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWANo/A=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 752, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWAO6qA=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 707, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "points": "720:728;658:728", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWIQWAMDo8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWIQWANo/A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWIQWAO6qA=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWMgWAcaQw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAd1rc=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 789, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAeZ8k=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 804, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAfxqc=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 759, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "points": "720:780;658:780", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWMgWAd1rc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWMgWAeZ8k=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWMgWAfxqc=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwL2WeWA5NQI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL2WeGA460g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL2WeWA62bI=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "model": { + "$ref": "AAAAAAFFwL2WeGA460g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA7mnk=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 61, + "top": 649, + "width": 98, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA8/Wk=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 61, + "top": 663, + "width": 98, + "height": 12, + "text": "UMLDependency" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA9NaM=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 144, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA+CiM=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 144, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 56, + "top": 644, + "width": 108, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL2WeWA7mnk=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL2WeWA8/Wk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL2WeWA9NaM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL2WeWA+CiM=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 56, + "top": 644, + "width": 108, + "height": 277, + "nameCompartment": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL4D0mBZIkY=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJkp/rUc=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL4D0mBaqmw=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D0mBbBNE=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 649, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D0mBc7go=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 663, + "width": 69.380859375, + "height": 12, + "text": "Create" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D02Bd3+g=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D02BeWA8=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 644, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL4D0mBbBNE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL4D0mBc7go=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL4D02Bd3+g=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL4D02BeWA8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL4D02Bf0q0=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 664, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL4D02BgYs8=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 664, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL4D02BhsHw=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 644, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL4D02Bf0q0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL4D02BgYs8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJkp/rUc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL4D02BhsHw=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL4h4WCCAAY=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJ0qVBvA=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL4h4WCD82Y=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCE1YI=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 713, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCFbHY=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 727, + "width": 69.380859375, + "height": 12, + "text": "Call" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCG+Bo=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCHhD8=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 708, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL4h4mCE1YI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL4h4mCFbHY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL4h4mCG+Bo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL4h4mCHhD8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL4h4mCIEqs=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 708, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL4h4mCJktQ=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 708, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL4h4mCKdqI=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 708, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL4h4mCIEqs=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL4h4mCJktQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJ0qVBvA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL4h4mCKdqI=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL45WWCr3cU=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJ0qrDxY=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL45WWCsDkc=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCtTBI=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 769, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCuTW0=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 783, + "width": 69.380859375, + "height": 12, + "text": "Instantiate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCv18Q=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -192, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCwZzE=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -192, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 764, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL45WWCtTBI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL45WWCuTW0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL45WWCv18Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL45WWCwZzE=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL45WWCxsuk=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 736, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL45WmCy+mU=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 736, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL45WmCzW1Y=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -128, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 764, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL45WWCxsuk=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL45WmCy+mU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJ0qrDxY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL45WmCzW1Y=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL5hQGDUxa0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKErBHOc=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL5hQGDVSBg=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDWrwI=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 825, + "width": 82.013671875, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDXPFU=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 839, + "width": 82.013671875, + "height": 12, + "text": "Responsibility" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDYpi0=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDZAt8=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 820, + "width": 92.013671875, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL5hQGDWrwI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL5hQGDXPFU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL5hQGDYpi0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL5hQGDZAt8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL5hQGDa1nY=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 772, + "width": 91, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL5hQGDbixI=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 772, + "width": 91, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL5hQGDcuS4=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 820, + "width": 92.013671875, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL5hQGDa1nY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL5hQGDbixI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKErBHOc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL5hQGDcuS4=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL7KdWEqew0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKErXxgY=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL7KdWEr60A=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEspPc=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 881, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEt7g0=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 895, + "width": 69.380859375, + "height": 12, + "text": "Send" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEum1Q=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -324, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEv3Yk=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -324, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 876, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL7KdWEspPc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL7KdWEt7g0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL7KdWEum1Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL7KdWEv3Yk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL7KdWEwzHc=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 804, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL7KdWExRWs=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 804, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL7KdWEyL0Q=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -216, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 876, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL7KdWEwzHc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL7KdWExRWs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKErXxgY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL7KdWEyL0Q=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+LCGFgCjw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFhp5w=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 634, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFihK4=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 619, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFjcmE=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 664, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "tail": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "points": "314:655;380:655", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+LCGFhp5w=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+LCGFihK4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+LCGFjcmE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+O8GFxUF4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GFyCzY=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 677, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GFzT+A=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 692, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GF0qhg=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 647, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "points": "236:668;163:668", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+O8GFyCzY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+O8GFzT+A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+O8GF0qhg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+SkWGC/a4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGDbeA=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 731, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGEkxM=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 746, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGFVnU=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 701, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "points": "236:722;163:722", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+SkWGDbeA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+SkWGEkxM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+SkWGFVnU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+WL2GTesQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GUDZ4=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 797, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GVfH8=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 812, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GW4Ys=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 767, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "points": "236:788;163:788", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+WL2GUDZ4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+WL2GVfH8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+WL2GW4Ys=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+Z72GkT5Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72GllyU=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 854, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72Gm6K8=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 869, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72GnawI=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 824, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "points": "236:845;163:845", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+Z72GllyU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+Z72Gm6K8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+Z72GnawI=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+eh2G1gXM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G2oXg=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 910, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G3GpE=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 925, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G4woY=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 880, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "points": "236:901;163:901", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+eh2G2oXg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+eh2G3GpE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+eh2G4woY=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwMFq1GHZe+E=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMFq1GHa5CM=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "model": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHbxIU=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 33, + "width": 93, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHc3zA=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 47, + "width": 93, + "height": 12, + "text": "UMLAbstraction" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHdTFI=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHeicg=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 28, + "width": 103, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMFq1GHbxIU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMFq1GHc3zA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMFq1GHdTFI=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMFq1GHeicg=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 28, + "width": 103, + "height": 153, + "nameCompartment": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGle2H29zI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKksmed8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGle2H3I+8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H4B8s=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 29, + "width": 110.396484375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H5FWo=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 43, + "width": 110.396484375, + "height": 12, + "text": "Derive" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H6wQw=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H7ifs=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 24, + "width": 120.396484375, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGle2H4B8s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGle2H5FWo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGle2H6wQw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGle2H7ifs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGle2H8ZWU=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFFwMJPAWJ40Vg=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H8ZWU=" + }, + "model": { + "$ref": "AAAAAAFFwMJO92J1Y/s=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 65, + "width": 110.396484375, + "height": 12, + "text": "+computation: String", + "horizontalAlignment": 0 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 60, + "width": 127.16787719726562, + "height": 22 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGle2H9VL8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 824, + "top": 60, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGle2H+hpQ=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 24, + "width": 120.396484375, + "height": 58, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGle2H8ZWU=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGle2H9VL8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKksmed8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGle2H+hpQ=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGo6mIepMc=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqK0s9CwU=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGo6mIfS5g=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIgcys=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 101, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIha40=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 115, + "width": 69.380859375, + "height": 12, + "text": "Refine" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIiGvE=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 276, + "top": 120, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIjVCs=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 276, + "top": 120, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 96, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGo6mIgcys=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGo6mIha40=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGo6mIiGvE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGo6mIjVCs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGo6mIkY0Y=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 832, + "top": 172, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGo6mIlYhc=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 832, + "top": 172, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGo6mImbZE=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 80, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 96, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGo6mIkY0Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGo6mIlYhc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqK0s9CwU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGo6mImbZE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGrimJGJ0s=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqK0tTuyw=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGrimJHZ7Y=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJIfxU=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 153, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJJ7uc=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 167, + "width": 69.380859375, + "height": 12, + "text": "Trace" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJKI9M=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 324, + "top": 168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJL3ag=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 324, + "top": 168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 148, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGrimJIfxU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGrimJJ7uc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGrimJKI9M=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGrimJL3ag=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGrimJMCIQ=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 848, + "top": 240, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGrimJNPbE=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 848, + "top": 240, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGrimJOkXc=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 112, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 148, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGrimJMCIQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGrimJNPbE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqK0tTuyw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGrimJOkXc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLTm2KEAI0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KFRRg=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 61, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KGrkQ=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 76, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KHZTE=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 31, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "points": "740:52;658:52", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLTm2KFRRg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLTm2KGrkQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLTm2KHZTE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLXQmKVDuM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKW+3c=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 121, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKXpUQ=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 136, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKYWOg=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 91, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "points": "740:112;658:112", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLXQmKW+3c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLXQmKXpUQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLXQmKYWOg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLbmmKmAvI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKnMuM=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 169, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKonTw=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 184, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKpbLQ=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 139, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "points": "740:160;658:160", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLbmmKnMuM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLbmmKonTw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLbmmKpbLQ=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwMYNEWK8jeA=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMYNEWK9Wb8=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "model": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWK++fU=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 833, + "width": 91, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWK/PY8=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 847, + "width": 91, + "height": 12, + "text": "UMLPackage" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWLAHjA=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWLBm9I=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 828, + "width": 101, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMYNEWK++fU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMYNEWK/PY8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMYNEWLAHjA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMYNEWLBm9I=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 828, + "width": 101, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMdnrWLZAY8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqLUuNRhM=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMdnrWLaXkY=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLbib0=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 729, + "top": 837, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLclU4=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 729, + "top": 851, + "width": 72.51593017578125, + "height": 12, + "text": "Framework" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLdBNU=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLeF4I=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 832, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMdnrmLbib0=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMdnrmLclU4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMdnrmLdBNU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMdnrmLeF4I=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMdnrmLf950=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 868, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMdnrmLgzek=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 878, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMdnrmLhmpQ=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 832, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMdnrmLf950=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMdnrmLgzek=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqLUuNRhM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMdnrmLhmpQ=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMeIHGMCTCk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqLUujT3E=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMeIHGMDiPY=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMEN4g=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 729, + "top": 893, + "width": 75.345703125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMFxQc=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 729, + "top": 907, + "width": 75.345703125, + "height": 12, + "text": "ModelLibrary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMG6CQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -60, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMH2dQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -60, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 888, + "width": 85.345703125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMeIHGMEN4g=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMeIHGMFxQc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMeIHGMG6CQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMeIHGMH2dQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMeIHGMI7hI=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 904, + "width": 85, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMeIHGMJi90=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 914, + "width": 85, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMeIHGMK1pc=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -40, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 888, + "width": 85.345703125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMeIHGMI7hI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMeIHGMJi90=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqLUujT3E=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMeIHGMK1pc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMevo2Mq4Ew=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2Mr7wQ=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 861, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2Msv/w=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 876, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2MtL5c=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 690, + "top": 831, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "tail": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "points": "724:852;656:852", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMevo2Mr7wQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMevo2Msv/w=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMevo2MtL5c=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMe0G2M7rmg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M8gls=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 917, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M9WEg=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 932, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M+CD8=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 690, + "top": 887, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "tail": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "points": "724:908;656:908", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMe0G2M8gls=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMe0G2M9WEg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMe0G2M+CD8=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFElnFrT1S7Kic=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLClassifier" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFElnF1nFTY/Sw=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Realization", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFElnGGLFUFZFA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "source": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "target": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFElnF1nFTZHOU=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFElnJRglVKSoc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Specification", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFElnKVuVV4pBU=", + "_parent": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "source": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "target": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFElnJRglVLifA=", + "_parent": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFJsYgDTM+Z6E=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "entity", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFJsZx3DOCac8=", + "_parent": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "source": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFJsYgDTM/qY8=", + "_parent": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "width": 40, + "height": 40, + "content": "var w = rect.getWidth(),\n m = w / 10;\ncanvas.fillEllipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.ellipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.line(rect.x1 + m, rect.y2 - m, rect.x2 - m, rect.y2 - m);\n" + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFJsZbpDNobIs=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLClass" + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwKqhJFq06mA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLArtifact" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKsvdVrRJUQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "File", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK5AeFyZpVg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "source": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "isAbstract": true, + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKsvdVrSLo0=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKtwS1r6wew=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Document", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzkslvX4gU=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "source": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4k1VxEEpM=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "source": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKtwS1r7XqE=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuBulsidLQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Executable", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzsCVvo11g=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4o4VxVx00=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuBulsjhp0=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuIMltKnQQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Library", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzxcVv56Dg=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4tiVxmVJM=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuIMltLkmg=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuS0ltysPk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Script", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKz3OVwK9hs=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "source": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK41YVx3Hr0=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "source": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuS0ltz9pw=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKueMVuaLXM=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Source", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKz9mFwbfDg=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "source": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK47MFyIL/c=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "source": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKueMlubedY=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwK/k1ly00Ec=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLBehavioralFeature" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLBdO1zQosE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Destroy", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLDMaFz5C14=", + "_parent": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "source": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "target": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLBdO1zR7Ak=", + "_parent": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLFUbV0QQVA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Auxiliary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNej157D6Y=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "source": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLFUbV0RoPU=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLFu8104he4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Focus", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNkZ16Mp7Y=", + "_parent": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "source": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLFu9F05JGE=", + "_parent": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLF4tF1g4No=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Metaclass", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNn916d4Yc=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "source": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLF4tF1h94I=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLF/G12IJ54=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "ImplementationClass", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNr116u93k=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "source": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLF/G12JIns=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLGEO12wqJ8=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Type", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNvdl6/WJI=", + "_parent": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "source": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLGEPF2x7bg=", + "_parent": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLGI813YL3s=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Utility", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLN0fl7QL9o=", + "_parent": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "source": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLGI813ZPxY=", + "_parent": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFFwLKxU14QPaE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Robustness Stereotypes", + "ownedViews": [ + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLL0NF4VWXk=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMEwRREE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLL0NF4WzoE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4X88I=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 89, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4YSt8=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 103, + "width": 72.51593017578125, + "height": 12, + "text": "entity" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4ZQaQ=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -1065, + "top": -270, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4asxs=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -1065, + "top": -270, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 84, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLL0NF4X88I=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLL0NF4YSt8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLL0NF4ZQaQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLL0NF4asxs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLL0NF4bgXg=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 92, + "top": -28, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLL0NF4cZ88=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 92, + "top": -18, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLL0NF4dJaE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -710, + "top": -180, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 84, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLL0NF4bgXg=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLL0NF4cZ88=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMEwRREE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLL0NF4dJaE=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwLMO8l44tWU=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLMO8l45ook=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l46Nac=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 33, + "top": 33, + "width": 79, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l47xu4=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 33, + "top": 47, + "width": 79, + "height": 12, + "text": "UMLClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l48V+s=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -489, + "top": -414, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l490+g=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -489, + "top": -414, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 28, + "top": 28, + "width": 89, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLMO8l46Nac=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLMO8l47xu4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLMO8l48V+s=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLMO8l490+g=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 28, + "top": 28, + "width": 89, + "height": 149, + "nameCompartment": { + "$ref": "AAAAAAFFwLMO8l45ook=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLMO814+17w=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO814/vLk=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 109, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO815A2sw=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 124, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO815BAcU=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 79, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "points": "212:100;116:100", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLMO814/vLk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLMO815A2sw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLMO815BAcU=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwx8Q/35wG9A=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMUw9MBk=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwx8Q/35xpyY=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/35yVU8=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 37, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/35z0VE=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 51, + "width": 72.51593017578125, + "height": 12, + "text": "control" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/3506PU=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -336, + "top": -312, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/351cP0=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -336, + "top": -312, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 32, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwx8Q/35yVU8=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwx8Q/35z0VE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwx8Q/3506PU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwx8Q/351cP0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwx8RAH52xko=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 76, + "top": -4, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwx8RAH53MWs=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 76, + "top": 6, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwx8RAH54kik=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -224, + "top": -208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 32, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwx8RAH52xko=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwx8RAH53MWs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMUw9MBk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwx8RAH54kik=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwyAHeH6a9yk=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6b9JY=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 61, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6cKyY=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 76, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6dvIk=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 31, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "points": "212:52;116:52", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwyAHeX6b9JY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwyAHeX6cKyY=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwyAHeX6dvIk=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFw0h1/QXNqo4=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMkxa+TA=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFw0h1/gXOBI4=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXPA/w=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 141, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXQ/LI=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 155, + "width": 72.51593017578125, + "height": 12, + "text": "boundary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXRrB4=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -360, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXSVgA=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -360, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 136, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFw0h1/gXPA/w=" + }, + "nameLabel": { + "$ref": "AAAAAAFFw0h1/gXQ/LI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFw0h1/gXRrB4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFw0h1/gXSVgA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFw0h1/gXTCRY=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -20, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFw0h1/gXUu1g=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -10, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFw0h1/gXVEL8=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 64, + "top": -240, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 136, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFw0h1/gXTCRY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFw0h1/gXUu1g=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMkxa+TA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFw0h1/gXVEL8=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFw0o5p5IVMGM=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IW5Js=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 165, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IXSKA=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 180, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IY/GE=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 135, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "points": "212:156;116:156", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFw0o5p5IW5Js=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFw0o5p5IXSKA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFw0o5p5IY/GE=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwLRECl7r1R4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLComponent" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLR8CF8G68k=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Entity", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLV9gV/Xhk4=", + "_parent": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "source": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLR8CF8HOik=", + "_parent": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSByF8umMo=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Implementation", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWA0V/olVk=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "source": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSByF8vzKA=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSIN19WMnE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Process", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWEUV/5Qq4=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "source": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSIN19XVng=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSO/19+cMY=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Service", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWIQWAKKPo=", + "_parent": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "source": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSO/19/YUk=", + "_parent": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSXP1+mTVk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Subsystem", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWMgWAb2Sk=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "source": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSXP1+njeI=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwL2WeGA460g=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLDependency" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL4D0mBXwu4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Create", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+LCGFfPQs=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "source": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "target": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+O8GFwbog=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "source": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL4D0mBYXVU=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL4h4WCAEkg=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Call", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+SkWGBCOg=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "source": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL4h4WCBKPU=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL45WWCpJ0o=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Instantiate", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+WL2GScgY=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "source": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL45WWCq/8I=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL5hP2DSEFk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Responsibility", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+Z72GjzGw=", + "_parent": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "source": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL5hQGDTCjI=", + "_parent": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL7KdWEoDhA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Send", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+eh2G01aU=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "source": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL7KdWEpx8M=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwMFq1GHYSKM=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLAbstraction" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGlemH0Tq8=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Derive", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLTmmKDF1M=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "source": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFFwMJO92J1Y/s=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "name": "computation", + "type": "String" + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGlemH1M8k=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGo6mIcITc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Refine", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLXQmKUyu0=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "source": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGo6mIdBMU=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGrimJEvvk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Trace", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLbmmKloGE=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "source": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGrimJF+z8=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwMYNEWK7ItA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLPackage" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMdnrWLXWLA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Framework", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMevo2MpIU4=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "source": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "target": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMdnrWLYFcM=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMeIHGMAPDc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "ModelLibrary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMe0G2M69PQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "source": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "target": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMeIHGMBKKk=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFFwQCuI7bLjDk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "StandardProfileL3", + "ownedViews": [ + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwQHC9rbwK6A=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQHC9rbx7Lo=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "model": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rbyTUQ=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 45, + "top": 121, + "width": 107, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rbzlgQ=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 45, + "top": 135, + "width": 107, + "height": 12, + "text": "UMLModel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rb0L9g=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rb1XIk=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 116, + "width": 117, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQHC9rbyTUQ=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQHC9rbzlgQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQHC9rb0L9g=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQHC9rb1XIk=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 116, + "width": 117, + "height": 97, + "nameCompartment": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQHjjbcLQPM=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqN0zJrS0=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQHjjbcMlRY=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcNrIk=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 41, + "width": 115, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcOnWs=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 55, + "width": 115, + "height": 12, + "text": "BuildComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcPLIM=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcQOtc=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 36, + "width": 125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQHjjbcNrIk=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQHjjbcOnWs=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQHjjbcPLIM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQHjjbcQOtc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQHjjrcRsYI=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 56, + "width": 105, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQHjjrcSCoc=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 66, + "width": 105, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQHjjrcTWEY=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 36, + "width": 125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQHjjrcRsYI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQHjjrcSCoc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqN0zJrS0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQHjjrcTWEY=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQIPLLc0Q7M=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqOEzfvr8=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQIPLLc1jrg=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc2rps=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 121, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc3wdo=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 135, + "width": 83, + "height": 12, + "text": "Metamodel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc4SHA=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -84, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc5Qvc=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -84, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 116, + "width": 93, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQIPLLc2rps=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQIPLLc3wdo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQIPLLc4SHA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQIPLLc5Qvc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQIPLLc63qc=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 124, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQIPLbc7y2w=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 134, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQIPLbc8jC8=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -56, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 116, + "width": 93, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQIPLLc63qc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQIPLbc7y2w=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqOEzfvr8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQIPLbc8jC8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQIrDLddK/I=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqOEz1SWk=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQIrDLdevJE=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdfcec=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 181, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdgsTM=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 195, + "width": 83, + "height": 12, + "text": "SystemModel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdhAR0=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdiiuQ=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 176, + "width": 93, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQIrDLdfcec=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQIrDLdgsTM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQIrDLdhAR0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQIrDLdiiuQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQIrDLdjYt8=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 264, + "top": 156, + "width": 88, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQIrDLdkEoo=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 264, + "top": 166, + "width": 88, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQIrDLdlkbo=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 80, + "top": -112, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 176, + "width": 93, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQIrDLdjYt8=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQIrDLdkEoo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqOEz1SWk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQIrDLdlkbo=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQLOH7eRZzI=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOH7eSzo8=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 145, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOILeTl4U=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 160, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOILeU1qE=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 115, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "tail": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "points": "224:136;156:136", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQLOH7eSzo8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQLOILeTl4U=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQLOILeU1qE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQLSp7eim6s=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7ejdqM=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 205, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7ekT+I=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 220, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7el67w=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 175, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "tail": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "points": "224:196;156:196", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQLSp7ejdqM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQLSp7ekT+I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQLSp7el67w=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwQdYRLfPnZs=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQdYRLfQc8o=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfPnZs=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfRm/U=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 45, + "top": 41, + "width": 107, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfSwyU=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 45, + "top": 55, + "width": 107, + "height": 12, + "text": "UMLComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfTyV4=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -702, + "top": -954, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfUafY=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -702, + "top": -954, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 36, + "width": 117, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQdYRLfRm/U=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQdYRLfSwyU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQdYRLfTyV4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQdYRLfUafY=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 36, + "width": 117, + "height": 41, + "nameCompartment": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQgwnLf7u0w=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnLf82nE=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 64, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnbf9bFo=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 79, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnbf+ckE=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 34, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQdYRLfPnZs=" + }, + "tail": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "lineStyle": 1, + "points": "223:55;157:55", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQgwnLf82nE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQgwnbf9bFo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQgwnbf+ckE=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwQHC9rbvUkk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLModel" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQHjjbcJ4Ks=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "BuildComponent", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQgwnLf6Q+0=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "source": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQHjjbcKYjk=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQIPLLcykEY=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Metamodel", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQLOH7eQuvE=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "source": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "target": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQIPLLcz/1A=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQIrDLdbTko=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "SystemModel", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQLSp7eh5o0=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "source": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "target": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQIrDLdcjKw=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwx8Q/35u/80=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "control", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwyAHeH6Znas=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "source": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwx8Q/35vMf0=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "width": 40, + "height": 40, + "content": "var w = rect.getWidth(),\n h = w / 2,\n m = w / 8;\ncanvas.fillEllipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.ellipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.line(rect.x1 + h, rect.y1 + m, rect.x1 + h + m, rect.y1);\ncanvas.line(rect.x1 + h, rect.y1 + m, rect.x1 + h + m, rect.y1 + 2 * m);\n" + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFw0h1/QXL978=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "boundary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFw0o5ppIUB2s=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "source": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFw0h1/QXM/ss=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "width": "50", + "height": 40, + "content": "var w = rect.getWidth(),\n h = rect.getHeight(),\n m = w / 5;\ncanvas.fillEllipse(rect.x1 + m, rect.y1, rect.x2, rect.y2);\ncanvas.ellipse(rect.x1 + m, rect.y1, rect.x2, rect.y2);\ncanvas.line(rect.x1, rect.y1, rect.x1, rect.y2);\ncanvas.line(rect.x1, rect.y1 + h/2, rect.x1 + m, rect.y1 + h/2);\n" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..c8f43e2 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,276 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\Users\Administrator\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} +-keepclassmembers class * { + public (org.json.JSONObject); +} +-keep public class cn.liuyanbing.surveyor.R$*{ +public static final int *; +} +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} +#混淆前后的映射 +-printmapping mapping.txt + +-keep class androidx.appcompat.widget.SearchView { *; } +-keep class cn.aigestudio.datepicker.**{*;} + +-dontwarn javax.** + +-keep class com.tencent.mm.sdk.** { + *; +} + +-dontwarn com.tencent.** +-keep class com.tencent.** {*;} + +-ignorewarnings + +# Apache POI +-dontwarn org.apache.** +-dontwarn org.openxmlformats.schemas.** +-dontwarn org.etsi.** +-dontwarn org.w3.** +-dontwarn com.microsoft.schemas.** +-dontwarn com.fasterxml.** +-dontwarn javax.naming.** +-dontwarn java.lang.management.** +-dontwarn org.slf4j.impl.** + +-dontnote org.apache.** +-dontnote org.openxmlformats.schemas.** +-dontnote org.etsi.** +-dontnote org.w3.** +-dontnote com.microsoft.schemas.** +-dontnote com.fasterxml.** +-dontnote javax.naming.** +-dontnote java.lang.management.** +-dontnote org.slf4j.impl.** + +-keeppackagenames org.apache.poi.ss.formula.function + +-keep class org.apache.** {*;} +-keep class org.openxmlformats.** {*;} +-keep class org.etsi.** {*;} +-keep class org.w3.** {*;} +-keep class com.microsoft.** {*;} +-keep class com.fasterxml.** {*;} +-keep class schemaorg_apache_xmlbeans.** {*;} + +# ------------------------ leancloud sdk ------------------------ +-keepattributes Signature +-dontwarn com.jcraft.jzlib.** +-keep class com.jcraft.jzlib.** { *;} + +-dontwarn sun.misc.** +-keep class sun.misc.** { *;} + +-dontwarn alibaba.fastjson.** +-dontnote alibaba.fastjson.** +-keep class alibaba.fastjson.** { *;} + +-dontwarn sun.security.** +-keep class sun.security.** { *; } + +-dontwarn com.google.** +-keep class com.google.** { *;} + +-dontwarn com.avos.** +-dontnote com.avos.** +-keep class com.avos.** { *;} + +-dontwarn cn.leancloud.** +-dontnote cn.leancloud.** +-keep class cn.leancloud.** { *;} + +-keep public class android.net.http.SslError +-keep public class android.webkit.WebViewClient + +-dontwarn android.webkit.WebView +-dontwarn android.net.http.SslError +-dontwarn android.webkit.WebViewClient +-dontnote android.net.http.** + +-dontwarn android.support.** + +-dontwarn org.jivesoftware.smack.** +-keep class org.jivesoftware.smack.** { *;} + +-dontwarn com.loopj.** +-keep class com.loopj.** { *;} + +-dontwarn com.squareup.okhttp.** +-keep class com.squareup.okhttp.** { *;} +-keep interface com.squareup.okhttp.** { *; } + +# keep okhttp3、okio +-dontwarn okhttp3.** +-keep class okhttp3.** { *;} +-keep interface okhttp3.** { *; } +-dontwarn okio.** + +-keep class com.google.protobuf.** { *; } +-keep public class * extends com.google.protobuf.** { *; } +-dontwarn com.google.protobuf.** + +-dontwarn org.xbill.** +-keep class org.xbill.** { *;} + +-keepattributes *Annotation* + + +# ------------------------ ChatKit ------------------------ +-dontwarn cn.leancloud.chatkit.** +-keep class cn.leancloud.chatkit.** { *;} +-dontnote cn.leancloud.chatkit.** + +# ------------------------ picasso ------------------------ +-dontwarn com.squareup.picasso** +-keep class com.squareup.picasso.**{*;} + +# ------------------------ eventbus ------------------------ +-keepattributes *Annotation* +-keepclassmembers class * { + @org.greenrobot.eventbus.Subscribe ; +} +-keep enum org.greenrobot.eventbus.ThreadMode { *; } + +# Only required if you use AsyncExecutor +-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { + (java.lang.Throwable); +} +#--------------------------工具集----------------------------- +-keep class blankj.utilcode.** { *; } +-keepclassmembers class blankj.utilcode.** { *; } +-dontwarn blankj.utilcode.** + +-keep class com.chad.library.adapter.** { +*; +} +-keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter +-keep public class * extends com.chad.library.adapter.base.BaseViewHolder +-keepclassmembers class **$** extends com.chad.library.adapter.base.BaseViewHolder { + (...); +} + +# glide 的混淆代码 +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { + **[] $VALUES; + public *; +} +# banner 的混淆代码 +-keep class com.youth.banner.** { + *; + } +# 华测sdk + -keep class com.chc.gnss.sdk.** { *; } + -dontwarn com.chc.gnss.sdk.** +# 中国移动sdk + -keep class com.cmcc.sy.hap.** { *; } + -dontwarn com.cmcc.sy.hap.** +# 梦想CAD sdk + -keep class org.cocos2dx.** { *; } + -dontwarn org.cocos2dx.** + -keep class com.chukong.cocosplay.client.** { *; } + -dontwarn com.chukong.cocosplay.client.** + -keep class com.MxDraw.** { *; } + -dontwarn com.MxDraw.** +#agentweb + -keep class com.just.agentweb.** { + *; + } + -dontwarn com.just.agentweb.** + +#androidx + -keep class com.google.android.material.** {*;} + -keep class androidx.** {*;} + -keep public class * extends androidx.** + -keep interface androidx.** {*;} + -dontwarn com.google.android.material.** + -dontnote com.google.android.material.** + -dontwarn androidx.** + +# 南方坐标转换 + -keep class com.qxwz.sdk.** { *; } + -dontwarn com.qxwz.sdk.** + + -keep class com.bingce.device.rtk.configuration.** { *; } + -keep class com.bingce.device.rtk.model.** { *; } + -keep class com.bingce.totalstation.TsConfig { *; } + + #OkSocket + -dontwarn xuhao.didi.socket.client.** + -dontwarn xuhao.didi.socket.common.** + -dontwarn xuhao.didi.socket.server.** + -dontwarn xuhao.didi.core.** + + -keep class xuhao.didi.socket.client.** { *; } + -keep class xuhao.didi.socket.common.** { *; } + -keep class xuhao.didi.socket.server.** { *; } + -keep class xuhao.didi.core.** { *; } + + -keep class xuhao.didi.socket.client.sdk.client.OkSocketOptions$* { + *; + } + -keep class xuhao.didi.socket.server.impl.OkServerOptions$* { + *; + } + + #gsyvideoplayer + -keep class com.shuyu.gsyvideoplayer.video.** { *; } + -dontwarn com.shuyu.gsyvideoplayer.video.** + -keep class com.shuyu.gsyvideoplayer.video.base.** { *; } + -dontwarn com.shuyu.gsyvideoplayer.video.base.** + -keep class com.shuyu.gsyvideoplayer.utils.** { *; } + -dontwarn com.shuyu.gsyvideoplayer.utils.** + -keep class tv.danmaku.ijk.** { *; } + -dontwarn tv.danmaku.ijk.** + + -keep public class * extends android.view.View{ + *** get*(); + void set*(***); + public (android.content.Context); + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); + } + +# # keep rx +# -dontwarn sun.misc.** +# -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { +# long producerIndex; +# long consumerIndex; +# } +# -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { +# rx.internal.util.atomic.LinkedQueueNode producerNode; +# } +# -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { +# rx.internal.util.atomic.LinkedQueueNode consumerNode; +# } +# +# -keep class cn.liuyanbing.surveyor.model.base.SerializableStringArray { *; } + +-dontwarn com.yalantis.ucrop** +-keep class com.yalantis.ucrop** { *; } +-keep interface com.yalantis.ucrop** { *; } + +-keep class com.bingce.event.WxLoginSuccessEvent{ *; } + +# 友盟 + -keep class com.umeng.** {*;} \ No newline at end of file diff --git a/app/src/androidTest/java/cn/liuyanbing/surveyor/activity/MainActivityTest.java b/app/src/androidTest/java/cn/liuyanbing/surveyor/activity/MainActivityTest.java new file mode 100644 index 0000000..eed3c00 --- /dev/null +++ b/app/src/androidTest/java/cn/liuyanbing/surveyor/activity/MainActivityTest.java @@ -0,0 +1,19 @@ +package cn.liuyanbing.surveyor.activity; + +import android.util.Log; + +import org.junit.Test; + +public class MainActivityTest { + + @Test + public void initSound() { + Log.d("hwhw", "initSound"); + } + + @Test + public void onCreate() { + Log.d("hwhw", "onCreate"); + + } +} \ No newline at end of file diff --git a/app/src/androidTest/kotlin/HelloKotlin.kt b/app/src/androidTest/kotlin/HelloKotlin.kt new file mode 100644 index 0000000..f967c63 --- /dev/null +++ b/app/src/androidTest/kotlin/HelloKotlin.kt @@ -0,0 +1,49 @@ +import android.util.Log +import com.bingce.controlnetwork.http.RetrofitClient +import com.bingce.controlnetwork.http.sevice.CommonService +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.junit.Test + +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") +// } +// } +// +// +// } + } + + +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9228c83 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/README.md b/app/src/main/README.md new file mode 100644 index 0000000..ef62895 --- /dev/null +++ b/app/src/main/README.md @@ -0,0 +1 @@ +#controlnetwork diff --git a/app/src/main/assets/Roboto-Light.ttf b/app/src/main/assets/Roboto-Light.ttf new file mode 100644 index 0000000..d43e943 Binary files /dev/null and b/app/src/main/assets/Roboto-Light.ttf differ diff --git a/app/src/main/assets/Roboto-Medium.ttf b/app/src/main/assets/Roboto-Medium.ttf new file mode 100644 index 0000000..8798341 Binary files /dev/null and b/app/src/main/assets/Roboto-Medium.ttf differ diff --git a/app/src/main/assets/default_tolerance b/app/src/main/assets/default_tolerance new file mode 100644 index 0000000..e13dc04 --- /dev/null +++ b/app/src/main/assets/default_tolerance @@ -0,0 +1,868 @@ +[{ + "name": "城市轨道交通", + "level": [{ + "name": "城市轨道交通精密导线", + "precision": [{ + "name": "I级", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "3", + "singleCycleDistanceDifference": "3", + "allCycleDistanceDifference": "4", + "cycleCount": "4" + }, { + "name": "II级", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "4", + "singleCycleDistanceDifference": "4", + "allCycleDistanceDifference": "6", + "cycleCount": "6" + }] + }] +}, { + "name": "铁路工程测量", + "level": [{ + "name": "铁路工程测量二等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "4", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "3", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "铁路工程测量三等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "4", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "3", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "3", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "铁路工程测量四等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "4", + "hor2C": "6", + "horCyclesDirect2CDifference": "6", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "3", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "3" + }] + }, { + "name": "铁路工程测量一级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "?", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "?", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "3" + }] + }, { + "name": "铁路工程测量二级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "?", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "?", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "3" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "20", + "singleCycleDistanceDifference": "20", + "allCycleDistanceDifference": "30", + "cycleCount": "3" + }] + }] +}, { + "name": "水利水电工程测量", + "level": [{ + "name": "水利水电工程测量二等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "2", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "3", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "6", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }] + }, { + "name": "水利水电工程测量三等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "2", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "3", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "6", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }] + }, { + "name": "水利水电工程测量四等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "2", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "3", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "6", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }] + }, { + "name": "水利水电工程测量五等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "6", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "12", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "24", + "horCyclesDirectValueDifference": "24", + "hor2C": "24", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }] +}, { + "name": "工程测量", + "level": [{ + "name": "工程测量三等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "工程测量四等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "工程测量一级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }] + }, { + "name": "工程测量二级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "24", + "horCyclesDirectValueDifference": "24", + "hor2C": "24", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }] + }, { + "name": "工程测量三级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "24", + "horCyclesDirectValueDifference": "24", + "hor2C": "24", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }] + }] +}, { + "name": "城市测量", + "level": [{ + "name": "城市测量三等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "城市测量四等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "城市测量一级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "城市测量二级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "城市测量三级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }] +}] \ No newline at end of file diff --git a/app/src/main/assets/features.hcc b/app/src/main/assets/features.hcc new file mode 100644 index 0000000..5ea2931 --- /dev/null +++ b/app/src/main/assets/features.hcc @@ -0,0 +1,574 @@ +[Group][Radio] +[Model][Valid] +Baudrate:1:4800,9600,19200:1,0,2 +Power:10:1,2,5,10,20:2,6,3,4,5 +Stepper:10:125,250:0,2 +[Model][RadioChannels] +High:456.05,456.55,457.05,458.05,459.05,460.05,461.05,462.05,462.55 +Middle:430.00,432.50,435.00,437.50,440.00,442.50,445.00,447.50,450.00 +Low:415.05,416.05,417.05,418.05,419.05,420.05,421.05,422.05,423.05 +[Model][Advanced For Satel] +Step-Protocol-Baudrate:125-8-9600 +Step-Protocol-Baudrate:125-16-9600 +Step-Protocol-Baudrate:125-2-4800 +Step-Protocol-Baudrate:125-4-4800 +Step-Protocol-Baudrate:250-8-19200 +Step-Protocol-Baudrate:250-16-19200 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +[Model][Advanced For HuaXin] +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-1-19200 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +[Model][Advanced For HuaXin-EX] +Step-Protocol-Baudrate:125-1-4800 +Step-Protocol-Baudrate:125-2-4800 +Step-Protocol-Baudrate:125-4-4800 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-1-19200 +[Model][Advanced For HuaXin-EX2] +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-512-9600 +Step-Protocol-Baudrate:250-256-19200 +Step-Protocol-Baudrate:250-512-19200 +[Model][Advanced For HuaXin-SOUTH] +Step-Protocol-Baudrate:125-1-4800 +Step-Protocol-Baudrate:125-2-4800 +Step-Protocol-Baudrate:125-4-4800 +Step-Protocol-Baudrate:125-256-4800 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-1-19200 +Step-Protocol-Baudrate:250-256-19200 +[Model][Advanced For D352] +Step-Protocol-Baudrate:125-1-9600 +Step-Protocol-Baudrate:125-2-9600 +Step-Protocol-Baudrate:125-4-9600 +Step-Protocol-Baudrate:125-1-19200 +Step-Protocol-Baudrate:125-2-19200 +Step-Protocol-Baudrate:125-4-19200 +Step-Protocol-Baudrate:200-1-9600 +Step-Protocol-Baudrate:200-2-9600 +Step-Protocol-Baudrate:200-4-9600 +Step-Protocol-Baudrate:200-1-19200 +Step-Protocol-Baudrate:200-2-19200 +Step-Protocol-Baudrate:200-4-19200 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-1-19200 +Step-Protocol-Baudrate:250-2-19200 +Step-Protocol-Baudrate:250-4-19200 +[Model][Advanced For D352_CHCX] +Step-Protocol-Baudrate:125-1-9600 +Step-Protocol-Baudrate:125-2-9600 +Step-Protocol-Baudrate:125-4-9600 +Step-Protocol-Baudrate:125-2-19200 +Step-Protocol-Baudrate:125-4-19200 +Step-Protocol-Baudrate:125-4096-19200 +Step-Protocol-Baudrate:200-1-9600 +Step-Protocol-Baudrate:200-2-9600 +Step-Protocol-Baudrate:200-4-9600 +Step-Protocol-Baudrate:200-2-19200 +Step-Protocol-Baudrate:200-4-19200 +Step-Protocol-Baudrate:200-4096-19200 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-2-19200 +Step-Protocol-Baudrate:250-4-19200 +Step-Protocol-Baudrate:250-4096-19200 +[Model][Advanced For HuaXin-SOUTH_CHCX] +Step-Protocol-Baudrate:125-1-4800 +Step-Protocol-Baudrate:125-2-4800 +Step-Protocol-Baudrate:125-4-4800 +Step-Protocol-Baudrate:125-256-4800 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-256-19200 +Step-Protocol-Baudrate:250-4096-19200 +[Model][Advanced For HuaXin_SOUTH_ZHD_CHCX] +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-512-9600 +Step-Protocol-Baudrate:250-256-19200 +Step-Protocol-Baudrate:250-512-19200 +Step-Protocol-Baudrate:250-4096-19200 +[Model][Advanced For HuaXin_SOUTH_ZHD] +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-512-9600 +Step-Protocol-Baudrate:250-1-19200 +Step-Protocol-Baudrate:250-256-19200 +Step-Protocol-Baudrate:250-512-19200 +[Model][Features] +Size:19 +ID:1:RX +Range:450,470 +Baudrate:4800,9600,19200 +Stepper:125 +Protocol:1,2,4 +Power:NONE +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:0,0 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:2:RXTX +Range:450,470 +Baudrate:9600 +Stepper:125 +Protocol:1,2,4,128 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:0,0 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:3:Satel +Range:403,473 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:2,4,8,16 +Power:1,5,10 +[Model][Operations] +Frequency:1,1 +Baudrate:0,0 +Power:1,1 +Sensitivity:1,1 +FEC:1,1 +Stepper:1,1 +CallSign:1,1 +ID:4:LFS +Range:455,463 +Baudrate:9600 +Stepper:250 +Protocol:1 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:0,0 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:5:RXTX-MOREBAUDS +Range:450,470 +Baudrate:4800,9600,19200 +Stepper:125 +Protocol:1,2,4 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:6:LFS-MOREBAUDS +Range:455,463 +Baudrate:9600,19200 +Stepper:250 +Protocol:1 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:7:LFS-Low +Range:412,422 +Baudrate:9600 +Stepper:250 +Protocol:1 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:0,0 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:8:Satel-I80 +Range:403,473 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:2,4,8,16 +Power:1,2,5,10 +[Model][Operations] +Frequency:1,1 +Baudrate:1,0 +Power:1,1 +Sensitivity:1,1 +FEC:1,1 +Stepper:1,1 +CallSign:1,1 +ID:9:HX +Range:410,470 +Baudrate:9600,19200 +Stepper:250 +Protocol:1,2,4 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:10:HX-EX +Range:410,470 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:1,2,4 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:11:Satel-TR8 +Range:865,867 +Baudrate:19200 +Stepper:250 +Protocol:8 +Power:1,5,10 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:1,1 +Stepper:1,1 +CallSign:0,0 +ID:12:HX-EX2 +Range:410,470 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:2,4,256,512 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:13:D352 +Range:410,470 +Baudrate:9600,19200 +Stepper:125,200,250 +Protocol:1,2,4 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:14:HX_SOUTH +Range:410,470 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:1,2,4,256 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:15:HX_865 +Range:1,8 +Baudrate:19200 +Stepper:125 +Protocol:1 +Power:5,10 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:16:D352_CHCX +Range:410,470 +Baudrate:9600,19200 +Stepper:125,200,250 +Protocol:1,2,4,4096 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:17:HX_SOUTH_CHCX +Range:410,470 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:1,2,4,256,4096 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:18:HX_SOUTH_ZHD_CHCX +Range:410,470 +Baudrate:9600,19200 +Stepper:125,250 +Protocol:2,4,256,512,4096 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:19:HX_SOUTH_ZHD +Range:410,470 +Baudrate:9600,19200 +Stepper:125,250 +Protocol:1,2,4,256,512 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +[Group][NMEA] +[Model][Features] +Size:8 +ID:1 +Type:1,2,3,4,5,6,7,8,9,12,13,14,19,20 +Frequency:3,4,5,6,7,8,9,10,11 +ID:2 +Type:1,2,3,4,5,6,7,8,9,10,11,12 +Frequency:4,5,6,7,8,9,10,11 +ID:4 +Type:1,2,3,4,5,6,7,8,9,12,15,16 +Frequency:5,6,7,8 +ID:6 +Type:1,2,3,5,6,7,8,9,10,11 +Frequency:4,5,6,7,8,9,10,11 +ID:7 +Type:1,2,3,4,5,6,7,8,9,12,15,16 +Frequency:5,6,7,8,9,10,11 +ID:8 +Type:1,2,3,4,5,6,7,8,9,12,13,14,17,18,19,20,21,22,23,24,25 +Frequency:5,6,7,8,9,10 +ID:12 +Type:1,2,3,4,5,6,7,8,9,12,19 +Frequency:8,9,10,11 +ID:14 +Type:1,2,3,5,6,7,8,9,10,11 +Frequency:4,5,6,7,8,9,10,11 +[Group][Precision] +[Model][Features] +Size:5 +ID:1 +HP:0.2 +VP:0.2 +XP:0.2 +YP:0.2 +RMS:0.2 +Status:11 +DiffAge:-1 +ID:2 +HP:0.6 +VP:0.6 +XP:0.6 +YP:0.6 +RMS:0.6 +Status:-1 +DiffAge:5 +ID:3 +HP:0.6 +VP:0.6 +XP:0.6 +YP:0.6 +RMS:0.6 +Status:-1 +DiffAge:5 +ID:7 +HP:0.3 +VP:0.3 +XP:0.3 +YP:0.3 +RMS:0.3 +Status:11 +DiffAge:-1 +ID:8 +HP:0.2 +VP:0.2 +XP:0.2 +YP:0.2 +RMS:0.2 +Status:11 +DiffAge:-1 +[Group][EBubbleMatrix] +[Model][Features] +Size:4 +ID:1 +Type:-2 +Matrix:0,1,-1,0 +ID:2 +Type:-1 +Matrix:1,0,0,1 +ID:3 +Type:0 +Matrix:-1,0,0,1 +ID:4 +Type:1 +Matrix:-1,0,0,1 +[Group][StaticSampleFreq] +[Model][Features] +Size:4 +ID:1 +Type:0 +FreqList:7,8,9,10,11,12,15,16 +ID:2 +Type:1 +FreqList:4,5,6,7,8,9,10,11,12,15,16 +ID:3 +Type:2 +FreqList:6,8,9,10,11,12,15,16 +ID:4 +Type:3 +FreqList:8,9,10,11 +[Group][SmartGNSSPN] +[Model][Features] +Size:13 +ID:1 +Type:1 +Name:N72 +CalibrationType:1 +Main:72 +Sub:00,01,10 +ID:2 +Type:2 +Name:I80 +CalibrationType:1 +Main:80 +Sub:00,01 +ID:3 +Type:3 +Name:X10 +CalibrationType:1 +Main:80 +Sub:02,03 +ID:4 +Type:4 +Name:T8 +CalibrationType:1 +Main:80 +Sub:06,07 +ID:5 +Type:5 +Name:X9 +CalibrationType:1 +Main:80 +Sub:11,15 +ID:6 +Type:6 +Name:M6 +CalibrationType:2 +Main:80 +Sub:08 +ID:7 +Type:7 +Name:I70 +CalibrationType:1 +Main:80 +Sub:09,10,13 +ID:8 +Type:8 +Name:T7 +CalibrationType:1 +Main:80 +Sub:14 +ID:9 +Type:9 +Name:X360 +CalibrationType:1 +Main:36 +Sub: +ID:10 +Type:10 +Name:NX100 +CalibrationType:0 +Main:74 +Sub:12,24 +ID:11 +Type:11 +Name:NX101 +CalibrationType:0 +Main:75 +Sub: +ID:12 +Type:12 +Name:MC100 +CalibrationType:0 +Main:76 +Sub:00,01 +ID:13 +Type:13 +Name:NX200 +CalibrationType:0 +Main:77 +Sub: +[Group][SupportGNSSType] +[Model][SMARTGNSS] +Type:0 +MainBoard:0 +[Model][ARM] +Type:0 +MainBoard:0 +[Model][DIRECT] +Type:0 +MainBoard:0 \ No newline at end of file diff --git a/app/src/main/assets/network_error.png b/app/src/main/assets/network_error.png new file mode 100644 index 0000000..c1fed83 Binary files /dev/null and b/app/src/main/assets/network_error.png differ diff --git a/app/src/main/assets/service_default.html b/app/src/main/assets/service_default.html new file mode 100644 index 0000000..a5a2796 --- /dev/null +++ b/app/src/main/assets/service_default.html @@ -0,0 +1,51 @@ + + + + + + + + + +
+
+ +
点击刷新
+
+
+ + + \ No newline at end of file diff --git a/app/src/main/assets/supplierconfig.json b/app/src/main/assets/supplierconfig.json new file mode 100644 index 0000000..5f5f8e0 --- /dev/null +++ b/app/src/main/assets/supplierconfig.json @@ -0,0 +1,13 @@ +{ + "supplier": { + "vivo": { + "appid": "100215079" + }, + "xiaomi": { + }, + "huawei": { + }, + "oppo": { + } + } +} \ No newline at end of file diff --git a/app/src/main/assets/template_tolerance b/app/src/main/assets/template_tolerance new file mode 100644 index 0000000..0cc2af3 --- /dev/null +++ b/app/src/main/assets/template_tolerance @@ -0,0 +1,93 @@ +[{ + "createDate": "Jan 27, 2021 9:37:42 AM", + "hor2C": 5.0, + "horCycleDirect2CDifference": 5.0, + "horCyclesDirect2CDifference": 5.0, + "horCyclesDirectValueDifference": 5.0, + "horHalfReturnZeroDifference": 5.0, + "horReadDifference": 5.0, + "id": "20210127093742841174", + "isTemplate": true, + "name": "限差模板0", + "singleSurveyor": true, + "slopeCycleDistanceDifference": 5.0, + "slopeLensDistanceDifference": 5.0, + "slopeReadDifference": 5.0, + "surveyorCycleCount": 2, + "verCheckWhenAngle3": true, + "verCycleDirectIDifference": 5.0, + "verCyclesAngleDifference": 5.0, + "verCyclesIDifference": 5.0, + "verIDifference": 5.0, + "verReadDifference": 5.0 + }, + { + "createDate": "Jan 27, 2021 9:37:43 AM", + "hor2C": 5.0, + "horCycleDirect2CDifference": 5.0, + "horCyclesDirect2CDifference": 5.0, + "horCyclesDirectValueDifference": 5.0, + "horHalfReturnZeroDifference": 5.0, + "horReadDifference": 5.0, + "id": "20210127093743841174", + "isTemplate": true, + "name": "限差模板1", + "singleSurveyor": true, + "slopeCycleDistanceDifference": 5.0, + "slopeLensDistanceDifference": 5.0, + "slopeReadDifference": 5.0, + "surveyorCycleCount": 2, + "verCheckWhenAngle3": true, + "verCycleDirectIDifference": 5.0, + "verCyclesAngleDifference": 5.0, + "verCyclesIDifference": 5.0, + "verIDifference": 5.0, + "verReadDifference": 5.0 + }, + { + "createDate": "Jan 27, 2021 9:37:44 AM", + "hor2C": 5.0, + "horCycleDirect2CDifference": 5.0, + "horCyclesDirect2CDifference": 5.0, + "horCyclesDirectValueDifference": 5.0, + "horHalfReturnZeroDifference": 5.0, + "horReadDifference": 5.0, + "id": "20210127093744841174", + "isTemplate": true, + "name": "限差模板2", + "singleSurveyor": true, + "slopeCycleDistanceDifference": 5.0, + "slopeLensDistanceDifference": 5.0, + "slopeReadDifference": 5.0, + "surveyorCycleCount": 2, + "verCheckWhenAngle3": true, + "verCycleDirectIDifference": 5.0, + "verCyclesAngleDifference": 5.0, + "verCyclesIDifference": 5.0, + "verIDifference": 5.0, + "verReadDifference": 5.0 + }, + { + "createDate": "Jan 27, 2021 9:37:45 AM", + "hor2C": 5.0, + "horCycleDirect2CDifference": 5.0, + "horCyclesDirect2CDifference": 5.0, + "horCyclesDirectValueDifference": 5.0, + "horHalfReturnZeroDifference": 5.0, + "horReadDifference": 5.0, + "id": "20210127093745841174", + "isTemplate": true, + "name": "限差模板3", + "singleSurveyor": true, + "slopeCycleDistanceDifference": 5.0, + "slopeLensDistanceDifference": 5.0, + "slopeReadDifference": 5.0, + "surveyorCycleCount": 2, + "verCheckWhenAngle3": true, + "verCycleDirectIDifference": 5.0, + "verCyclesAngleDifference": 5.0, + "verCyclesIDifference": 5.0, + "verIDifference": 5.0, + "verReadDifference": 5.0 + } +] \ No newline at end of file diff --git a/app/src/main/design.sketch b/app/src/main/design.sketch new file mode 100644 index 0000000..244c413 Binary files /dev/null and b/app/src/main/design.sketch differ diff --git a/app/src/main/doc/测绘云流程图.mdj b/app/src/main/doc/测绘云流程图.mdj new file mode 100644 index 0000000..2ba0b6c --- /dev/null +++ b/app/src/main/doc/测绘云流程图.mdj @@ -0,0 +1,12064 @@ +{ + "_type": "Project", + "_id": "AAAAAAFF+h6SjaM2Hec=", + "name": "Untitled", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFF+qBWK6M3Z8Y=", + "_parent": { + "$ref": "AAAAAAFF+h6SjaM2Hec=" + }, + "name": "Model", + "ownedElements": [ + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFF+qBtyKM79qY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Main", + "defaultDiagram": true + }, + { + "_type": "UMLUseCaseDiagram", + "_id": "AAAAAAF2+mcHh6BjMLk=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "UseCaseDiagram1", + "ownedViews": [ + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mcRVqBoffw=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mcRVqBpas8=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mcRVqBq5fo=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -208, + "top": -512, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mcRVqBrTyU=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "font": "Arial;13;1", + "left": 86, + "top": 67.5, + "width": 72, + "height": 13, + "text": "doSurveyor" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mcRV6BsSvw=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -208, + "top": -512, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mcRV6BtFlw=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -208, + "top": -512, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 81, + "top": 60.5, + "width": 82.24267578125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mcRVqBq5fo=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mcRVqBrTyU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mcRV6BsSvw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mcRV6BtFlw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mcRV6Bu9xo=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mcRV6BvRaU=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mcRV6BwxMs=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mcRV6BxmtM=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mcRV6ByVVo=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 64, + "top": 56, + "width": 116, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mcRV6Bu9xo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mcRV6BvRaU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mcRV6BwxMs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mcRV6BxmtM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mcRV6ByVVo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mdRV6CXVyE=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mdRV6CYpcE=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mdRV6CZOus=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -320, + "top": -272, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mdRWKCaX8Q=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "font": "Arial;13;1", + "left": 134.5, + "top": 147.5, + "width": 111, + "height": 13, + "text": "checkReadData" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mdRWKCbUZ0=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -320, + "top": -272, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mdRWKCcYaU=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -320, + "top": -272, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 129.5, + "top": 140.5, + "width": 121, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mdRV6CZOus=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mdRWKCaX8Q=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mdRWKCbUZ0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mdRWKCcYaU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mdRWKCdx0Q=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mdRWKCeh8A=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mdRWKCfFBs=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mdRWKCgSTk=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mdRWKChHfo=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 104, + "top": 136, + "width": 172, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mdRWKCdx0Q=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mdRWKCeh8A=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mdRWKCfFBs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mdRWKCgSTk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mdRWKChHfo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+memFaDHSqA=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFaDI0Ig=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "font": "Arial;13;0", + "left": 150, + "top": 97, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 1, + "text": "+成功" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDJfpw=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 177, + "top": 87, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDKHFY=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 143, + "top": 116, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDLP6k=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDE9N8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 94, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDMvYQ=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDE9N8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 175, + "top": 87, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDNR6U=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDE9N8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 140, + "top": 109, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDO+bI=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDFhUw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 168, + "top": 99, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDP+fU=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDFhUw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 176, + "top": 89, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDQoeo=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDFhUw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 150, + "top": 120, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+memFqDRZjQ=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDE9N8=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+memFqDSnhY=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDFhUw=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "tail": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "lineStyle": 1, + "points": "136:91;174:135", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+memFaDI0Ig=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+memFqDJfpw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+memFqDKHFY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+memFqDLP6k=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+memFqDMvYQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+memFqDNR6U=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+memFqDO+bI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+memFqDP+fU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+memFqDQoeo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+memFqDRZjQ=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+memFqDSnhY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mkD1KIJSsk=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mkD1KIKN1Y=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mkD1KILUvM=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1424, + "top": 800, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mkD1aIMgv4=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "font": "Arial;13;1", + "left": 1116, + "top": 899.5, + "width": 98, + "height": 13, + "text": "SurveyorFailure" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mkD1aINBig=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1424, + "top": 800, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mkD1aIOP5w=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1424, + "top": 800, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1111, + "top": 892.5, + "width": 108.9853515625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mkD1KILUvM=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mkD1aIMgv4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mkD1aINBig=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mkD1aIOP5w=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mkD1aIPWB4=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mkD1aIQdMs=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mkD1aIRjCw=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mkD1aISQKk=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mkD1aITnSE=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1088, + "top": 888, + "width": 154, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mkD1aIPWB4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mkD1aIQdMs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mkD1aIRjCw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mkD1aISQKk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mkD1aITnSE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mntyKOOOdo=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mntyKOPRlw=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mntyaOQPU8=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1424, + "top": 272, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mntyaORm4U=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "font": "Arial;13;1", + "left": 60, + "top": 235.5, + "width": 175, + "height": 13, + "text": "isHalfCycleZeroCheckReady" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mntyaOSZzs=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1424, + "top": 272, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mntyaOTchM=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1424, + "top": 272, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 55, + "top": 228.5, + "width": 186.2998046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mntyaOQPU8=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mntyaORm4U=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mntyaOSZzs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mntyaOTchM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mntyaOUZOw=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mntyaOVKGs=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mntyaOWiEg=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mntyaOXRTU=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mntyaOYDwo=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 16, + "top": 224, + "width": 263, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mntyaOUZOw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mntyaOVKGs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mntyaOWiEg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mntyaOXRTU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mntyaOYDwo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+moC5KQPBko=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQQceg=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "font": "Arial;13;0", + "left": 152, + "top": 197, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQRJ/g=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 195, + "top": 203, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQSRfg=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 154, + "top": 184, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQT7kk=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQMlXg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 182, + "top": 194, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQU3fw=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQMlXg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 193, + "top": 202, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQV8KI=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQMlXg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 159, + "top": 179, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQWyNA=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQNhhs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 180, + "top": 199, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQXfeg=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQNhhs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 193, + "top": 203, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQYo5E=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQNhhs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 153, + "top": 192, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+moC5KQZHbs=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQMlXg=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+moC5KQar0s=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQNhhs=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "tail": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "lineStyle": 1, + "points": "180:171;156:223", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+moC5KQQceg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+moC5KQRJ/g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+moC5KQSRfg=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+moC5KQT7kk=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+moC5KQU3fw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+moC5KQV8KI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+moC5KQWyNA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+moC5KQXfeg=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+moC5KQYo5E=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+moC5KQZHbs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+moC5KQar0s=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mq6h6SuwYA=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mq6h6Sv0Ic=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mq6iKSwPhE=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": 1008, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mq6iKSxaL0=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "font": "Arial;13;1", + "left": 1035.5, + "top": 763.5, + "width": 136, + "height": 13, + "text": "doDeleteCurrentCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mq6iKSyJ1A=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": 1008, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mq6iKSzjnI=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": 1008, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1030.5, + "top": 756.5, + "width": 146.5380859375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mq6iKSwPhE=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mq6iKSxaL0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mq6iKSyJ1A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mq6iKSzjnI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mq6iKS0rdE=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mq6iKS1PJ4=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mq6iKS2Mes=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mq6iKS3ZVY=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mq6iKS4Kqg=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1000, + "top": 752, + "width": 207, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mq6iKS0rdE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mq6iKS1PJ4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mq6iKS2Mes=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mq6iKS3ZVY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mq6iKS4Kqg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+mrOv6VKaJI=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VLPnA=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "font": "Arial;13;0", + "left": 535, + "top": 107, + "width": 267.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 1, + "text": "+未通过检测提示目标两次读数超限请重新测量" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VMamw=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 667, + "top": 92, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VN3Ss=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 669, + "top": 136, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VO7dE=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VHNRw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 301, + "top": 125, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VPrV4=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VHNRw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 302, + "top": 112, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VQWxU=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VHNRw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 298, + "top": 153, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VRiCs=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VIVq0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1036, + "top": 88, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VSM/w=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VIVq0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1033, + "top": 75, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VTlbY=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VIVq0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1042, + "top": 115, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mrOv6VUz6Q=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VHNRw=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mrOv6VV49g=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VIVq0=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "lineStyle": 1, + "points": "276:148;1063:108", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+mrOv6VLPnA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mrOv6VMamw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mrOv6VN3Ss=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+mrOv6VO7dE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+mrOv6VPrV4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+mrOv6VQWxU=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+mrOv6VRiCs=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+mrOv6VSM/w=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+mrOv6VTlbY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+mrOv6VUz6Q=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+mrOv6VV49g=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mvXKaZ9JcA=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mvXKaZ+a7s=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mvXKaZ/YSQ=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1664, + "top": 544, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mvXKaaAI84=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "font": "Arial;13;1", + "left": 73, + "top": 643.5, + "width": 124, + "height": 13, + "text": "checkHalfCycleZero" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mvXKaaB8qQ=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1664, + "top": 544, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mvXKaaCW0M=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1664, + "top": 544, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 68, + "top": 636.5, + "width": 134.28076171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mvXKaZ/YSQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mvXKaaAI84=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mvXKaaB8qQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mvXKaaCW0M=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mvXKaaD/VM=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mvXKaaE660=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mvXKaaFnDM=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mvXKaaGOXs=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mvXKaaHvGE=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 40, + "top": 632, + "width": 190, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mvXKaaD/VM=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mvXKaaE660=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mvXKaaFnDM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mvXKaaGOXs=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mvXKaaHvGE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+mvs0qc0M6s=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc1wM8=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "font": "Arial;13;0", + "left": 125, + "top": 439, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 1, + "text": "+满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc202A=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 169, + "top": 439, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc3e6M=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 125, + "top": 438, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc4Drs=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcx6HM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 160, + "top": 279, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc5vMI=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcx6HM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 173, + "top": 282, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc6Rdg=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcx6HM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 132, + "top": 274, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc7l5k=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcyuaY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 150, + "top": 599, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc8asw=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcyuaY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 597, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc9HoU=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcyuaY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 123, + "top": 602, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mvs0qc+Nck=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcx6HM=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mvs0qc/jzw=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcyuaY=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "tail": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "lineStyle": 1, + "points": "146:259;135:631", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+mvs0qc1wM8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mvs0qc202A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mvs0qc3e6M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+mvs0qc4Drs=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+mvs0qc5vMI=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+mvs0qc6Rdg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+mvs0qc7l5k=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+mvs0qc8asw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+mvs0qc9HoU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+mvs0qc+Nck=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+mvs0qc/jzw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mwCOqh1UGk=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mwCO6h22P0=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mwCO6h3Ono=", + "_parent": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": -640, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mwCO6h4ZQA=", + "_parent": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "font": "Arial;13;1", + "left": 1084, + "top": 99.5, + "width": 62, + "height": 13, + "text": "Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mwCO6h565A=", + "_parent": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": -640, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mwCO6h6b3M=", + "_parent": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": -640, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1079, + "top": 92.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mwCO6h3Ono=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mwCO6h4ZQA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mwCO6h565A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mwCO6h6b3M=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mwCO6h75qU=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mwCO6h8WBM=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mwCO6h9qfA=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mwCO6h+cG0=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mwCO6h/PzE=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1064, + "top": 88, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mwCO6h75qU=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mwCO6h8WBM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mwCO6h9qfA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mwCO6h+cG0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mwCO6h/PzE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+mw/iqlHhw8=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlICrw=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1093, + "top": 430, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlJZUA=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1078, + "top": 430, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlKnVA=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1122, + "top": 431, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlLEKc=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlEWtE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": 718, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlMafs=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlEWtE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1075, + "top": 716, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlNnYc=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlEWtE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1115, + "top": 723, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlOQrw=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlF64M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1098, + "top": 142, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlPlDs=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlF64M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1085, + "top": 144, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlQdOY=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlF64M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1126, + "top": 138, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mw/iqlRtpI=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlEWtE=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mw/iqlS6xc=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlF64M=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "lineStyle": 1, + "points": "1103:751;1114:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+mw/iqlICrw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mw/iqlJZUA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mw/iqlKnVA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+mw/iqlLEKc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+mw/iqlMafs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+mw/iqlNnYc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+mw/iqlOQrw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+mw/iqlPlDs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+mw/iqlQdOY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+mw/iqlRtpI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+mw/iqlS6xc=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+m3Ng67WXiU=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+m3Ng67Xic8=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+m3Ng67YH00=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1744, + "top": 368, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m3Ng67ZMKU=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "font": "Arial;13;1", + "left": 261, + "top": 355.5, + "width": 105, + "height": 13, + "text": "isReady2CCheck" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m3Ng67aYAg=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1744, + "top": 368, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m3Ng67b7tk=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1744, + "top": 368, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 256, + "top": 348.5, + "width": 115.498046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m3Ng67YH00=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+m3Ng67ZMKU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+m3Ng67aYAg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m3Ng67b7tk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+m3Ng67cquY=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+m3NhK7dOGY=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+m3NhK7ePSk=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+m3NhK7f3Bg=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+m3NhK7gUrI=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 232, + "top": 344, + "width": 163, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+m3Ng67cquY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+m3NhK7dOGY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+m3NhK7ePSk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+m3NhK7f3Bg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+m3NhK7gUrI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+m3lu6/DOUc=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/E2Do=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "font": "Arial;13;0", + "left": 181, + "top": 491, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/FDO0=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 197, + "top": 483, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/Gi08=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 235, + "top": 506, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/Hf44=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/AYdA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 146, + "top": 595, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/IqJw=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/AYdA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 135, + "top": 586, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/JdkM=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/AYdA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 167, + "top": 613, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/KoQg=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/BCoQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 275, + "top": 387, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/LFko=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/BCoQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 263, + "top": 382, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/MT0A=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/BCoQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 301, + "top": 397, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m3lu6/N6Ng=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/AYdA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m3lu6/Ooek=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/BCoQ=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "tail": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "lineStyle": 1, + "points": "145:631;302:379", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+m3lu6/E2Do=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m3lu6/FDO0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m3lu6/Gi08=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+m3lu6/Hf44=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+m3lu6/IqJw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+m3lu6/JdkM=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+m3lu6/KoQg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+m3lu6/LFko=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+m3lu6/MT0A=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+m3lu6/N6Ng=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+m3lu6/Ooek=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+m4Cd7DQ378=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DRAVE=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "font": "Arial;13;0", + "left": 579, + "top": 687, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DScfk=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 617, + "top": 672, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DTMTY=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 612, + "top": 716, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DUVcI=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DNh98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 257, + "top": 643, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DVlvI=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DNh98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 261, + "top": 630, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DWLMQ=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DNh98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 249, + "top": 670, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DXhyw=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DOnkA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 975, + "top": 731, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DYDkU=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DOnkA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 974, + "top": 718, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DZShc=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DOnkA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 975, + "top": 759, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m4Cd7DaWVU=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DNh98=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m4Cd7Dbwu8=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DOnkA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "tail": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "lineStyle": 1, + "points": "230:661;999:756", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+m4Cd7DRAVE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m4Cd7DScfk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m4Cd7DTMTY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+m4Cd7DUVcI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+m4Cd7DVlvI=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+m4Cd7DWLMQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+m4Cd7DXhyw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+m4Cd7DYDkU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+m4Cd7DZShc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+m4Cd7DaWVU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+m4Cd7Dbwu8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+m6507J/Zuo=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KAvO0=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "font": "Arial;13;0", + "left": 215, + "top": 282, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 1, + "text": "+不满足" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KBRDQ=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 247, + "top": 270, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KCcvI=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 221, + "top": 307, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KDh+o=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ8zw4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 201, + "top": 256, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KECBE=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ8zw4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 211, + "top": 246, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KFH0o=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ8zw4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 182, + "top": 275, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KGgnk=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ9BDM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 275, + "top": 309, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KHvxk=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ9BDM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 281, + "top": 297, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KIBfg=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ9BDM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 263, + "top": 334, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m6507KJ9Bk=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ8zw4=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m6507KKLw0=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ9BDM=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "tail": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "lineStyle": 1, + "points": "172:259;288:343", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+m6507KAvO0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m6507KBRDQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m6507KCcvI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+m6507KDh+o=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+m6507KECBE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+m6507KFH0o=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+m6507KGgnk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+m6507KHvxk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+m6507KIBfg=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+m6507KJ9Bk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+m6507KKLw0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+m+73bQ4m2I=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+m+73bQ51AA=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+m+73bQ6nXw=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1408, + "top": -752, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m+73bQ744s=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "font": "Arial;13;1", + "left": 492, + "top": 203.5, + "width": 62, + "height": 13, + "text": "check2C" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m+73bQ8TTM=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1408, + "top": -752, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m+73bQ9+Mw=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1408, + "top": -752, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 487, + "top": 196.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m+73bQ6nXw=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+m+73bQ744s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+m+73bQ8TTM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m+73bQ9+Mw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+m+73bQ+qzE=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+m+73bQ/52s=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+m+73bRAXBQ=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+m+73bRBpqA=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+m+73bRCY/s=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 472, + "top": 192, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+m+73bQ+qzE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+m+73bQ/52s=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+m+73bRAXBQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+m+73bRBpqA=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+m+73bRCY/s=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+m/aRbZnCCE=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZoX2c=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "font": "Arial;13;0", + "left": 379, + "top": 266, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 1, + "text": "+满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZpYP8=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 399, + "top": 254, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZq7mM=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 425, + "top": 291, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZrfg0=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZkwdI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 350, + "top": 309, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZsE+c=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZkwdI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 344, + "top": 297, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZtnbI=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZkwdI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 362, + "top": 334, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZuIZ4=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZlRAA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 467, + "top": 224, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRrZv/So=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZlRAA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 457, + "top": 214, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRrZw+Wc=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZlRAA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 486, + "top": 243, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m/aRrZxzMY=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZkwdI=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m/aRrZyYfg=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZlRAA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "tail": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "lineStyle": 1, + "points": "338:343;497:227", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+m/aRbZoX2c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m/aRbZpYP8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m/aRbZq7mM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+m/aRbZrfg0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+m/aRbZsE+c=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+m/aRbZtnbI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+m/aRbZuIZ4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+m/aRrZv/So=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+m/aRrZw+Wc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+m/aRrZxzMY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+m/aRrZyYfg=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nB7EcWvyhg=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nB7EsWwrGE=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nB7EsWxRXc=", + "_parent": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1632, + "top": 896, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nB7EsWyp7A=", + "_parent": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "font": "Arial;13;1", + "left": 606.5, + "top": 627.5, + "width": 151, + "height": 13, + "text": "isSingleCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nB7EsWzuj0=", + "_parent": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1632, + "top": 896, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nB7EsW0vEM=", + "_parent": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1632, + "top": 896, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 601.5, + "top": 620.5, + "width": 161.708984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nB7EsWxRXc=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nB7EsWyp7A=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nB7EsWzuj0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nB7EsW0vEM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nB7EsW1O74=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nB7EsW24Ak=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nB7EsW3La4=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nB7EsW4CYw=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nB7EsW5ziA=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 568, + "top": 616, + "width": 228, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nB7EsW1O74=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nB7EsW24Ak=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nB7EsW3La4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nB7EsW4CYw=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nB7EsW5ziA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+nC6Y8gyCOM=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8gzGbk=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "font": "Arial;13;0", + "left": 423, + "top": 400, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g0Btw=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 466, + "top": 406, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g1YTc=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 425, + "top": 389, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g2LKo=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gvJw0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 517, + "top": 250, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g3efU=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gvJw0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": 258, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g4m7s=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gvJw0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 493, + "top": 235, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g5UNs=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gwxpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 389, + "top": 551, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g6C1c=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gwxpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 402, + "top": 554, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g7AZQ=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gwxpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 362, + "top": 544, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nC6Y8g8U9U=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gvJw0=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nC6ZMg9Wfs=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gwxpA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "tail": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "lineStyle": 1, + "points": "514:227;365:575", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+nC6Y8gzGbk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nC6Y8g0Btw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nC6Y8g1YTc=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+nC6Y8g2LKo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+nC6Y8g3efU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+nC6Y8g4m7s=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+nC6Y8g5UNs=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+nC6Y8g6C1c=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+nC6Y8g7AZQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+nC6Y8g8U9U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+nC6ZMg9Wfs=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nIha+T0PKc=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nIha+T1GkI=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nIha+T2NuQ=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1504, + "top": -304, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nIha+T3MZE=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "font": "Arial;13;1", + "left": 291, + "top": 587.5, + "width": 133, + "height": 13, + "text": "doRecordClean" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nIha+T42aU=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1504, + "top": -304, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nIha+T5gIo=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1504, + "top": -304, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 286, + "top": 580.5, + "width": 143, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nIha+T2NuQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nIha+T3MZE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nIha+T42aU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nIha+T5gIo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nIha+T6I/s=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nIha+T7f88=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nIha+T8JnQ=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nIha+T97Co=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nIha+T+yMo=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 256, + "top": 576, + "width": 203, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nIha+T6I/s=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nIha+T7f88=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nIha+T8JnQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nIha+T97Co=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nIha+T+yMo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+nJuA+o1SCQ=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuA+o2CrU=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "font": "Arial;13;0", + "left": 313, + "top": 468, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 1, + "text": "+不满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuA+o3+MU=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 364, + "top": 465, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuA+o4dNs=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 320, + "top": 473, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo5VPw=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oyVzg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 335, + "top": 395, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo6yNA=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oyVzg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 349, + "top": 395, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo7uM0=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oyVzg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 307, + "top": 396, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo8SD0=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+ozWP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 363, + "top": 540, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo9a+E=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+ozWP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": 535, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo+Ck4=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+ozWP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 337, + "top": 550, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nJuBOo/2Pk=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oyVzg=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nJuBOpAePc=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+ozWP8=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "tail": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "lineStyle": 1, + "points": "316:379;354:575", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+nJuA+o2CrU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nJuA+o3+MU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nJuA+o4dNs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+nJuBOo5VPw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+nJuBOo6yNA=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+nJuBOo7uM0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+nJuBOo8SD0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+nJuBOo9a+E=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+nJuBOo+Ck4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+nJuBOo/2Pk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+nJuBOpAePc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+nQJoxCDdok=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCEJ/4=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "font": "Arial;13;0", + "left": 629, + "top": 524, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 1, + "text": "+未通过" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCFIAk=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 637, + "top": 526, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCGzfs=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 681, + "top": 521, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCHSY0=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCAKVI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 660, + "top": 585, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCIs3Y=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCAKVI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 647, + "top": 584, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCJhbQ=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCAKVI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 688, + "top": 585, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCKIrE=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCBbxs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 644, + "top": 464, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCLFVw=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCBbxs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 631, + "top": 468, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCMLbI=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCBbxs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 671, + "top": 456, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nQJoxCNff4=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCAKVI=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nQJoxCO0rE=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCBbxs=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "tail": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "lineStyle": 1, + "points": "679:615;656:443", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+nQJoxCEJ/4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nQJoxCFIAk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nQJoxCGzfs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+nQJoxCHSY0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+nQJoxCIs3Y=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+nQJoxCJhbQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+nQJoxCKIrE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+nQJoxCLFVw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+nQJoxCMLbI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+nQJoxCNff4=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+nQJoxCO0rE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nRKkx5Vaw4=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nRKkx5Wffo=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nRKkx5X/zo=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1904, + "top": 720, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nRKkx5Y40M=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "font": "Arial;13;1", + "left": 894, + "top": 531.5, + "width": 110, + "height": 13, + "text": "checkSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nRKlB5ZYRU=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1904, + "top": 720, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nRKlB5aPXo=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1904, + "top": 720, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 889, + "top": 524.5, + "width": 120.55712890625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nRKkx5X/zo=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nRKkx5Y40M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nRKlB5ZYRU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nRKlB5aPXo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nRKlB5bsGs=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nRKlB5calY=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nRKlB5doOk=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nRKlB5eoWY=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nRKlB5fYaI=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 864, + "top": 520, + "width": 170, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nRKlB5bsGs=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nRKlB5calY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nRKlB5doOk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nRKlB5eoWY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nRKlB5fYaI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+nS1vB//BAk=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vCAA1/w=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "font": "Arial;13;0", + "left": 779, + "top": 564, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 1, + "text": "+满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSABc/8=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 803, + "top": 550, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSACp60=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 819, + "top": 593, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAD2nc=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/8CFI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 750, + "top": 586, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAE3Cg=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/8CFI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 748, + "top": 572, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAFUjQ=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/8CFI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 755, + "top": 613, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAGNTg=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/9vRE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 868, + "top": 543, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAHtw0=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/9vRE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 861, + "top": 531, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAIfWc=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/9vRE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 881, + "top": 568, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nS1vSAJTTM=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/8CFI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -8, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nS1vSAK/NU=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/9vRE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -8, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "tail": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "lineStyle": 1, + "points": "731:615;898:555", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+nS1vCAA1/w=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nS1vSABc/8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nS1vSACp60=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+nS1vSAD2nc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+nS1vSAE3Cg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+nS1vSAFUjQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+nS1vSAGNTg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+nS1vSAHtw0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+nS1vSAIfWc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+nS1vSAJTTM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+nS1vSAK/NU=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nWEKyMwAMc=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nWEKyMxf1Q=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nWEKyMyBP8=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 800, + "top": -992, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nWEKyMzemE=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "font": "Arial;13;1", + "left": 2066, + "top": 11.5, + "width": 129, + "height": 13, + "text": "isAllCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nWEKyM01LQ=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 800, + "top": -992, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nWEKyM1r1Q=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 800, + "top": -992, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2061, + "top": 4.5, + "width": 139.314453125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nWEKyMyBP8=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nWEKyMzemE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nWEKyM01LQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nWEKyM1r1Q=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nWEKyM2sSI=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nWEKyM3PmE=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nWEKyM4Ihc=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nWELCM5C+g=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nWELCM6KvA=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2032, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nWEKyM2sSI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nWEKyM3PmE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nWEKyM4Ihc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nWELCM5C+g=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nWELCM6KvA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nfCMZ3BUsM=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nfCMp3C1RI=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nfCMp3DNmU=", + "_parent": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1456, + "top": -2448, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nfCMp3ECXU=", + "_parent": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "font": "Arial;13;1", + "left": 882, + "top": 403.5, + "width": 129, + "height": 13, + "text": "isAllCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nfCMp3FeYo=", + "_parent": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1456, + "top": -2448, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nfCMp3Gpdk=", + "_parent": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1456, + "top": -2448, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 877, + "top": 396.5, + "width": 139.314453125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nfCMp3DNmU=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nfCMp3ECXU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nfCMp3FeYo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nfCMp3Gpdk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nfCMp3Hk/w=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nfCMp3Ipoc=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nfCMp3J3MA=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nfCMp3KD9I=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nfCMp3LjAc=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 848, + "top": 392, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nfCMp3Hk/w=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nfCMp3Ipoc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nfCMp3J3MA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nfCMp3KD9I=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nfCMp3LjAc=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nmf8//Gfbw=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nmf8//HI2g=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nmf9P/I6yI=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -960, + "top": -1456, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nmf9P/JtnQ=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "font": "Arial;13;1", + "left": 541.5, + "top": 315.5, + "width": 105, + "height": 13, + "text": "doDeleteAllCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nmf9P/KQDY=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -960, + "top": -1456, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nmf9P/LlNA=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -960, + "top": -1456, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 536.5, + "top": 308.5, + "width": 116.20263671875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nmf9P/I6yI=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nmf9P/JtnQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nmf9P/KQDY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nmf9P/LlNA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nmf9P/MVYQ=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nmf9P/N0tE=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nmf9P/OUoc=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nmf9P/PSrQ=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nmf9P/QKKU=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 512, + "top": 304, + "width": 164, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nmf9P/MVYQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nmf9P/N0tE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nmf9P/OUoc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nmf9P/PSrQ=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nmf9P/QKKU=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nq2QxzFIJA=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nq2QxzGCOI=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nq2QxzHPGg=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 816, + "top": -1376, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nq2QxzIGSU=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "font": "Arial;13;1", + "left": 473.5, + "top": 899.5, + "width": 87, + "height": 13, + "text": "checkAllCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nq2QxzJNkI=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 816, + "top": -1376, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nq2QxzK1gc=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 816, + "top": -1376, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 468.5, + "top": 892.5, + "width": 98.16259765625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nq2QxzHPGg=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nq2QxzIGSU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nq2QxzJNkI=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nq2QxzK1gc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nq2QxzLAgw=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nq2QxzMb90=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nq2QxzN8NY=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nq2QxzOrKA=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nq2QxzPhCY=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 448, + "top": 888, + "width": 138, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nq2QxzLAgw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nq2QxzMb90=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nq2QxzN8NY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nq2QxzOrKA=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nq2QxzPhCY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nsueip2TzQ=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nsueip3gdc=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nsueip4ids=", + "_parent": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": -1696, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nsueip54uU=", + "_parent": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "font": "Arial;13;1", + "left": 772, + "top": 915.5, + "width": 62, + "height": 13, + "text": "Finish" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nsueip60ls=", + "_parent": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": -1696, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nsueip7mbo=", + "_parent": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": -1696, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 767, + "top": 908.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nsueip4ids=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nsueip54uU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nsueip60ls=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nsueip7mbo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nsueip8654=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nsueip9KyQ=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nsueip+40A=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nsueip/CZI=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nsueyqAa5A=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 752, + "top": 904, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nsueip8654=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nsueip9KyQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nsueip+40A=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nsueip/CZI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nsueyqAa5A=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+n3z7GQDM/o=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+n3z7GQEn4U=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+n3z7GQFG64=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 1072, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n3z7GQGJmk=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "font": "Arial;13;1", + "left": 913.5, + "top": 907.5, + "width": 87, + "height": 13, + "text": "doRecordSkip" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n3z7GQHHNY=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 1072, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n3z7GQIaUk=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 1072, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 908.5, + "top": 900.5, + "width": 98.12451171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+n3z7GQFG64=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+n3z7GQGJmk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+n3z7GQHHNY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+n3z7GQIaUk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+n3z7GQJ098=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+n3z7GQKV2I=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+n3z7GQLZiI=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+n3z7GQMex8=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+n3z7WQNVSc=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 888, + "top": 896, + "width": 138, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+n3z7GQJ098=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+n3z7GQKV2I=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+n3z7GQLZiI=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+n3z7GQMex8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+n3z7WQNVSc=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+n8X9HOVNKs=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+n8X9HOWLww=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+n8X9XOXkdk=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -976, + "top": -320, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n8X9XOY3/k=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "font": "Arial;13;1", + "left": 587.5, + "top": 419.5, + "width": 135, + "height": 13, + "text": "doMove2NextValidate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n8X9XOZd4c=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -976, + "top": -320, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n8X9XOalho=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -976, + "top": -320, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 582.5, + "top": 412.5, + "width": 145, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+n8X9XOXkdk=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+n8X9XOY3/k=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+n8X9XOZd4c=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+n8X9XOalho=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+n8X9XObuaA=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+n8X9XOc/uM=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+n8X9XOdBOU=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+n8X9XOeXy8=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+n8X9XOfF+Y=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 552, + "top": 408, + "width": 206, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+n8X9XObuaA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+n8X9XOc/uM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+n8X9XOdBOU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+n8X9XOeXy8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+n8X9XOfF+Y=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+oUnoB1S/NM=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3GYHfzyUBIH8=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "font": "Arial;13;0", + "left": 826, + "top": 246, + "width": 98.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 1, + "text": "+计算下一个目标" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoB1U2Yg=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 866, + "top": 234, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoB1V4II=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 892, + "top": 271, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1Ww1E=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1PoOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 692, + "top": 373, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1XLyA=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1PoOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 687, + "top": 361, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1Y5p0=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1PoOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 398, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1ZY1E=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1Q1uk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1058, + "top": 119, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1aRTo=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1Q1uk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1048, + "top": 109, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1bUzg=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1Q1uk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1077, + "top": 139, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+oUnoR1cIHg=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1PoOw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+oUnoR1d4qE=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1Q1uk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "lineStyle": 1, + "points": "680:407;1088:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3GYHfzyUBIH8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+oUnoB1U2Yg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+oUnoB1V4II=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+oUnoR1Ww1E=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+oUnoR1XLyA=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+oUnoR1Y5p0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+oUnoR1ZY1E=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+oUnoR1aRTo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+oUnoR1bUzg=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+oUnoR1cIHg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+oUnoR1d4qE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2/55prhrf+xg=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2/55prhrgemE=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2/55prhrh4Oo=", + "_parent": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48, + "top": 448, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2/55prhrinco=", + "_parent": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "font": "Arial;13;1", + "left": 619, + "top": 899.5, + "width": 96, + "height": 13, + "text": "doRecordDirty" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2/55prhrjBVk=", + "_parent": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48, + "top": 448, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2/55prhrkkxo=", + "_parent": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48, + "top": 448, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 614, + "top": 892.5, + "width": 106, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2/55prhrh4Oo=" + }, + "nameLabel": { + "$ref": "AAAAAAF2/55prhrinco=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2/55prhrjBVk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2/55prhrkkxo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2/55prhrl5zY=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2/55prhrmK5A=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2/55prhrnGxY=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2/55prhroX/Q=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2/55prhrpOzg=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 592, + "top": 888, + "width": 150, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2/55prhrl5zY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2/55prhrmK5A=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2/55prhrnGxY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2/55prhroX/Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2/55prhrpOzg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3AAi3NvRv3KY=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvRwDN8=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 847, + "top": 193, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvRxRCk=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 841, + "top": 179, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvRypxI=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 220, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvRziZA=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRsLF0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 654, + "top": 273, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR0i3M=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRsLF0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 651, + "top": 260, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR1v00=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRsLF0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 660, + "top": 300, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR27EA=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRtPso=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1041, + "top": 113, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR3NBA=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRtPso=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1034, + "top": 101, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR46nA=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRtPso=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1055, + "top": 136, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAi3NvR5srI=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRsLF0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAi3NvR6YUo=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRtPso=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "lineStyle": 1, + "points": "636:303;1071:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3AAi3NvRwDN8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3AAi3NvRxRCk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3AAi3NvRypxI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3AAi3NvRziZA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3AAi3NvR0i3M=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3AAi3NvR1v00=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3AAi3NvR27EA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3AAi3NvR3NBA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3AAi3NvR46nA=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3AAi3NvR5srI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3AAi3NvR6YUo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3AAkuEf3u4rc=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3vFUU=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "font": "Arial;13;0", + "left": 786, + "top": 136, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 1, + "text": "+重新测量" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3wr8I=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 812, + "top": 121, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3x3Io=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 820, + "top": 165, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3yj1w=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3rpYI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 596, + "top": 174, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3zA9Y=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3rpYI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 596, + "top": 161, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf30kh0=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3rpYI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 597, + "top": 202, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf31ZFk=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3seOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1034, + "top": 97, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf32s54=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3seOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1030, + "top": 85, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf33mtU=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3seOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1043, + "top": 124, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAkuEf341iM=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3rpYI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAkuEf35gXc=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3seOw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "lineStyle": 1, + "points": "574:200;1063:114", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3AAkuEf3vFUU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3AAkuEf3wr8I=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3AAkuEf3x3Io=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3AAkuEf3yj1w=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3AAkuEf3zA9Y=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3AAkuEf30kh0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3AAkuEf31ZFk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3AAkuEf32s54=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3AAkuEf33mtU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3AAkuEf341iM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3AAkuEf35gXc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3AAllGAV4vW0=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV5JwE=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "font": "Arial;13;0", + "left": 540, + "top": 250, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 1, + "text": "+清空测量" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV6J1c=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 582, + "top": 242, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV7E+E=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": 267, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV8Fz4=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV1sLI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 559, + "top": 234, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV9EBE=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV1sLI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 572, + "top": 229, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV+La8=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV1sLI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 534, + "top": 245, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV/WHE=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV2oyY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 580, + "top": 267, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAWA3ZU=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV2oyY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 590, + "top": 257, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAWB0W0=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV2oyY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 559, + "top": 285, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAllGAWCqYI=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV1sLI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAllGAWDVu4=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV2oyY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "tail": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "lineStyle": 1, + "points": "533:227;582:303", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3AAllGAV5JwE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3AAllGAV6J1c=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3AAllGAV7E+E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3AAllGAV8Fz4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3AAllGAV9EBE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3AAllGAV+La8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3AAllGAV/WHE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3AAllGAWA3ZU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3AAllGAWB0W0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3AAllGAWCqYI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3AAllGAWDVu4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3ABeWIk8op44=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8pzMQ=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 514, + "top": 591, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8qvK8=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 516, + "top": 576, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8rXNY=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 511, + "top": 620, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8sd3M=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8l/nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 486, + "top": 588, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8tucs=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8l/nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 490, + "top": 575, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8uDSU=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8l/nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 479, + "top": 614, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8v4Ak=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8mwTw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 542, + "top": 595, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8wWtM=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8mwTw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 542, + "top": 581, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8xBTc=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8mwTw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": 622, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3ABeWIk8yQcs=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8l/nk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3ABeWIk8z5Rc=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8mwTw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "tail": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "lineStyle": 1, + "points": "459:606;567:619", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3ABeWIk8pzMQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3ABeWIk8qvK8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3ABeWIk8rXNY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3ABeWIk8sd3M=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3ABeWIk8tucs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3ABeWIk8uDSU=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3ABeWIk8v4Ak=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3ABeWIk8wWtM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3ABeWIk8xBTc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3ABeWIk8yQcs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3ABeWIk8z5Rc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYXf89UtfGE=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89UuSck=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "font": "Arial;13;0", + "left": 903, + "top": 467, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89Uv0GE=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 917, + "top": 467, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89UwhBk=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 961, + "top": 466, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89Ux8/0=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUqXjA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 932, + "top": 487, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89Uyiek=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUqXjA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 919, + "top": 485, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89Uz1EE=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUqXjA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 491, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89U0nxQ=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf89Uremo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 931, + "top": 447, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89U16n8=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf89Uremo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 918, + "top": 449, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89U2Rmk=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf89Uremo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 958, + "top": 442, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYXf89U3eCA=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUqXjA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYXf89U4/vg=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf89Uremo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "tail": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "lineStyle": 1, + "points": "948:519;946:427", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYXf89UuSck=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYXf89Uv0GE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYXf89UwhBk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYXf89Ux8/0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYXf89Uyiek=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYXf89Uz1EE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYXf89U0nxQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYXf89U16n8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYXf89U2Rmk=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYXf89U3eCA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYXf89U4/vg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYY3Odi5Qvo=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi62oY=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "font": "Arial;13;0", + "left": 993, + "top": 243, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi7tcE=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1003, + "top": 236, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi8lBY=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1043, + "top": 258, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi96UE=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi2Kgc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 955, + "top": 355, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi+RAs=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi2Kgc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 944, + "top": 346, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi/zVk=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi2Kgc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 977, + "top": 372, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3OdjAr2E=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi3/4g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1078, + "top": 132, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3OdjB8MY=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi3/4g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1065, + "top": 128, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3OdjC1b8=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi3/4g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1104, + "top": 141, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYY3OdjDoGI=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi2Kgc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYY3OdjEpKI=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi3/4g=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "lineStyle": 1, + "points": "956:391;1104:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYY3Odi62oY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYY3Odi7tcE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYY3Odi8lBY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYY3Odi96UE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYY3Odi+RAs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYY3Odi/zVk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYY3OdjAr2E=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYY3OdjB8MY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYY3OdjC1b8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYY3OdjDoGI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYY3OdjEpKI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF3FYZbFNuAuzw=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF3FYZbFNuBlYE=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF3FYZbFduC04Q=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 16, + "top": 464, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYZbFduDcAk=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "font": "Arial;13;1", + "left": 852, + "top": 843.5, + "width": 62, + "height": 13, + "text": "需要补测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYZbFduER9s=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 16, + "top": 464, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYZbFduFXxc=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 16, + "top": 464, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 847, + "top": 836.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYZbFduC04Q=" + }, + "nameLabel": { + "$ref": "AAAAAAF3FYZbFduDcAk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF3FYZbFduER9s=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYZbFduFXxc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF3FYZbFduGvug=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF3FYZbFduHXxg=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF3FYZbFduIknI=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF3FYZbFduJrfE=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF3FYZbFduKuNA=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 832, + "top": 832, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF3FYZbFduGvug=" + }, + "operationCompartment": { + "$ref": "AAAAAAF3FYZbFduHXxg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF3FYZbFduIknI=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF3FYZbFduJrfE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF3FYZbFduKuNA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF3FYeGO+xbgps=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF3FYeGO+xcNdU=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF3FYeGO+xdFmg=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 144, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYeGO+xeMok=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "font": "Arial;13;1", + "left": 1324, + "top": 795.5, + "width": 62, + "height": 13, + "text": "补测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYeGO+xfBVg=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 144, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYeGO+xgJBc=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 144, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1319, + "top": 788.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYeGO+xdFmg=" + }, + "nameLabel": { + "$ref": "AAAAAAF3FYeGO+xeMok=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF3FYeGO+xfBVg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYeGO+xgJBc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF3FYeGPOxh8UQ=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF3FYeGPOxiyA8=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF3FYeGPOxjOfM=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF3FYeGPOxk208=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF3FYeGPOxlhv8=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1304, + "top": 784, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF3FYeGPOxh8UQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAF3FYeGPOxiyA8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF3FYeGPOxjOfM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF3FYeGPOxk208=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF3FYeGPOxlhv8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYfmnPCIr84=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCJbKg=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "font": "Arial;13;0", + "left": 676, + "top": 471, + "width": 216.61895751953125, + "height": 13, + "alpha": 0.1884747434719145, + "distance": 17.26267650163207, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 1, + "text": "+未通过检测,将补测数据标识为dirty" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCK6BE=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 790, + "top": 503, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCLgus=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 806, + "top": 460, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCMTXU=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CF45U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 871, + "top": 517, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCN6dg=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CF45U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 864, + "top": 529, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCO0WE=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CF45U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 885, + "top": 493, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCPTs4=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CGlMo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 719, + "top": 460, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCQ4ZQ=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CGlMo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 717, + "top": 473, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCR0YI=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CGlMo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 725, + "top": 433, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYfmnPCS3/Q=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CF45U=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYfmnPCTkR4=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CGlMo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "tail": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "lineStyle": 1, + "points": "901:519;701:443", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYfmnPCJbKg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYfmnPCK6BE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYfmnPCLgus=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYfmnPCMTXU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYfmnPCN6dg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYfmnPCO0WE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYfmnPCPTs4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYfmnPCQ4ZQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYfmnPCR0YI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYfmnPCS3/Q=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYfmnPCTkR4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYiOTvpbRvo=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpckKI=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 246, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpdswc=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 866, + "top": 234, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpeCiY=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 892, + "top": 271, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpf64s=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpYHAk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 692, + "top": 373, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpgCV4=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpYHAk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 687, + "top": 361, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvph4mg=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpYHAk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 398, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpiVXw=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpZRGM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1058, + "top": 119, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpj6rs=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpZRGM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1048, + "top": 109, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpkLlM=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpZRGM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1077, + "top": 139, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYiOTvplKeU=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpYHAk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYiOTvpmbVY=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpZRGM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "lineStyle": 1, + "points": "680:407;1088:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYiOTvpckKI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYiOTvpdswc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYiOTvpeCiY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYiOTvpf64s=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYiOTvpgCV4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYiOTvph4mg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYiOTvpiVXw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYiOTvpj6rs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYiOTvpkLlM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYiOTvplKeU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYiOTvpmbVY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYjyg/5tJuM=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyg/5u2LA=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "font": "Arial;13;0", + "left": 907, + "top": 613, + "width": 163.864990234375, + "height": 13, + "alpha": -2.906930651480722, + "distance": 49.64876634922564, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 1, + "text": "+未通过检测,选择清空测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyg/5vWMM=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1049, + "top": 630, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP5wgnA=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1012, + "top": 655, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP5x/LY=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5q+Kw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 986, + "top": 562, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP5yX1g=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5q+Kw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 999, + "top": 556, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP5z07A=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5q+Kw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 961, + "top": 573, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP502Qw=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5rtgo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1089, + "top": 715, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP51mnU=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5rtgo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1098, + "top": 705, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP52OCQ=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5rtgo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1068, + "top": 733, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYjyhP53e10=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5q+Kw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYjyhP54iWg=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5rtgo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "tail": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "lineStyle": 1, + "points": "960:555;1091:751", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYjyg/5u2LA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYjyg/5vWMM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYjyhP5wgnA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYjyhP5x/LY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYjyhP5yX1g=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYjyhP5z07A=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYjyhP502Qw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYjyhP51mnU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYjyhP52OCQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYjyhP53e10=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYjyhP54iWg=" + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mcRVqBmJfY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doSurveyor", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+memFKDDSP0=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "name": "成功", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+memFaDE9N8=", + "_parent": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "reference": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+memFaDFhUw=", + "_parent": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "reference": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mglyqGKrLA=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "name": "测量失败次数过多", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mgly6GLeNY=", + "_parent": { + "$ref": "AAAAAAF2+mglyqGKrLA=" + }, + "reference": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mgly6GM4vI=", + "_parent": { + "$ref": "AAAAAAF2+mglyqGKrLA=" + }, + "reference": { + "$ref": "AAAAAAF2+mgPp6E+Z94=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mlDdqJrvAs=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "name": "测量失败,又没有允许重复尝试", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mlDdqJshZY=", + "_parent": { + "$ref": "AAAAAAF2+mlDdqJrvAs=" + }, + "reference": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mlDdqJtw60=", + "_parent": { + "$ref": "AAAAAAF2+mlDdqJrvAs=" + }, + "reference": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mdRV6CVRE8=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkReadData", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+moC5KQL07Q=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+moC5KQMlXg=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "reference": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+moC5KQNhhs=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "reference": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mrOv6VGNxM=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "name": "未通过检测提示目标两次读数超限请重新测量", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mrOv6VHNRw=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "reference": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mrOv6VIVq0=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mgPp6E+Z94=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "RecordDirty" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mkD1KIH4O4=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "SurveyorFailure", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+n5IxmZmfb4=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "name": "决定跳过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n5IxmZn2bs=", + "_parent": { + "$ref": "AAAAAAF2+n5IxmZmfb4=" + }, + "reference": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n5IxmZowY8=", + "_parent": { + "$ref": "AAAAAAF2+n5IxmZmfb4=" + }, + "reference": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+n7Ipmp5/TQ=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "name": "取消跳过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n7Ipmp6n4I=", + "_parent": { + "$ref": "AAAAAAF2+n7Ipmp5/TQ=" + }, + "reference": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n7Ipmp7myU=", + "_parent": { + "$ref": "AAAAAAF2+n7Ipmp5/TQ=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mntyKOMDSM=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isHalfCycleZeroCheckReady", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mvs0qcw0ng=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mvs0qcx6HM=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "reference": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mvs0qcyuaY=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "reference": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+m650rJ78WY=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "name": "不满足", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m650rJ8zw4=", + "_parent": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "reference": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m650rJ9BDM=", + "_parent": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "reference": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mq6h6Ss6fQ=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doDeleteCurrentCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mw/ialD1P0=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mw/iqlEWtE=", + "_parent": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "reference": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mw/iqlF64M=", + "_parent": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mvXKaZ71tg=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkHalfCycleZero", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+m3lu6+/SvE=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m3lu6/AYdA=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "reference": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m3lu6/BCoQ=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "reference": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+m4Cd7DMOyM=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m4Cd7DNh98=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "reference": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m4Cd7DOnkA=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "reference": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mwCOqhz6ko=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Idle" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+m3Ng67UQ3Q=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isReady2CCheck", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+m/aRbZjsQw=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m/aRbZkwdI=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "reference": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m/aRbZlRAA=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nJuA+oxvHQ=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "name": "不满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nJuA+oyVzg=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "reference": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nJuA+ozWP8=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+m+73LQ2jlo=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "check2C", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nC6YsguVIY=", + "_parent": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nC6Y8gvJw0=", + "_parent": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nC6Y8gwxpA=", + "_parent": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+owe6Cfh2+U=", + "_parent": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "name": "忽略错误", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+owe6CfiblE=", + "_parent": { + "$ref": "AAAAAAF2+owe6Cfh2+U=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+owe6CfjEGs=", + "_parent": { + "$ref": "AAAAAAF2+owe6Cfh2+U=" + }, + "reference": { + "$ref": "AAAAAAF2/55prRrd34g=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3AAkuEf3qL3g=", + "_parent": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "name": "重新测量", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAkuEf3rpYI=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAkuEf3seOw=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3AAllGAV08Nw=", + "_parent": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "name": "清空测量", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAllGAV1sLI=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAllGAV2oyY=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nB7EcWt+n8=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isSingleCycleCompleted", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nQJohB/pjc=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "name": "未通过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nQJohCAKVI=", + "_parent": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nQJohCBbxs=", + "_parent": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nS1vB/7hWk=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nS1vB/8CFI=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nS1vB/9vRE=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nIhauTyfGU=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doRecordClean", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+n9ElngPQXA=", + "_parent": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n9ElngQC7s=", + "_parent": { + "$ref": "AAAAAAF2+n9ElngPQXA=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n9ElngRO/w=", + "_parent": { + "$ref": "AAAAAAF2+n9ElngPQXA=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3ABeWIk8kkqs=", + "_parent": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3ABeWIk8l/nk=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3ABeWIk8mwTw=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nRKkx5T21c=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nhS8LdviJA=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nhS8bdwtKo=", + "_parent": { + "$ref": "AAAAAAF2+nhS8LdviJA=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nhS8bdxqW4=", + "_parent": { + "$ref": "AAAAAAF2+nhS8LdviJA=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nm/XgG9mDY=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nm/XgG+7Ao=", + "_parent": { + "$ref": "AAAAAAF2+nm/XgG9mDY=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nm/XgG/cLw=", + "_parent": { + "$ref": "AAAAAAF2+nm/XgG9mDY=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYXf8tUp5SY=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYXf8tUqXjA=", + "_parent": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYXf89Uremo=", + "_parent": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYfmm/CEg44=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "未通过检测,将补测数据标识为dirty", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYfmm/CF45U=", + "_parent": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYfmm/CGlMo=", + "_parent": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYjyg/5pmRs=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "未通过检测,选择清空测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYjyg/5q+Kw=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYjyg/5rtgo=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "reference": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nWEKyMuLhQ=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isAllCycleCompleted" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nfCMJ2/R+8=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isAllCycleCompleted", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nkxU+qk8wM=", + "_parent": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "name": "不满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nkxVOqlU+M=", + "_parent": { + "$ref": "AAAAAAF2+nkxU+qk8wM=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nkxVOqmmi4=", + "_parent": { + "$ref": "AAAAAAF2+nkxU+qk8wM=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nsWEifnmc4=", + "_parent": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nsWEifod44=", + "_parent": { + "$ref": "AAAAAAF2+nsWEifnmc4=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nsWEifpM0I=", + "_parent": { + "$ref": "AAAAAAF2+nsWEifnmc4=" + }, + "reference": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYY3ONi1k54=", + "_parent": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYY3Odi2Kgc=", + "_parent": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYY3Odi3/4g=", + "_parent": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nmf8//EQJ0=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doDeleteAllCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nnjTAPYxiQ=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nnjTAPZd8A=", + "_parent": { + "$ref": "AAAAAAF2+nnjTAPYxiQ=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nnjTAPaO1I=", + "_parent": { + "$ref": "AAAAAAF2+nnjTAPYxiQ=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3AAi3NfRr6EY=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAi3NfRsLF0=", + "_parent": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAi3NfRtPso=", + "_parent": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nq2QxzDZ/U=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkAllCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+ntEUyxG5GE=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+ntEUyxHkJg=", + "_parent": { + "$ref": "AAAAAAF2+ntEUyxG5GE=" + }, + "reference": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+ntEUyxITXI=", + "_parent": { + "$ref": "AAAAAAF2+ntEUyxG5GE=" + }, + "reference": { + "$ref": "AAAAAAF2+nsueSp07D8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nt66S40Bz8=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nt66S41kFQ=", + "_parent": { + "$ref": "AAAAAAF2+nt66S40Bz8=" + }, + "reference": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nt66S42nQw=", + "_parent": { + "$ref": "AAAAAAF2+nt66S40Bz8=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nsueSp07D8=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Finish" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+n3z62QBjMI=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doRecordSkip", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+n81lnZzRwY=", + "_parent": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n81lnZ00eg=", + "_parent": { + "$ref": "AAAAAAF2+n81lnZzRwY=" + }, + "reference": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n81lnZ1tkU=", + "_parent": { + "$ref": "AAAAAAF2+n81lnZzRwY=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+n8X9HOTo5I=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doMove2NextValidate", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+oUnnx1ORxs=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "name": "计算下一个目标", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+oUnnx1PoOw=", + "_parent": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+oUnnx1Q1uk=", + "_parent": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYiOTvpXxUA=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYiOTvpYHAk=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYiOTvpZRGM=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2/55prRrd34g=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doRecordDirty", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2/57X7ycUMD0=", + "_parent": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "name": "单测回完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/57X7ycVqls=", + "_parent": { + "$ref": "AAAAAAF2/57X7ycUMD0=" + }, + "reference": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/57X7ycW028=", + "_parent": { + "$ref": "AAAAAAF2/57X7ycUMD0=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3ABn9InDG0I8=", + "_parent": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3ABn9InDHYy0=", + "_parent": { + "$ref": "AAAAAAF3ABn9InDG0I8=" + }, + "reference": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3ABn9InDIm3A=", + "_parent": { + "$ref": "AAAAAAF3ABn9InDG0I8=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2/+4lLTMZ3R0=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isSingleCycleCompletedAfterDirty", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2/+8EZEWEVSo=", + "_parent": { + "$ref": "AAAAAAF2/+4lLTMZ3R0=" + }, + "name": "单测回未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/+8EZEWFV4M=", + "_parent": { + "$ref": "AAAAAAF2/+8EZEWEVSo=" + }, + "reference": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/+8EZEWGccA=", + "_parent": { + "$ref": "AAAAAAF2/+8EZEWEVSo=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2/+8rLEgaoTY=", + "_parent": { + "$ref": "AAAAAAF2/+4lLTMZ3R0=" + }, + "name": "满足", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/+8rLEgb+jA=", + "_parent": { + "$ref": "AAAAAAF2/+8rLEgaoTY=" + }, + "reference": { + "$ref": "AAAAAAF2/+4lLTMZ3R0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/+8rLEgciEE=", + "_parent": { + "$ref": "AAAAAAF2/+8rLEgaoTY=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2/+6bzj11GxQ=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkSingleCycleAfterDirty" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF3FYZbFNt+k4c=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "需要补测" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF3FYeGOuxZC7s=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "补测" + } + ] + } + ] +} \ 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 new file mode 100644 index 0000000..1189ca5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/App.java @@ -0,0 +1,210 @@ +package com.bingce.controlnetwork; + +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; + +import androidx.appcompat.app.AppCompatDelegate; +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.tolerance.load.ToleranceLoadUtil; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorConstants; +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; +import com.umeng.commonsdk.UMConfigure; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.polaric.colorful.Colorful; + +import blankj.utilcode.util.ActivityUtils; +import blankj.utilcode.util.Utils; +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; + +public class App extends RepositoryBaseApp { + + /** + * 试用次数 + */ + public int tryCount = 0; //非setting + /** + * 上次手动点击跳过首屏广告的时间 + */ + public long lastSplashShowTime = 0;//非setting + /** + * 磁偏角,用于校正指南针 + */ + public float magneticDeclination = 0; + /** + * 蓝牙是否连接 + */ + public boolean isBluetoothConnected = false; + /** + * 蓝牙是否重连 + */ + public boolean isBluetoothReconnect = false; + /** + * 退出软件后是否关闭设备 + */ + public boolean isCloseInstrumentAfterExit = false; + /** + * 用户状态发生变化,例如登录 + */ + public boolean isUserStatusChanged = false; + /** + * 注册码第二版 + */ + public String registerCodeV2 = ""; + + public String wifiChatClientIp = ""; + public String lastPhoneLocation = ""; + + public String levelSurveyorTime; + + private static App app; + + @Override + public void onCreate() { + customChannel = AppChannel.CUSTOM_CONTROL_PUBLIC;//AppChannel.CUSTOM_PUBLIC; + super.onCreate(); + app = this; + + initThemeDark(); + + RxJavaPlugins.setErrorHandler(new Consumer() { + @Override + public void accept(Throwable throwable) { + Log.e("rxThrowable", String.valueOf(throwable)); + } + }); + + UMConfigure.preInit(this, "62c2c24705844627b5d6f943", "public"); + + // 在 LeanCloud.initialize() 之前调用 + LeanCloud.setLogLevel(LCLogger.Level.DEBUG); + + LeanCloud.initialize(this + , DES.decryptIt("//HYY/P0uNjW2bvmcfWVsRqUZcBGI1mjKeLw17mtlc4poF3nDQzo0Q==")//id,BvjcpX3kNB69xP8N0fHxDQav-gzGzoHsz + , DES.decryptIt("LBk6WfZhiDVIlf/vpesX6s8j4ik+d23atgE0QGuwyw8=") + , "https://leancloud.bingce.com"); + + PushService.setDefaultPushCallback(this, NotificationActivity.class); + PushService.setAutoWakeUp(true); + PushService.setDefaultChannelId(this, "normal"); + LCInstallation.getCurrentInstallation().saveInBackground().subscribe(); + + DrawerImageLoader.init(new AbstractDrawerImageLoader() { + @Override + public void set(ImageView imageView, Uri uri, Drawable placeholder) { +// Picasso.get().load(uri).placeholder(placeholder).into(imageView); + Glide.with(App.this).load(uri).into(imageView); + } + + @Override + public void cancel(ImageView imageView) { + Glide.with(App.this).clear(imageView); +// Picasso.get().cancelRequest(imageView); + } + }); + + restorePrefs(); + + if (customChannel == AppChannel.CUSTOM_CONTROL_PRO) { + Colorful.config(this).primaryColor(Colorful.ThemeColor.BROWN).apply(); + Colorful.config(this).accentColor(Colorful.ThemeColor.BROWN).apply(); + } + + + initControlApp(); + } + + private void initThemeDark() { + Colorful.defaults() + .primaryColor(Colorful.ThemeColor.BLUE) + .accentColor(Colorful.ThemeColor.BLUE) + .translucent(false) + .dark(SettingValueUtil.isThemeDark()); + Colorful.init(this); + + if (SettingValueUtil.isThemeDark()) { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); + } else { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); + } + } + + private void restorePrefs() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + registerCodeV2 = prefs.getString("registerCodeV2", ""); + lastSplashShowTime = prefs.getLong("lastSplashShowTime", 0); + wifiChatClientIp = prefs.getString("wifiChatClientIp", ""); + 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 + public void onTrimMemory(int level) { + super.onTrimMemory(level); + if (level == TRIM_MEMORY_MODERATE) { + //开始自杀,清场掉所有的activity + ActivityUtils.finishAllActivities(); + } + } + + @Override + public String applicationId() { + return BuildConfig.APPLICATION_ID; + } + + @Override + public boolean isThemeDark() { + return false; + } + + @Override + public int angleNotNumber() { + return AppConfig.instance.angleDotNum(); + } + + public static App getApp() { + return app; + } + + @Override + protected void initTtsManager() { + TtsManager.getInstance().init(this); + } + + private void initControlApp() { + userAgreementAgree = true; + ISurveyorConstants.isOpenAtr = SettingValueUtil.isOpenAtr(); + Utils.init(this); + ThreadPoolUtil.execute(ToleranceLoadUtil::init); + //数据库 + 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 new file mode 100644 index 0000000..fd1cf35 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/AboutActivity.java @@ -0,0 +1,83 @@ +package com.bingce.controlnetwork.activity; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import org.polaric.colorful.ColorfulActivity; + +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; + +public class AboutActivity extends ColorfulActivity { + private Toolbar mToolbar; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_about); + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + final FrameLayout flHolder = findViewById(R.id.activity_about_frame); + View tianjinView = getTianjinView(); + flHolder.addView(tianjinView); + } + + @Override + public boolean onCreateOptionsMenu(@NonNull Menu menu) { + getMenuInflater().inflate(R.menu.menu_activity_about, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + break; + case R.id.menu_debug_switch: + startOpenCloseMeasureDebug(); + break; + } + return super.onOptionsItemSelected(item); + } + + private View getTianjinView() { + View viewTianjin = View.inflate(this, R.layout.item_about_tj_one, null); +// TextView tvUnit = viewTianjin.findViewById(R.id.tvUnit); + TextView tvVersion = viewTianjin.findViewById(R.id.tvVersion); + tvVersion.setText(Tools.getVersionName()); + return viewTianjin; + } + + /** + * 开始打开或关闭调试 + */ + 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/BaseActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/BaseActivity.java new file mode 100644 index 0000000..93d121d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/BaseActivity.java @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.activity; + +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import org.polaric.colorful.ColorfulActivity; + +import com.bingce.controlnetwork.R; + +public abstract class BaseActivity extends ColorfulActivity { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public void setContentView(View view) { + super.setContentView(view); + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public void setContentView(int layoutResID) { + super.setContentView(layoutResID); + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public void setContentView(View view, ViewGroup.LayoutParams params) { + super.setContentView(view, params); + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/ChangelogActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/ChangelogActivity.java new file mode 100644 index 0000000..ee63361 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/ChangelogActivity.java @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.activity; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.view.MenuItem; + +import androidx.appcompat.widget.Toolbar; + +import org.polaric.colorful.ColorfulActivity; + +import com.bingce.controlnetwork.R; + +/** + * 更新日志 + */ +public class ChangelogActivity extends ColorfulActivity { + private static final String TAG = "ChangelogActivity"; + private Toolbar mToolbar; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_changelog); + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/LogCollectActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/LogCollectActivity.java new file mode 100644 index 0000000..8f211f7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/LogCollectActivity.java @@ -0,0 +1,26 @@ +package com.bingce.controlnetwork.activity; + +import android.content.Context; +import android.content.Intent; + +import com.bingce.activity.AbstractLogCollectActivity; + +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.BuildConfig; + +public class LogCollectActivity extends AbstractLogCollectActivity { + @Override + protected String applicationId() { + return BuildConfig.APPLICATION_ID; + } + + @Override + protected boolean isLandscape() { + return ((App) getApplication()).isLandscape(); + } + + public static void start(Context context) { + Intent intent = new Intent(context, LogCollectActivity.class); + context.startActivity(intent); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java new file mode 100644 index 0000000..8197a19 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java @@ -0,0 +1,622 @@ +package com.bingce.controlnetwork.activity; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.WindowManager; +import android.widget.CheckBox; +import android.widget.CompoundButton; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +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; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.AppChannel; +import com.bingce.BaseApp; +import com.bingce.activity.BaseMainActivity; +import com.bingce.controlapphelper.event.DatabaseReadyEvent; +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.launch.BackupImportHelper; +import com.bingce.controlnetwork.activity.user.RegisterActivity; +import com.bingce.controlnetwork.fragment.MainSurveyFragment; +import com.bingce.controlnetwork.fragment.ProjectListFragment; +import com.bingce.controlnetwork.newui.configfragment.ConfigFragment; +import com.bingce.controlnetwork.newui.mefragment.MeFragment; +import com.bingce.controlnetwork.viewmodel.MainActivityViewModel; +import com.bingce.data.sync.GlobalFlowCenter; +import com.bingce.device.Device; +import com.bingce.device.ui.manager.DeviceConnectManager; +import com.bingce.device.ui.manager.DeviceRemindManager; +import com.bingce.device.ui.manager.DeviceRequestManager; +import com.bingce.event.CountDownEvent; +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.ColorUtil; +import com.bingce.utils.DateUtils; +import com.bingce.utils.SdkUtils; +import com.bingce.utils.SoundPoolUtil; +import com.bingce.utils.VipManager; +import com.daimajia.numberprogressbar.NumberProgressBar; +import com.flyco.tablayout.CommonTabLayout; +import com.flyco.tablayout.listener.CustomTabEntity; +import com.flyco.tablayout.listener.OnTabSelectListener; +import com.mikepenz.iconics.IconicsDrawable; +import com.mikepenz.material_design_iconic_typeface_library.MaterialDesignIconic; +import com.tencent.mm.opensdk.openapi.IWXAPI; +import com.tencent.mm.opensdk.openapi.WXAPIFactory; +import com.umeng.commonsdk.UMConfigure; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.polaric.colorful.Colorful; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ActivityUtils; +import blankj.utilcode.util.ServiceUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCObject; +import cn.leancloud.LCQuery; +import cn.leancloud.LCUser; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +public class MainActivity extends BaseMainActivity implements Device.IDeviceConnectListener, Device.IDeviceRequestListener, Device.IDeviceRemindListener { + public MainActivityUtils mainActivityUtils = new MainActivityUtils(this, () -> this); + private final DeviceConnectManager deviceConnectManager = new DeviceConnectManager(this, this); + public final DeviceRequestManager deviceRequestManager = new DeviceRequestManager(this, this); + 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 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_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_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); + mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class); + EventBus.getDefault().register(this); + + if (isThemeDark()) { + setTheme(R.style.CustomThemeDark); + } + Colorful.applyTheme(this); + setContentView(R.layout.activity_main); + initWidgetListener(savedInstanceState);//初始化组件和监听器 + + ((App) Utils.getApp()).tryCount = 0; + IntentFilter filter = new IntentFilter(); + filter.addAction(MAIN_IN_ACTION_NAME); + +// if (LCUser.getCurrentUser() != null && LCUser.getCurrentUser().isAuthenticated()) { +// +// } + VipManager.getInstance().controlSdkRefresh(this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + + } + + @Override + public void onRefreshFailed(int errorCode) { + + } + }); + } + + /** + * 初始化组件和监听器,屏幕方向发生改变时执行一次 + */ + private void initWidgetListener(Bundle savedInstanceState) { + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + setTitle(R.string.app_name); + //set the back arrow in the toolbar + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(false); + getSupportActionBar().setDisplayShowTitleEnabled(true); + } + cutDownProgressBar = findViewById(R.id.cut_down_progressbar); + mViewPager = findViewById(R.id.activity_main_viewpager); + mTabLayout = findViewById(R.id.activity_main_tab_layout); + if (isThemeDark()) { + if (mTabLayout != null) { + mTabLayout.setBackgroundColor(Color.DKGRAY); + mTabLayout.setTextUnselectColor(Color.LTGRAY); + mTabLayout.setUnderlineColor(Color.BLACK); + } + } + mTitles = new String[]{getString(R.string.project), getString(R.string.survey), getString(R.string.label_manager), 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])); + } + + mTabLayout.setTabData(mTabEntities); + mTabLayout.setOnTabSelectListener(new OnTabSelectListener() { + @Override + public void onTabSelect(int position) { + mViewPager.setCurrentItem(position); + } + + @Override + public void onTabReselect(int position) { + if (position == 0) { +// mTabLayout.showMsg(0, mRandom.nextInt(100) + 1); +// UnreadMsgUtils.show(mTabLayout_2.getMsgView(0), mRandom.nextInt(100) + 1); + } + } + }); + + 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) { + + } + + @Override + public void onPageSelected(int position) { + setCurrentTab(position); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + } + + public void setCurrentTab(int position) { + mTabLayout.setCurrentTab(position); + } + + + private void updateSplashLog(final boolean autoDismiss, final boolean skipDismiss, final boolean clickImageDismiss) { + if (AppChannel.customChannel != AppChannel.CUSTOM_CONTROL_PUBLIC) + return;//只统计公版 + final Date today = DateUtils.reverse2Date(DateUtils.getTodayStartTime()); + new LCQuery<>("SplashLog") + .whereEqualTo("date", today) + .findInBackground().subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(List avObjects) { + if (avObjects != null && !avObjects.isEmpty()) { + avObjects.get(0).increment("showTimes"); + if (autoDismiss) + avObjects.get(0).increment("autoDismissTimes"); + if (skipDismiss) + avObjects.get(0).increment("skipTimes"); + if (clickImageDismiss) + avObjects.get(0).increment("clickTimes"); + avObjects.get(0).saveInBackground().subscribe(); + } else { + LCObject splashLog = new LCObject("SplashLog"); + splashLog.put("date", today); + splashLog.saveInBackground().subscribe(); + } + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } + + /** + * 读取项目文件 + */ + @Override + public void initialize() { + //友盟统计 + UMConfigure.init(this, "62c2c24705844627b5d6f943", "public", UMConfigure.DEVICE_TYPE_PHONE, ""); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {//安卓10以下,请求读取硬件信息 + mainActivityUtils.requestPhonePermission(); + } + try {//微信插件实例化 + if (Utils.getApp() instanceof BaseApp) { + IWXAPI wxApi = WXAPIFactory.createWXAPI(this, "wx8b41ad369eba83a9"); + wxApi.registerApp("wx8b41ad369eba83a9"); + ((BaseApp) Utils.getApp()).setWxApi(wxApi); + } + } catch (Exception ignored) { + } +// CheckControlUpdateUtil.checkUpdate(this, false); + EventBus.getDefault().post(new DatabaseReadyEvent()); + + if (LCUser.getCurrentUser() == null) { + VipManager.getInstance().controlSdkRefresh(this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + Log.d("controlSdkRefresh", "onRefreshSuccess"); + } + + @Override + public void onRefreshFailed(int errorCode) { + Log.d("controlSdkRefresh", "onRefreshFailed--errorCode--" + errorCode); + } + }); + } + + GlobalFlowCenter.Companion.getInstance().onMainActivityInitial(); + } + + // this piece of code is show how to press twice back button to exit App + private long exitTime = 0; + + public void ExitApp() { + if ((System.currentTimeMillis() - exitTime) > 2000) { + ToastUtils.showShort(getString(R.string.press_again_exit)); + exitTime = System.currentTimeMillis(); + } else { + if (((App) Utils.getApp()).isBluetoothConnected) { + if (TotalStation.getInstance().isSupportPowerOff()) { + showPowerOffDialog(); + } else { + finish(); + } + } else { + finish(); + } + } + } + + public void showPowerOffDialog() { + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.hint) + .customView(R.layout.dialog_power_off, false) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + if (((App) Utils.getApp()).isCloseInstrumentAfterExit) { + TotalStation.getInstance().powerOff(); + } + finish(); + } + }) + .positiveText(getString(R.string.confirm)) + .negativeText(getString(R.string.cancel)).build(); + + powerOffCheckbox = dialog.getCustomView().findViewById(R.id.dialog_power_off_checkbox); + powerOffCheckbox.setChecked(((App) Utils.getApp()).isCloseInstrumentAfterExit); + powerOffCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + ((App) Utils.getApp()).isCloseInstrumentAfterExit = isChecked; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(Utils.getApp()); + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean("isCloseInstrumentAfterExit", ((App) Utils.getApp()).isCloseInstrumentAfterExit); + editor.apply(); + } + }); + dialog.show(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { +// if (drawerLeft != null && drawerLeft.isDrawerOpen()) { +// drawerLeft.closeDrawer(); +// return true; +// } + + if (mViewPager != null) { + Fragment viewPagerFragment = getViewPagerFragment(this, mViewPager.getId(), mViewPager.getCurrentItem()); + if (viewPagerFragment instanceof InterfaceUtil.ICustomGroup) { + if (((InterfaceUtil.ICustomGroup) viewPagerFragment).isEditModel()) { + ((InterfaceUtil.ICustomGroup) viewPagerFragment).cancelEditModel(); + return true; + } + } + } + ExitApp(); + return true; + } + return super.onKeyDown(keyCode, event); + } + + public static Fragment getViewPagerFragment(AppCompatActivity activity, int viewId, int index) { + String tag = "android:switcher:" + viewId + ":" + index; + return activity.getSupportFragmentManager().findFragmentByTag(tag); + } + + @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); + super.onSaveInstanceState(outState); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_activity_main, menu); + menu.findItem(R.id.menu_activity_main_bluetooth).setIcon( + new IconicsDrawable(Utils.getApp()).icon(MaterialDesignIconic.Icon.gmi_bluetooth).color(Color.WHITE).sizeDp(20)); + menu.findItem(R.id.menu_activity_main_bound_device_activate).setTitle(R.string.bound_device_activate); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + case R.id.menu_activity_main_bluetooth: + mainActivityUtils.requestBluetoothPermission(); + break; + case R.id.menu_activity_main_bound_device_activate: + showActivateType(); + break; + case R.id.menu_activity_main_settings: + Intent intent4 = new Intent(Utils.getApp(), SettingsActivity.class); + startActivityForResult(intent4, 331); + break; + } + return super.onOptionsItemSelected(item); + } + + /** + * 选择激活方式 + */ + private void showActivateType() { +// if (AppChannel.customChannel == AppChannel.CUSTOM_CONTROL_PUBLIC) { +// 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)); +// } +// } else { +// startActivity(new Intent(MainActivity.this, RegisterActivity.class)); +// } + startActivity(new Intent(MainActivity.this, RegisterActivity.class)); + } + + @Override + public void onResume() { + super.onResume(); + //如果是从其他Activity返回到MainActivity时,不显示广告,如果是从后台切换出来,检查并显示广告; + //一定放到super.onResume前,否则TopActivity始终是MainActivity,因为App的onActivityResumed在super.onResume内执行 + + //按照设置选项,保持屏幕常亮,放在onResume而不放在onCreate里是因为,用户更改设置后返回主页就要开始常亮了 + boolean isWakeLock = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("key_is_wake_lock", false); + if (isWakeLock) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } else { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + + SdkUtils.tick(); + EventBus.getDefault().post(new CountDownEvent()); + } + + @Override + public void onPause() { + super.onPause(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + + TtsManager.getInstance().stopTts(); + VipManager.getInstance().destroy(); + + SoundPoolUtil.getInstance().onDestroy(); + ((App) Utils.getApp()).isBluetoothReconnect = false; + TotalStation.getInstance().stopAll(); + Device.getInstance().requestDisconnect(); + for (String serviceName : ServiceUtils.getAllRunningServices()) { + ServiceUtils.stopService(serviceName); + } + ActivityUtils.finishAllActivities(); + + GlobalFlowCenter.Companion.getInstance().onMainActivityDestroy(); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(SwitchPageEvent event) { + int type = event.getType(); + try { + int index = 1; + if (type == SwitchPageEvent.TYPE_SWITCH_TO_MEASURE_PAGE_AND_DATA) { + mViewPager.setCurrentItem(index); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(OpenShortUrlEvent event) { + if (event.getShortUrl() != null) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", event.getShortUrl()); +// startActivity(intent); + AgentWebActivity.navigation2(MainActivity.this, event.getShortUrl()); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(CountDownEvent event) { + if (cutDownProgressBar != null) { + cutDownProgressBar.setVisibility(View.VISIBLE); + if (!SdkUtils.isRegCodeValidate() && SdkUtils.isVipValidate()) { + int maxProgress = (int) (SdkUtils.availableTimeMax() / 60 / 1000L); + cutDownProgressBar.setMax(maxProgress); + int progress = Math.max((int) (SdkUtils.availableTime() / 60 / 1000L), 0);//可用时间可能小于0 + cutDownProgressBar.setProgress(progress); + if (progress < 60) { + cutDownProgressBar.setPrefix(getString(R.string.remaining_offline_time) + progress + getString(R.string.minute) + " "); + } else { + cutDownProgressBar.setPrefix(getString(R.string.remaining_offline_time) + progress / 60 + getString(R.string.hour) + progress % 60 + getString(R.string.minute) + " "); + } + if (event.isNeedRefresh()) { + VipManager.getInstance().controlSdkRefresh(this, ((App) Utils.getApp()).registerCodeV2, null); + } + if (progress == 240 || progress == 180 || progress == 120 || progress == 60 || (progress > 0 && progress < 60 && progress % 10 == 0)) { + new AlertDialog.Builder(this) + .setTitle(R.string.warning) + .setMessage(getString(R.string.remaining_offline_time) + progress + getString(R.string.minute) + "," + getString(R.string.the_network_reboot_software_can_reset_the_remaining_time_offline)) + .setPositiveButton(R.string.i_know, null) + .show(); + } + if (progress > 240) {//离线时间大于4小时,主题色显示 + cutDownProgressBar.setProgressTextColor(ColorUtil.getColorPrimary(this)); + cutDownProgressBar.setReachedBarColor(ColorUtil.getColorPrimary(this)); + cutDownProgressBar.setUnreachedBarColor(ColorUtil.getColorPrimary(this)); + } else if (progress > 120) {//离线时间2-5小时间显示橙色警告 + cutDownProgressBar.setProgressTextColor(ContextCompat.getColor(this, R.color.md_orange_800)); + cutDownProgressBar.setReachedBarColor(ContextCompat.getColor(this, R.color.md_orange_800)); + cutDownProgressBar.setUnreachedBarColor(ContextCompat.getColor(this, R.color.md_orange_800)); + } else {//离线时间小于2小时红色警告 + cutDownProgressBar.setProgressTextColor(Color.RED); + cutDownProgressBar.setReachedBarColor(Color.RED); + cutDownProgressBar.setUnreachedBarColor(Color.RED); + } + Log.d("cutdownProgressBar", "setProgress" + progress); + } else { + cutDownProgressBar.setVisibility(View.GONE); + } + } + } + + @Override + public void onDeviceConnectLost() { + mainActivityUtils.onDeviceConnectLost(); + } + + @Override + public void onDeviceConnectFailed() { + mainActivityUtils.onDeviceConnectFailed(); + } + + @Override + public void onDeviceConnectSucceed() { + mainActivityUtils.onDeviceConnectSucceed(); + } + + @Override + public void onDeviceConnectNeedOpenBT() { + } + + @Override + public void onDeviceRequestConnect() { + mainActivityUtils.onRequestConnect(); + } + + @Override + public void onDeviceRequestDisconnect() { + + } + + @Override + public void onDeviceRequestSetupChat() { + + } + + @Override + public void onRemindConnectDevice() { + mainActivityUtils.showRemindConnectDeviceDialog(); + } + + private class MyPagerAdapter extends FragmentPagerAdapter { + public MyPagerAdapter(@NonNull FragmentManager fm) { + super(fm); + } + + public MyPagerAdapter(@NonNull FragmentManager fm, int behavior) { + super(fm, behavior); + } + + @NonNull + @Override + public Fragment getItem(int position) { + return mFragments.get(position); + } + + @Override + public int getCount() { + return mFragments.size(); + } + } + + private void restartApplication() { + android.os.Process.killProcess(android.os.Process.myPid()); + } + + private boolean isThemeDark() { + return SettingValueUtil.isThemeDark(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java new file mode 100644 index 0000000..01e45ef --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java @@ -0,0 +1,464 @@ +package com.bingce.controlnetwork.activity; + +import android.Manifest; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +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; +import androidx.core.app.ActivityCompat; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleEventObserver; +import androidx.lifecycle.LifecycleOwner; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.AppChannel; +import com.bingce.BaseApp; +import com.bingce.controlnetwork.R; +import com.bingce.device.Device; +import com.bingce.device.enums.ConnectTypeEnum; +import com.bingce.device.enums.DeviceTypeEnum; +import com.bingce.device.service.comm.ble.BleService; +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.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; +import com.bingce.utils.AppCompatActivityProviderUtils; +import com.bingce.utils.IProvider; +import com.bingce.utils.RomUtil; +import com.bingce.utils.SoundPoolUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.Util; +import com.bingce.utils.ValidateUtil; +import com.hjq.permissions.OnPermissionCallback; +import com.hjq.permissions.OnPermissionPageCallback; +import com.hjq.permissions.Permission; +import com.hjq.permissions.XXPermissions; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.List; + +import blankj.utilcode.util.ActivityUtils; +import blankj.utilcode.util.ServiceUtils; +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; + +public class MainActivityUtils extends AppCompatActivityProviderUtils { + private BCProgressDialog deviceConnectingProgressDialog; + + public MainActivityUtils(AppCompatActivity activity, IProvider activityIProvider) { + super(activityIProvider); + activity.getLifecycle().addObserver(new LifecycleEventObserver() { + @Override + public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { + switch (event) { + case ON_CREATE: + EventBus.getDefault().register(MainActivityUtils.this); + SoundPoolUtil.getInstance().initHintSing(activity, SoundPoolUtil.TEST, R.raw.savedone); + break; + case ON_DESTROY: + EventBus.getDefault().unregister(MainActivityUtils.this); + SoundPoolUtil.getInstance().onDestroy(); + break; + } + } + }); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(RtkSpeechEvent event) { + if (!StringUtils.isEmpty(event.getText())) TtsManager.getInstance().speak(event.getText()); + } + + /** + * 连接设备成功后,启动相关服务,因为Ntrip与SN无关,可以在此执行,与SN相关的服务在RtkReceivedSerialNumberEvent事件后执行 + */ + public void onDeviceConnectSucceed() { + if (deviceConnectingProgressDialog != null && deviceConnectingProgressDialog.isShowing()) { + deviceConnectingProgressDialog.dismiss(); + } + + 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)); + if (mLocationManager != null) { + List providers = mLocationManager.getProviders(true); + if (providers.contains(LocationManager.GPS_PROVIDER)) { + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + if (location != null) { + ((BaseApp) Utils.getApp()).lastPhoneLocation = location.getLatitude() + "," + location.getLongitude(); + Util.putPreference("lastPhoneLocation", ((BaseApp) Utils.getApp()).lastPhoneLocation); + } + } + } + } + } + + + public void onDeviceConnectFailed() { + if (deviceConnectingProgressDialog != null && deviceConnectingProgressDialog.isShowing()) { + deviceConnectingProgressDialog.dismiss(); + ToastUtils.showShort(R.string.device_connect_failed); + } + } + + public void onDeviceConnectLost() { + ToastUtils.showShort(R.string.device_connect_lost); + } + + public void onRequestConnect() { + if (deviceConnectingProgressDialog == null || !deviceConnectingProgressDialog.isShowing()) { + deviceConnectingProgressDialog = new BCProgressDialog.Builder(ActivityUtils.getTopActivity()).title(R.string.connect_device).build(); + deviceConnectingProgressDialog.show(); + } + } + + /** + * 连接蓝牙先请求打开定位权限 + */ + public void requestBluetoothPermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.BLUETOOTH_CONNECT)) {//S及以后不需要位置权限 + checkConnectLast(); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {//S及以后不需要位置权限,此时只需请求connect权限 + if (XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.BLUETOOTH_CONNECT)) { + checkConnectLast(); + } else { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.location_permission) + .content(R.string.bluetooth_need_location_permission) + .canceledOnTouchOutside(false) + .positiveText(R.string.to_allow) + .negativeText(R.string.refuse) + .onPositive((dialog, which) -> { + XXPermissions.with(ActivityUtils.getTopActivity()) + .permission(Permission.BLUETOOTH_CONNECT) + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + checkConnectLast(); + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + ToastUtils.showLong(R.string.bluetooth_connect_need_permission); + XXPermissions.startPermissionActivity(ActivityUtils.getTopActivity(), permissions, new OnPermissionPageCallback() { + @Override + public void onGranted() { + requestBluetoothPermission(); + } + + @Override + public void onDenied() { + ToastUtils.showLong(R.string.bluetooth_connect_need_permission); + } + }); + } else { + requestBluetoothPermission(); + } + } + }); + }) + .onNegative((dialog, which) -> { + + }).show(); + } + } else {//S以下,需要请求两个权限,位置和Connect权限 + if (XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.ACCESS_FINE_LOCATION, Permission.BLUETOOTH_CONNECT)) { + checkConnectLast(); + } else { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.location_permission) + .content(R.string.bluetooth_need_location_permission) + .canceledOnTouchOutside(false) + .positiveText(R.string.to_allow) + .negativeText(R.string.refuse) + .onPositive((dialog, which) -> { + XXPermissions.with(ActivityUtils.getTopActivity()) + .permission(Permission.ACCESS_FINE_LOCATION, Permission.BLUETOOTH_CONNECT) + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + if (all) { + checkConnectLast(); + } else { + requestBluetoothPermission(); + } + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + ToastUtils.showLong(R.string.bluetooth_connection_requires_positioning_permission_please_turn_it_on_manually); + XXPermissions.startPermissionActivity(ActivityUtils.getTopActivity(), permissions, new OnPermissionPageCallback() { + @Override + public void onGranted() { + requestBluetoothPermission(); + } + + @Override + public void onDenied() { + ToastUtils.showLong(R.string.bluetooth_connect_need_permission); + } + }); + } else { + requestBluetoothPermission(); + } + } + }); + }) + .onNegative((dialog, which) -> { + + }).show(); + } + } + } + + /** + * 检查权限 + */ + public void requestPhonePermission() { + if (!XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.READ_PHONE_STATE)) { + long lastReadPhoneStateDeniedTime = Util.getLongPreference("lastReadPhoneStateDeniedTime", 0L); + if (System.currentTimeMillis() - lastReadPhoneStateDeniedTime > 48 * 60 * 60 * 1000L) {//每48小时提示一次 + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.mobile_phone_permissions) + .content(R.string.verify_imei_imsi_code_to_prevent_account_theft) + .canceledOnTouchOutside(false) + .positiveText(R.string.to_allow) + .negativeText(R.string.refuse) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + XXPermissions.with(ActivityUtils.getTopActivity()) + .permission(Permission.READ_PHONE_STATE) + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + ToastUtils.showShort(R.string.manually_enable_the_phone_state_permission_to_bind_hardware_devices); + } + Util.putPreference("lastReadPhoneStateDeniedTime", System.currentTimeMillis()); + } + }); + } + }) + .onNegative(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + Util.putPreference("lastReadPhoneStateDeniedTime", System.currentTimeMillis()); + } + }).show(); + } + } + } + + public void showRemindConnectDeviceDialog() { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.hint) + .content(R.string.no_instrument_connected) + .positiveText(R.string.connect) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + checkConnectLast(); + } + }) + .negativeText(R.string.cancel) + .show(); + } + + + public void checkConnectLast() { + if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_SPP) { + if (!ServiceUtils.isServiceRunning(BTService.class.getName())) { + ServiceUtils.startService(BTService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_BLE) { + if (!ServiceUtils.isServiceRunning(BleService.class.getName())) { + ServiceUtils.startService(BleService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_QXBT) { + //千寻RTK需要GnssServer连接蓝牙 + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_HOTSPOT) { + 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(TsSocketService.class.getName())) { + ServiceUtils.startService(TsSocketService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_PHONE_LOCATION) { + if (!ServiceUtils.isServiceRunning(NativePositioningService.class.getName())) { + ServiceUtils.startService(NativePositioningService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_EMULATOR) { + if (!ServiceUtils.isServiceRunning(EmulatorService.class.getName())) { + ServiceUtils.startService(EmulatorService.class); + } + } + if (!Device.getInstance().isDeviceConnected()) { + if (!"".equals(Device.getInstance().deviceBlueName)) { + String instrumentInfo = ActivityUtils.getTopActivity().getString(R.string.instrument_name) + ":" + Device.getInstance().deviceBlueName + "\n" + ActivityUtils.getTopActivity().getString(R.string.instrument_type_name) + ":" + Device.getInstance().deviceBrand; + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.quick_connect) + .content(instrumentInfo) + .positiveText(R.string.connect) + .negativeText(R.string.config) + .neutralText(R.string.switch_instrument) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_HOTSPOT) { + startHotspotComm(); + } else { + Device.getInstance().requestConnect(); + ToastUtils.showShort(R.string.connecting_please_wait); + } + } + }).onNegative(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + 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); + } + intent.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent); + } + }).onNeutral(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + chooseInstrumentType(); + } + }).show(); + } else { + chooseInstrumentType(); + } + } else { + if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_PHONE_LOCATION) { + ToastUtils.showShort(R.string.native_rtk_is_running); + } else { + 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); + } + intent.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent); + } + } + } + + private void chooseInstrumentType() { + 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(); + } + + + /** + * 开启wifi通信 + */ + private void startHotspotComm() { + if (!ValidateUtil.isIPAddress(TsConfig.getInstance().getIp())) { + ToastUtils.showShort(R.string.please_input_correct_ip); + return; + } + if (TsConfig.getInstance().getPort() < 1024 || TsConfig.getInstance().getPort() > 65535) { + ToastUtils.showShort(R.string.please_input_correct_port); + return; + } + if (DeviceUtil.isWifiApOpen()) { + ServiceUtils.stopService(EmulatorService.class); + ServiceUtils.stopService(LocationService.class); + ServiceUtils.stopService(NativePositioningService.class); + ServiceUtils.stopService(BTService.class); + ServiceUtils.stopService(BleService.class); + ServiceUtils.startService(TsSocketService.class); + ThreadPoolUtil.execute(new Runnable() { + @Override + public void run() { + Device.getInstance().requestConnect(); + } + }, 200); + } else { + ToastUtils.showShort(R.string.please_open_hotspot_first); + //打开网络共享与热点设置页面 + if (RomUtil.isOppo() || RomUtil.isLenove() || RomUtil.isGionee()) { + //OPPO系统系统特殊,会让在Manifest.xml声明Settings$TetherSettingsActivity,现在让用户自己找热点界面,并开启 + ToastUtils.showShort(R.string.find_tether_setting_and_open); + ActivityUtils.getTopActivity().startActivity(new Intent(Settings.ACTION_SETTINGS)); + } else { + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.Settings$TetherSettingsActivity"); + intent.setComponent(comp); + ActivityUtils.getTopActivity().startActivity(intent); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/NotificationActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/NotificationActivity.java new file mode 100644 index 0000000..9e087ee --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/NotificationActivity.java @@ -0,0 +1,250 @@ +package com.bingce.controlnetwork.activity; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.webkit.WebResourceRequest; +import android.webkit.WebView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.utils.ClipboardUtils; +import com.bingce.utils.StringUtil; +import com.just.agentweb.AgentWeb; +import com.just.agentweb.DefaultWebClient; +import com.just.agentweb.WebChromeClient; +import com.just.agentweb.WebViewClient; + +import org.polaric.colorful.ColorfulActivity; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; + +/** + * Created by cenxiaozhong on 2017/5/26. + *

+ * source code https://github.com/Justson/AgentWeb + */ + +public class NotificationActivity extends ColorfulActivity { + protected AgentWeb mAgentWeb; + private LinearLayout mLinearLayout; + private Toolbar mToolbar; + private TextView mTitleTextView; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_agentweb_base); + + mLinearLayout = this.findViewById(R.id.container); + mToolbar = this.findViewById(R.id.toolbar); + mToolbar.setTitle(""); + mToolbar.setNavigationIcon(R.mipmap.icon_close_x); + mTitleTextView = this.findViewById(R.id.toolbar_title); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mToolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + mAgentWeb = AgentWeb.with(this) + .setAgentWebParent(mLinearLayout, new LinearLayout.LayoutParams(-1, -1)) + .useDefaultIndicator() + .setWebChromeClient(mWebChromeClient) + .setWebViewClient(mWebViewClient) + .setMainFrameErrorView(R.layout.agentweb_error_page, -1) + .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK) + .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.ASK)//打开其他应用时,弹窗咨询用户是否前往其他应用 + .interceptUnkownUrl() //拦截找不到相关页面的Scheme + .createAgentWeb() + .ready() + .go(getUrl()); + + mAgentWeb.getWebCreator().getWebView().getSettings().setSupportZoom(true); + mAgentWeb.getWebCreator().getWebView().getSettings().setBuiltInZoomControls(true); + mAgentWeb.getWebCreator().getWebView().getSettings().setDisplayZoomControls(false); + mAgentWeb.getWebCreator().getWebView().getSettings().setUseWideViewPort(true); + + LeanCloudConfigLoader.findInBackground("notificationUrl", instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", "notificationUrl") +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (isFinishing()) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String url = /*avObjects.get(0).getString("value")*/instance.value; + mAgentWeb.getUrlLoader().loadUrl(url); + } else { + mAgentWeb.getUrlLoader().loadUrl("https://www.bingce.com"); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + } + + private final WebViewClient mWebViewClient = new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + return super.shouldOverrideUrlLoading(view, request); + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + //do you work + Log.i("Info", "AgentWebActivity onPageStarted"); + } + }; + private final WebChromeClient mWebChromeClient = new WebChromeClient() { + @Override + public void onReceivedTitle(WebView view, String title) { + super.onReceivedTitle(view, title); + if (mTitleTextView != null) { + mTitleTextView.setText(title); + } + } + }; + + public String getUrl() { + return null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_activity_agentweb, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // true表示AgentWeb处理了该事件 + if (!mAgentWeb.back()) { + finish(); + } + break; + case R.id.refresh: + if (mAgentWeb != null) { + mAgentWeb.getUrlLoader().reload(); // 刷新 + } + break; + case R.id.copy_url: + if (mAgentWeb != null) { + ClipboardUtils.copyText(mAgentWeb.getWebCreator().getWebView().getUrl()); + ToastUtils.showShort(R.string.copy_success); + } + break; + case R.id.clean: + toCleanWebCache(); + break; + case R.id.open_with_broswer: + if (mAgentWeb != null) { + openBrowser(mAgentWeb.getWebCreator().getWebView().getUrl()); + } + break; + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (mAgentWeb.handleKeyEvent(keyCode, event)) { + return true; + } + return super.onKeyDown(keyCode, event); + } + + @Override + protected void onPause() { + mAgentWeb.getWebLifeCycle().onPause(); + super.onPause(); + + } + + @Override + protected void onResume() { + mAgentWeb.getWebLifeCycle().onResume(); + super.onResume(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + Log.i("Info", "onResult:" + requestCode + " onResult:" + resultCode); + super.onActivityResult(requestCode, resultCode, data); + } + + + @Override + protected void onDestroy() { + super.onDestroy(); + //mAgentWeb.destroy(); + mAgentWeb.getWebLifeCycle().onDestroy(); + } + + /** + * 清除 WebView 缓存 + */ + private void toCleanWebCache() { + if (this.mAgentWeb != null) { + //清理所有跟WebView相关的缓存 ,数据库, 历史记录 等。 + this.mAgentWeb.clearWebCache(); + ToastUtils.showShort("已清理缓存"); + //清空所有 AgentWeb 硬盘缓存,包括 WebView 的缓存 , AgentWeb 下载的图片 ,视频 ,apk 等文件。 +// AgentWebConfig.clearDiskCache(this.getContext()); + } + } + + /** + * 打开浏览器 + * + * @param targetUrl 外部浏览器打开的地址 + */ + private void openBrowser(String targetUrl) { + if (TextUtils.isEmpty(targetUrl) || targetUrl.startsWith("file://")) { + ToastUtils.showShort(targetUrl + " 该链接无法使用浏览器打开。"); + return; + } + Intent intent = new Intent(); + intent.setAction("android.intent.action.VIEW"); + Uri mUri = Uri.parse(targetUrl); + intent.setData(mUri); + startActivity(intent); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/SettingsActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/SettingsActivity.java new file mode 100644 index 0000000..25c0ea2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/SettingsActivity.java @@ -0,0 +1,195 @@ +package com.bingce.controlnetwork.activity; + + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.WindowManager; + +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; +import androidx.preference.ListPreference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreferenceCompat; + +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorConstants; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.controller.KeyEventAction; + +import org.polaric.colorful.Colorful; +import org.polaric.colorful.ColorfulActivity; + +/** + * 设置页面 + */ +public class SettingsActivity extends ColorfulActivity { + private Toolbar mToolbar; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(Bundle savedInstanceState) { + App app = App.getApp(); + if (app.isLandscape()) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + } else { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_settings); + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (savedInstanceState == null) { + getSupportFragmentManager().beginTransaction() + .add(R.id.activity_settings_content, createSettingFragment()) + .commit(); + } + } + + private Fragment createSettingFragment() { + return new SettingsFragment(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + public static class SettingsFragment extends PreferenceFragmentCompat { + private SwitchPreferenceCompat nightModePrefs; + private SwitchPreferenceCompat isOpenAtr; +// private ColorPickerPreference themePrimaryColor, themeAccentColor; + + private ListPreference volume_plus_prefs, volume_minus_prefs; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.prefs, rootKey); + + nightModePrefs = findPreference("key_is_night_mode"); +// themePrimaryColor = findPreference("key_theme_primary_color"); +// themeAccentColor = findPreference("key_theme_accent_color"); + + + volume_plus_prefs = findPreference("key_volume_plus_function"); + volume_minus_prefs = findPreference("key_volume_minus_function"); + + volume_plus_prefs.setSummary(volume_plus_prefs.getEntry()); + volume_minus_prefs.setSummary(volume_minus_prefs.getEntry()); + + isOpenAtr = findPreference("key_is_open_atr"); + + nightModePrefs.setOnPreferenceChangeListener((preference, newValue) -> { + Colorful.config(App.getApp()).dark((Boolean) newValue).apply(); + new AlertDialog.Builder(getActivity()) + .setMessage(R.string.please_restart_to_apply_new_theme) + .setPositiveButton(R.string.confirm, null) + .setOnDismissListener(dialogInterface -> { + Intent intent = new Intent(); + intent.putExtra("isThemeChanged", true); + getActivity().setResult(RESULT_OK, intent); + getActivity().finish(); + }).show(); + return true; + }); + + +// //主色 +// themePrimaryColor.setOnPreferenceChangeListener((preference, newValue) -> { +// new AlertDialog.Builder(getActivity()) +// .setMessage(R.string.please_restart_to_apply_new_theme) +// .setPositiveButton(R.string.confirm, null) +// .setOnDismissListener(new DialogInterface.OnDismissListener() { +// @Override +// public void onDismiss(DialogInterface dialogInterface) { +// Intent intent = new Intent(); +// intent.putExtra("isThemeChanged", true); +// getActivity().setResult(RESULT_OK, intent); +// getActivity().finish(); +// } +// }).show(); +// return true; +// }); +// //配色 +// themeAccentColor.setOnPreferenceChangeListener((preference, newValue) -> { +// new AlertDialog.Builder(getActivity()) +// .setMessage(R.string.please_restart_to_apply_new_theme) +// .setPositiveButton(R.string.confirm, null) +// .setOnDismissListener(new DialogInterface.OnDismissListener() { +// @Override +// public void onDismiss(DialogInterface dialogInterface) { +// Intent intent = new Intent(); +// intent.putExtra("isThemeChanged", true); +// getActivity().setResult(RESULT_OK, intent); +// getActivity().finish(); +// } +// }).show(); +// return true; +// }); + + volume_plus_prefs.setOnPreferenceChangeListener((preference, newValue) -> { + setKeyEvent(newValue, volume_plus_prefs); + return true; + }); + volume_minus_prefs.setOnPreferenceChangeListener((preference, newValue) -> { + setKeyEvent(newValue, volume_minus_prefs); + return true; + }); + + isOpenAtr.setOnPreferenceChangeListener((preference, newValue) -> { + ISurveyorConstants.isOpenAtr = (boolean) newValue; + return true; + }); + +// if (AppChannel.customChannel != AppChannel.CUSTOM_CONTROL_PUBLIC) { +// //主配色隐藏 +// themePrimaryColor.setVisible(false); +// themeAccentColor.setVisible(false); +// } + + } + + private void setKeyEvent(Object newValue, ListPreference volume_minus_prefs) { + switch (String.valueOf(newValue)) { + case KeyEventAction.NONE: + volume_minus_prefs.setSummary("无"); + break; + case KeyEventAction.CAL: + volume_minus_prefs.setSummary("计算"); + break; + case KeyEventAction.SURVEY: + volume_minus_prefs.setSummary("观测"); + break; + case KeyEventAction.RECORD: + volume_minus_prefs.setSummary("记录"); + break; + case KeyEventAction.LAST: + volume_minus_prefs.setSummary("上一点"); + break; + case KeyEventAction.NEXT: + volume_minus_prefs.setSummary("下一点"); + break; + case KeyEventAction.SURVEY_NO_SEND: + volume_minus_prefs.setSummary("观测后不发送结果"); + break; + case KeyEventAction.SURVEY_AND_RECORD: + volume_minus_prefs.setSummary("观测并记录"); + break; + } + } + + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/SplashActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/SplashActivity.java new file mode 100644 index 0000000..e667518 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/SplashActivity.java @@ -0,0 +1,235 @@ +package com.bingce.controlnetwork.activity; + +import static com.king.app.updater.util.AppUtils.getPackageInfo; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.databinding.ActivitySplashBinding; +import com.bingce.file.FileOperator; +import com.bingce.path.PathManager; +import com.bingce.utils.NetworkUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.zip.ZipUtil; + +import org.polaric.colorful.ColorfulActivity; + +import java.io.File; +import java.io.FileNotFoundException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import cn.leancloud.LCFile; +import cn.leancloud.LCObject; +import cn.leancloud.LCQuery; + +/** + * 欢迎页 + */ +@SuppressLint("CustomSplashScreen") +public class SplashActivity extends ColorfulActivity { + + private boolean isEnterMainActivity = false; + + private static final String CODE_NO_UPLOAD = "0"; + private static final String CODE_UPLOAD_COMPARE_SMALL_WITH_FIRST = "1"; + private static final String CODE_UPLOAD_COMPARE_SMALL_WITHOUT_FIRST = "2"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); +// getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + ActivitySplashBinding binding = ActivitySplashBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + startCopyDbFileToCache(); + } + + private void startCopyDbFileToCache() { + ThreadPoolUtil.execute(() -> { + try { + File copyFolder = PathManager.appDocumentFolder(); + File[] files = copyFolder.listFiles(); + List collectFileList = null; + if (files != null) { + collectFileList = new ArrayList<>(Arrays.asList(files)); + } + + if (collectFileList != null && !collectFileList.isEmpty()) { + + SimpleDateFormat simple = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()); + String fileName = "控制测量电子手薄数据备份_" + "_" + getVersionName() + "_" + simple.format(new Date()); + File zipTartFile = new File(copyFolder, fileName + ".zip"); + boolean zip = ZipUtil.zip(zipTartFile, collectFileList); + + if (zip) { + //获取上一次备份的文件 + File lastFile = getBeforeTargetFile(targetFolder()); + //备份文件 + File targetFile = new File(targetFolder().getAbsolutePath(), fileName); + boolean isCopySuccess = FileOperator.copyFile(zipTartFile.getAbsolutePath(), targetFile.getAbsolutePath()); + //无论备份成功或者失败都删除压缩后的文件 + zipTartFile.delete(); + if (isCopySuccess) { + //delete多余文件 + deleteRemainCacheFile(lastFile, targetFile); + + if (NetworkUtil.isNetworkAvailable(SplashActivity.this)) { + String code = queryUploadConfig(); + checkUpload(code, lastFile, targetFile); + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + goMainActivity(); + } + }); + } + + /** + * 文件个数大于3就删除 + * + * @param lastFile + * @param targetFile + */ + private void deleteRemainCacheFile(File lastFile, File targetFile) { + File file = targetFolder(); + if (file != null) { + File[] files = file.listFiles(); + if (files != null && files.length > 3) { + File deleteFile = null; + for (File fileEach : files) { + String eachName = fileEach.getName(); + if (eachName.equals(getFileName(lastFile)) || eachName.equals(getFileName(targetFile))) { + continue; + } + if (deleteFile != null && deleteFile.lastModified() > fileEach.lastModified()) { + deleteFile = fileEach; + } + if (deleteFile == null) { + deleteFile = fileEach; + } + } + if (deleteFile != null) { + deleteFile.delete(); + } + } + } + } + + private String getFileName(File file) { + if (file != null) { + return file.getName(); + } + return null; + } + + /** + * 控制测量电子手薄是否自动上传可能错误的数据库 + * 0.不上传 + * 1.比上次小就上传上次备份数据;但是如果是首次备份,也将该备份上传 + * 2.比上次小就上传上次备份数据;如果是首次备份,不会将该备份上传 + */ + private void checkUpload(String code, File lastFile, File targetFile) throws FileNotFoundException { + if (CODE_NO_UPLOAD.equals(code)) { + //不上传 + } else if (CODE_UPLOAD_COMPARE_SMALL_WITH_FIRST.equals(code)) { + if (compareSmall(lastFile, targetFile)) { + uploadFile(lastFile); + } else if (lastFile == null) { + uploadFile(targetFile); + } + } else if (CODE_UPLOAD_COMPARE_SMALL_WITHOUT_FIRST.equals(code) && compareSmall(lastFile, targetFile)) { + uploadFile(lastFile); + } + } + + /** + * 是否比上次小 + * + * @param lastFile + * @param targetFile + * @return + */ + private boolean compareSmall(File lastFile, File targetFile) { + return lastFile != null && targetFile.length() < lastFile.length() / 2; + } + + /** + * 获取上次备份的文件 + * + * @param fileFolder + * @return + */ + private File getBeforeTargetFile(File fileFolder) { + File targetFile = null; + if (fileFolder != null) { + File[] files = fileFolder.listFiles(); + if (files != null) { + for (File eachFile : files) { + if (targetFile == null || targetFile.lastModified() < eachFile.lastModified()) { + targetFile = eachFile; + } + } + } + } + return targetFile; + } + + /** + * 上传leanCloud文件 + */ + private void uploadFile(File zipTartFile) throws FileNotFoundException { + Log.d("hwhw", "数据库备份文件上传LeanCloud"); + LCFile lcFile = LCFile.withAbsoluteLocalPath(zipTartFile.getName(), zipTartFile.getAbsolutePath()); + lcFile.save(); + } + + private void goMainActivity() { + if (!isEnterMainActivity) { + isEnterMainActivity = true; + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + + public File targetFolder() { + File cacheFolder = getCacheDir(); + File targetFolder = new File(cacheFolder, "dbBackUp"); + if (!targetFolder.exists()) { + targetFolder.mkdirs(); + } + return targetFolder; + } + + private String getVersionName() { + try { + return getPackageInfo(this).versionName; + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + + private String queryUploadConfig() { + List avObjects = new LCQuery<>("Configuration").whereEqualTo("name", "ControlAppAutoUploadErrorDatabase") + .limit(1).find(); + if (avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null) { + return avObjects.get(0).getString("value"); + } + return CODE_NO_UPLOAD; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/ViewRecentCrashActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/ViewRecentCrashActivity.java new file mode 100644 index 0000000..c36a53a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/ViewRecentCrashActivity.java @@ -0,0 +1,62 @@ +package com.bingce.controlnetwork.activity; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.MenuItem; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.util.CrashCollectUtils; +import com.bingce.utils.ThreadPoolUtil; + +import org.polaric.colorful.ColorfulActivity; + +public class ViewRecentCrashActivity extends ColorfulActivity { + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_view_recent_crash_log); + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + TextView textView = findViewById(R.id.tv_content); + if (textView != null) { + ThreadPoolUtil.execute(() -> { + CrashCollectUtils.collectCrashLogInWorkerThread((cloudTable, appLabelKey, fileNameKey, contentKey, uuidKey, crashContent) -> { + if (!TextUtils.isEmpty(crashContent)) { + runOnUiThread(() -> textView.setText(crashContent)); + } + }); + }); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + break; + } + return super.onOptionsItemSelected(item); + } + + public static void start(Context context) { + Intent intent = new Intent(context, ViewRecentCrashActivity.class); + context.startActivity(intent); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/AbstractBackupExportActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/AbstractBackupExportActivity.java new file mode 100644 index 0000000..b819cd2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/AbstractBackupExportActivity.java @@ -0,0 +1,282 @@ +package com.bingce.controlnetwork.activity.backup; + +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; + +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.appcompat.widget.Toolbar; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase; +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityExportLayoutBinding; +import com.bingce.file.DownloadFileWriter; +import com.bingce.file.FileOperator; +import com.bingce.path.PathManager; +import com.bingce.utils.AsynchronousHelper; +import com.bingce.utils.FileUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.zip.ZipUtil; +import com.github.ybq.android.spinkit.SpinKitView; + +import org.polaric.colorful.ColorfulActivity; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.ToastUtils; + +public abstract class AbstractBackupExportActivity extends ColorfulActivity implements AsynchronousHelper.IDelegate { + + public static final String BACKUP_NAME = "控制测量电子手薄数据"; + public static final String FOLDER_DADA_DATABASES = "dada_databases"; + public static final String FOLDER_DATA_FILE_PROJECT = "data_file_project"; + public static final String FOLDER_ANDROID = "android"; + public static final String FOLDER_SDCARD = "sdcard"; + public static final String BACKUP_TXT = "backup.txt"; + + + private final AsynchronousHelper asynchronousHelper = new AsynchronousHelper(this); + private File zipFile = null; + + protected abstract String tipsString(); + + private ActivityExportLayoutBinding binding; + + @Override + final protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityExportLayoutBinding.inflate(getLayoutInflater()); +// getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + binding.shareButton.setOnClickListener(v -> doCollect()); + binding.progressText.setText(tipsString()); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + protected abstract String applicationId(); + + protected abstract String zipFileName(String dateString, String projectName); + + private void doCollect() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { //如果是>=Q版本,不需要申请权限 + doExport(); + } else { //如果是低于Q版本,则先申请存储权限 + //检测是否有写权限 + requestStoragePermission(); + } + } + + public void requestStoragePermission() { + CheckStorageUtil.check(this, this::doExport); + } + + private void doExport() { + if (zipFile == null) { + startCollect(); + } else { + FileOperator.shareFile(this, zipFile, /*BuildConfig.APPLICATION_ID*/applicationId()); + } + } + + private void startCollect() { +// + binding.progressText.setText(""); + asynchronousHelper.start(); + binding.shareButton.setEnabled(false); + binding.spinKit.setVisibility(View.VISIBLE); + binding.tvCompleted.setVisibility(View.GONE); + ThreadPoolUtil.execute(() -> { + + File packageFile = getFilesDir().getParentFile(); + + //1 + File database1 = new File(packageFile, "databases"); + File[] files = database1.listFiles(); + List dataDatabasesFiles = getDbListFiles(files); + //2 + File file2 = new File(PathManager.appFolder(), "NOPROJECT"); + File[] files2 = file2.listFiles(); + List dataProjectFiles = getDbListFiles(files2); + //3 + File file3 = PathManager.appDocumentFolder(); + File[] files3 = file3.listFiles(); + List androidFiles = getDbListFiles(files3); + //4 + File file4 = new File(FileUtil.getSDPath(), "控制测量电子手薄"); + File[] files4 = file4.listFiles(); + List sdFiles = getDbListFiles(files4); + + File fileTargetP = new File(PathManager.appCacheFolder(this), BACKUP_NAME); + FileUtil.deleteDir(fileTargetP); + + File fileTxt = new File(fileTargetP, "backup.txt"); + FileUtil.writeString(FOLDER_ANDROID, fileTxt); + + copyFile(dataDatabasesFiles, new File(fileTargetP, FOLDER_DADA_DATABASES)); + copyFile(dataProjectFiles, new File(fileTargetP, FOLDER_DATA_FILE_PROJECT)); + copyFile(androidFiles, new File(fileTargetP, FOLDER_ANDROID)); + copyFile(sdFiles, new File(fileTargetP, FOLDER_SDCARD)); + + SimpleDateFormat simple = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()); + String fileName = zipFileName(simple.format(new Date()), ""); + File target = new File(fileTargetP, fileName + ".zip"); + List list = new ArrayList<>(); + list.add(fileTargetP); + boolean zip = ZipUtil.zip(target, list); + Log.d("hwhw", "备份是否ok" + zip); + if (zip) { + zipFile = target; + } + asynchronousHelper.completed(); + }); + } + + @Override + public void onBackPressed() { + if (asynchronousHelper.isWorking()) { + ToastUtils.showShort("数据收集中,请稍候。"); + return; + } + super.onBackPressed(); + } + + public static void start(Context context, Class clz) { + start(context, clz, null); + } + + private static final String KEY_PROJECT_NAME = "key_project_name"; + + public static void start(Context context, Class clz, String projectName) { + Intent intent = new Intent(context, clz); + if (!StringUtils.isEmpty(projectName)) { + intent.putExtra(KEY_PROJECT_NAME, projectName); + } + context.startActivity(intent); + } + + @Override + public void onUpdateProgress(String msg) { + String string = binding.progressText.getText().toString(); + binding.progressText.setText(string + "\n" + msg); + binding.scrollView.post(() -> binding.scrollView.fullScroll(View.FOCUS_DOWN)); + } + + @Override + public void onCompleted() { + if (zipFile == null) { + return; + } + if (isDestroyed() || isFinishing()) { + return; + } + Button shareButton = findViewById(R.id.share_button); + if (shareButton != null) { + shareButton.setEnabled(true); + shareButton.setText(R.string.share); + } + SpinKitView spinKitView = findViewById(R.id.spin_kit); + if (spinKitView != null) { + spinKitView.setVisibility(View.INVISIBLE); + } + AppCompatTextView completeTv = findViewById(R.id.tv_completed); + if (completeTv != null) { + completeTv.setText(Tools.getString(R.string.collection_completed)); + completeTv.setVisibility(View.VISIBLE); + } + //将文件存储到download中 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + String tipsString; + if (DownloadFileWriter.writeHigherQ(this, zipFile)) { + tipsString = "数据备份完毕,存储在根目录「Download\\" + zipFile.getName() + "」压缩包中."; + } else { + tipsString = "数据备份完毕,请存放到安全位置以便日后恢复."; + } + //弾框提示 + showDialog(this, applicationId(), tipsString, zipFile); + } else { + File resultFile = DownloadFileWriter.writeLowerQ(zipFile); + String tipsString; + if (resultFile != null) { + tipsString = "数据备份完毕,存储在「" + resultFile.getAbsolutePath() + "」压缩包中."; + } else { + tipsString = "数据备份完毕,请存放到安全位置以便日后恢复."; + } + showDialog(this, applicationId(), tipsString, zipFile); + } + } + + private static void showDialog(Context context, String applicationId, String title, File zipFile) { + //弾框提示 + new MaterialDialog.Builder(context).title(Tools.getString(R.string.notice)) + .content(title) + .positiveText(R.string.send_to) + .negativeText(R.string.cancel) + .cancelable(false) + .onPositive((dialog, which) -> FileOperator.shareFile(context, zipFile, /*BuildConfig.APPLICATION_ID*/applicationId)) + .show(); + } + + + /** + * 筛选出需要的db文件 + * + * @param files + * @return + */ + @WorkerThread + private List getDbListFiles(File[] files) { + List fileList = new ArrayList<>(); + if (files != null) { + for (File file : files) { + if (file.getName().contains(SurveyorDataBase.DB_NAME)) { + fileList.add(file); + } + } + } + return fileList; + } + + @WorkerThread + private void copyFile(List files, File targetFile) { + if (files != null && !files.isEmpty()) { + if (!targetFile.exists()) { + targetFile.mkdirs(); + } + + for (File file : files) { + FileOperator.copyFile(file.getAbsolutePath(), targetFile.getAbsolutePath() + File.separator + file.getName()); + } + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/BackupExportActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/BackupExportActivity.java new file mode 100644 index 0000000..7164bca --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/BackupExportActivity.java @@ -0,0 +1,30 @@ +package com.bingce.controlnetwork.activity.backup; + +import blankj.utilcode.util.StringUtils; + +import com.bingce.controlnetwork.BuildConfig; +import com.bingce.controlnetwork.R; + +public class BackupExportActivity extends AbstractBackupExportActivity { + @Override + protected String tipsString() { + return getString(R.string.back_up_data_tips); + } + + @Override + protected String applicationId() { + return BuildConfig.APPLICATION_ID; + } + + @Override + protected String zipFileName(String dateString, String projectName) { + StringBuilder stringBuilder = new StringBuilder(BACKUP_NAME); + if (!StringUtils.isEmpty(projectName)) { + stringBuilder.append("[") + .append(projectName) + .append("]"); + } + stringBuilder.append(dateString); + return stringBuilder.toString(); + } +} 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 new file mode 100644 index 0000000..84ca3a7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/BackupImportHelper.java @@ -0,0 +1,45 @@ +package com.bingce.controlnetwork.activity.backup.launch; + +import android.app.Activity; +import android.content.Context; +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; + private final ActivityResultLauncher importLauncher; + + public BackupImportHelper(AppCompatActivity activity) { + importLauncher = activity.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (callback == null) { + return; + } + boolean success = result != null && Activity.RESULT_OK == result.getResultCode(); + callback.onImported(success); + }); + } + + 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); + importLauncher.launch(intent); + } + + public interface ICallback { + void onImported(boolean success); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/MigrationFolder2PrivateRoomActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/MigrationFolder2PrivateRoomActivity.java new file mode 100644 index 0000000..23f81a0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/MigrationFolder2PrivateRoomActivity.java @@ -0,0 +1,141 @@ +package com.bingce.controlnetwork.activity.backup.launch; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityMigration2PrivateFolderLayoutBinding; +import com.bingce.file.DownloadFilePicker; +import com.bingce.utils.AsynchronousHelper; +import com.bingce.utils.IntentUtil; + +import org.polaric.colorful.ColorfulActivity; + +public class MigrationFolder2PrivateRoomActivity extends ColorfulActivity implements AsynchronousHelper.IDelegate { + private final DownloadFilePicker downloadFilePicker = new DownloadFilePicker(this); + private final AsynchronousHelper migrationHelper = new AsynchronousHelper(this); + private ActivityMigration2PrivateFolderLayoutBinding binding; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); +// getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + binding = ActivityMigration2PrivateFolderLayoutBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + + //从备份文件导入 + binding.backupFromZip.setOnClickListener(v -> { + binding.layout2.setVisibility(View.INVISIBLE); + ZipMigrationUtils.importFromZip(MigrationFolder2PrivateRoomActivity.this, + "控制测量电子手薄数据+日期", + migrationHelper, + downloadFilePicker, + new ZipMigrationUtils.IMigrationListener() { + @Override + public void onMigrationStart() { + showWorkLayout(); + } + + @Override + public void onMigrationInterrupt() { + back2Layout2(); + } + }); + }); + boolean fromMainActivity = IntentUtil.boolExtra(this, KEY_FROM_MAIN_ACTIVITY); + if (fromMainActivity) { + binding.enterAppDirect.setVisibility(View.GONE); + } else { + binding.enterAppDirect.setOnClickListener(v -> { + binding.backupFromZip.setEnabled(false); + binding.enterAppDirect.setEnabled(false); + enterApp(MigrationFolder2PrivateRoomActivity.this); + }); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + + private void showWorkLayout() { + binding.workLayout.setVisibility(View.VISIBLE); + binding.back.setEnabled(false); + binding.back.setOnClickListener(v -> back2Layout2()); + binding.next.setEnabled(false); + binding.next.setOnClickListener(v -> { + binding.back.setEnabled(false); + binding.next.setEnabled(false); + enterApp(MigrationFolder2PrivateRoomActivity.this); + }); + binding.tvCompleted.setVisibility(View.INVISIBLE); + binding.spinKit.setVisibility(View.VISIBLE); + binding.progressText.setText(""); + } + + private void back2Layout2() { + binding.workLayout.setVisibility(View.INVISIBLE); + binding.layout2.setVisibility(View.VISIBLE); + } + + private static void enterApp(Activity activity) { + boolean fromMainActivity = IntentUtil.boolExtra(activity, KEY_FROM_MAIN_ACTIVITY); + if (fromMainActivity) { + activity.setResult(Activity.RESULT_OK); + activity.finish(); + } + } + + @Override + public void onBackPressed() { + boolean fromMainActivity = IntentUtil.boolExtra(this, KEY_FROM_MAIN_ACTIVITY); + if (fromMainActivity) { + super.onBackPressed(); + } + } + + @Override + public void onUpdateProgress(String msg) { + binding.progressText.setText(binding.progressText.getText() + "\n" + msg); + binding.scrollView.post(() -> binding.scrollView.fullScroll(View.FOCUS_DOWN)); + } + + @Override + public void onCompleted() { + binding.next.setEnabled(true); + binding.back.setEnabled(true); + binding.tvCompleted.setVisibility(View.VISIBLE); + binding.spinKit.setVisibility(View.INVISIBLE); + } + + private static final String KEY_FROM_MAIN_ACTIVITY = "from_main_activity"; + + public static void start(Context context) { + context.startActivity(intent(context, false)); + } + + public static Intent intent(Context context, boolean fromMainActivity) { + Intent intent = new Intent(context, MigrationFolder2PrivateRoomActivity.class); + intent.putExtra(KEY_FROM_MAIN_ACTIVITY, fromMainActivity); + return intent; + } + +} 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 new file mode 100644 index 0000000..2dbf664 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/ZipMigrationUtils.java @@ -0,0 +1,124 @@ +package com.bingce.controlnetwork.activity.backup.launch; + +import android.content.Context; +import android.text.TextUtils; + +import com.bingce.controlnetwork.activity.backup.AbstractBackupExportActivity; +import com.bingce.file.DownloadFilePicker; +import com.bingce.file.FileOperator; +import com.bingce.path.PathManager; +import com.bingce.utils.AsynchronousHelper; +import com.bingce.utils.FileUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.zip.ZipHelper; + +import java.io.File; + +import blankj.utilcode.util.FileUtils; +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.activity.backup.AbstractBackupExportActivity; + +public class ZipMigrationUtils { + + public static void importFromZip(Context context, String backupName, AsynchronousHelper asynchronousHelper, DownloadFilePicker downloadFilePicker, IMigrationListener listener) { + downloadFilePicker.doPick(duplicate -> { + String errorString = "请选择正确的备份数据,位于根目录Download文件夹内,名称样式为「" + backupName + ".zip」"; + if (duplicate == null || !duplicate.exists()) { + ToastUtils.showShort(errorString); + if (listener != null) { + listener.onMigrationInterrupt(); + } + return; + } + if (!duplicate.getName().endsWith(".zip")) { + ToastUtils.showShort(errorString); + if (listener != null) { + listener.onMigrationInterrupt(); + } + return; + } + asynchronousHelper.start(); + if (listener != null) { + listener.onMigrationStart(); + } + //切换线路执行数据解压 + ThreadPoolUtil.execute(() -> { + //解压缩 + + File unzipFolder = new File(context.getExternalCacheDir(), duplicate.getName().replace(".zip", "")); + File[] prjFolders = unzipBackupFile(duplicate, unzipFolder, errorString); + if (prjFolders == null) { + return; + } + + for (File file : prjFolders) { + File[] folder = file.listFiles(); + String backUpType = null; + for (File fileBackup : folder) { + if (!fileBackup.isDirectory()) { + if (fileBackup.getName().equals(AbstractBackupExportActivity.BACKUP_TXT)) { + FileUtil.ReadFileResult readFileResult = FileUtil.readStringFrom(fileBackup); + if (readFileResult.success) { + backUpType = readFileResult.string; + } + break; + } + } + } + + for (File fileBackup : folder) { + if (fileBackup.isDirectory()) { + String name = fileBackup.getName(); + if (TextUtils.equals(name, backUpType)) { + File[] dbFileList = fileBackup.listFiles(); + for (File dbFile : dbFileList) { + FileOperator.copy(dbFile, PathManager.appDocumentFolder()); + } + } + } + } + } + + + //完成数据导入 + asynchronousHelper.completed(); + }); + }); + } + + private static File[] unzipBackupFile(File duplicate, File unzipFolder, String errorString) { + if (!unzipFolder.exists()) { + if (!unzipFolder.mkdirs()) { + ToastUtils.showShort("解压备份文件失败"); + return null; + } + } else { + //先删除,再创建 + try { + FileUtils.delete(unzipFolder); + } catch (Exception e) { + e.printStackTrace(); + ToastUtils.showShort("解压备份文件失败"); + return null; + } + if (!unzipFolder.mkdirs()) { + ToastUtils.showShort("解压备份文件失败"); + return null; + } + } + if (!ZipHelper.unZipFile(unzipFolder.getAbsolutePath(), duplicate.getAbsolutePath())) { + ToastUtils.showShort(errorString); + return null; + } + //解析文件内容 + return unzipFolder.listFiles(); + } + + + public interface IMigrationListener { + void onMigrationStart(); + + void onMigrationInterrupt(); + } +} 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 new file mode 100644 index 0000000..c118304 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainer.java @@ -0,0 +1,92 @@ +package com.bingce.controlnetwork.activity.fragmentcontainer; + +import android.os.Bundle; + +import androidx.fragment.app.Fragment; + +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.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; +import com.bingce.controlnetwork.fragment.station.heighttraverse.CreateStationForHeightTraverseFragment; +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 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 { + Fragment newInstance(Bundle args); + } + + private static final Map factory = new HashMap<>(); + + static { + factory.put(ProjectDetailHeightTraverseFragment.TAG, ProjectDetailHeightTraverseFragment::newInstance); + factory.put(ProjectDetailTriangleFragment.TAG, ProjectDetailTriangleFragment::newInstance); + factory.put(ProjectToleranceSettingFragment.TAG, ProjectToleranceSettingFragment::newInstance); + factory.put(ToleranceSelectFragment.TAG, ToleranceSelectFragment::newInstance); + factory.put(PointListFragment.TAG, PointListFragment::newInstance); + factory.put(SingleStationDetailAndEditFragment.TAG, SingleStationDetailAndEditFragment::newInstance); + factory.put(DefaultStationSetupFragment.TAG, DefaultStationSetupFragment::newInstance); + factory.put(PickPointFragment.TAG, PickPointFragment::newInstance); + factory.put(StationSurveyorFragment.TAG, StationSurveyorFragment::newInstance); + factory.put(StationSettingsFragment.TAG, StationSettingsFragment::newInstance); + factory.put(ToleranceManageFragment.TAG, ToleranceManageFragment::newInstance); + factory.put(ToleranceDetailFragment.TAG, ToleranceDetailFragment::newInstance); + factory.put(SelectExportSurveyorRecordFragment.TAG, SelectExportSurveyorRecordFragment::newInstance); + factory.put(SelectExportSurveyorRecordWireFileFragment.TAG, SelectExportSurveyorRecordWireFileFragment::newInstance); + factory.put(SurveyorSettingsFragment.TAG, SurveyorSettingsFragment::newInstance); + factory.put(LineStationSingleSetupFragment.TAG, LineStationSingleSetupFragment::newInstance); + factory.put(LineStationAttachedSetupFragment.TAG, LineStationAttachedSetupFragment::newInstance); + factory.put(LineStationCloseSetupFragment.TAG, LineStationCloseSetupFragment::newInstance); + factory.put(LineStationRandomSetupFragment.TAG, LineStationRandomSetupFragment::newInstance); + factory.put(LineStationWellSetupFragment.TAG, LineStationWellSetupFragment::newInstance); + factory.put(LineStationWellDoubleGroundSetupFragment.TAG, LineStationWellDoubleGroundSetupFragment::newInstance); + factory.put(LineStationWellDoubleUnderGroundSetupFragment.TAG, LineStationWellDoubleUnderGroundSetupFragment::newInstance); + factory.put(PrismManageFragment.TAG, PrismManageFragment::newInstance); + factory.put(MeasureFragment.TAG, MeasureFragment::newInstance); + factory.put(CreateStationForHeightTraverseFragment.TAG, CreateStationForHeightTraverseFragment::newInstance); + 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) { + IBuilder builder = factory.get(tag); + if (builder == null) { + return null; + } + return builder.newInstance(bundle); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainerActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainerActivity.java new file mode 100644 index 0000000..7196267 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainerActivity.java @@ -0,0 +1,138 @@ +package com.bingce.controlnetwork.activity.fragmentcontainer; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.MenuItem; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.List; + +import com.bingce.controlnetwork.R; + +public class FragmentContainerActivity extends ColorfulActivity { + private static final String KEY_TAG = "_TAG_"; + private static final String KEY_TITLE_STRING_ID = "__title_res"; + private static final String KEY_TITLE_STRING = "__title__"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //设置view + setContentView(R.layout.activity_fragment_container_layout); + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + //设置fragment + if (savedInstanceState == null) { + Intent intent = getIntent(); + if (intent == null) { + finish(); + return; + } + int title = intent.getIntExtra(KEY_TITLE_STRING_ID, -1); + if (title > 0) { + setTitle(title); + } else { + String string = intent.getStringExtra(KEY_TITLE_STRING); + setTitle(string); + } + String tag = intent.getStringExtra(KEY_TAG); + Bundle bundle = intent.getExtras(); + Fragment fragment = FragmentContainer.getFragment(tag, bundle); + if (fragment == null) { + finish(); + return; + } + getSupportFragmentManager().beginTransaction() + .replace(R.id.container, fragment) + .commitAllowingStateLoss(); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + if (!isCancelBack()) { + finish(); + } + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onBackPressed() { + if (isCancelBack()) { + return; + } + super.onBackPressed(); + } + + private boolean isCancelBack() { + List fragmentList = getSupportFragmentManager() + .getFragments(); + boolean cancelBack = false; + for (Fragment fragment : fragmentList) { + if (fragment instanceof IOnBackFilter) { + if (((IOnBackFilter) fragment).cancelBack()) { + cancelBack = true; + break; + } + } + } + return cancelBack; + } + + public static void start(Context context, String tag, int titleRes, Bundle bundle) { + Intent intent = new Intent(context, FragmentContainerActivity.class); + if (bundle != null) { + intent.putExtras(bundle); + } + intent.putExtra(KEY_TAG, tag); + intent.putExtra(KEY_TITLE_STRING_ID, titleRes); + context.startActivity(intent); + } + + public static void start(Context context, String tag, String title, Bundle bundle) { + Intent intent = new Intent(context, FragmentContainerActivity.class); + if (bundle != null) { + intent.putExtras(bundle); + } + intent.putExtra(KEY_TAG, tag); + intent.putExtra(KEY_TITLE_STRING, title); + context.startActivity(intent); + } + + public static Intent startIntent(Context context, + String tag, + int titleRes, + Bundle bundle) { + Intent intent = new Intent(context, FragmentContainerActivity.class); + if (bundle != null) { + intent.putExtras(bundle); + } + intent.putExtra(KEY_TAG, tag); + intent.putExtra(KEY_TITLE_STRING_ID, titleRes); + return intent; + } + + public static Intent startIntent(Context context, + String tag, + String title, + Bundle bundle) { + Intent intent = new Intent(context, FragmentContainerActivity.class); + if (bundle != null) { + intent.putExtras(bundle); + } + intent.putExtra(KEY_TAG, tag); + intent.putExtra(KEY_TITLE_STRING, title); + return intent; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentItem.java b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentItem.java new file mode 100644 index 0000000..824ec89 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentItem.java @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.activity.fragmentcontainer; + +public class FragmentItem { + public final int titleId; + public final String tag; + + public FragmentItem(int title, String tag) { + titleId = title; + this.tag = tag; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/IOnBackFilter.java b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/IOnBackFilter.java new file mode 100644 index 0000000..36dca2d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/IOnBackFilter.java @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.activity.fragmentcontainer; + +public interface IOnBackFilter { + boolean cancelBack(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/EditNicknamePasswordActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/EditNicknamePasswordActivity.java new file mode 100644 index 0000000..0e87722 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/EditNicknamePasswordActivity.java @@ -0,0 +1,143 @@ +package com.bingce.controlnetwork.activity.user; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.InputType; +import android.text.TextWatcher; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import org.polaric.colorful.ColorfulActivity; + +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCUser; + +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityEditUserNicknamePasswordBinding; + +public class EditNicknamePasswordActivity extends ColorfulActivity { + + private ActivityEditUserNicknamePasswordBinding binding; + private boolean isShowPassword01, isShowPassword02; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityEditUserNicknamePasswordBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + //隐藏显示按钮01(输入密码) + binding.llPassword01.setOnClickListener(v -> { + if (isShowPassword01) { + // 明文显示密码 + binding.etPassword01.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); + binding.ivPassword01.setImageDrawable(getDrawable(R.drawable.icon_password_open_eyes)); + } else { + // 隐藏密码 + binding.etPassword01.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + binding.ivPassword01.setImageDrawable(getDrawable(R.drawable.icon_password_close_eyes)); + } + isShowPassword01 = !isShowPassword01; + }); + + //隐藏显示按钮02(确认密码) + binding.llPassword02.setOnClickListener(v -> { + if (isShowPassword02) { + // 明文显示密码 + binding.etPassword02.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); + binding.ivPassword02.setImageDrawable(getDrawable(R.drawable.icon_password_open_eyes)); + } else { + // 隐藏密码 + binding.etPassword02.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + binding.ivPassword02.setImageDrawable(getDrawable(R.drawable.icon_password_close_eyes)); + } + isShowPassword02 = !isShowPassword02; + }); + + binding.etPassword01.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + checkPw(); + } + }); + binding.etPassword02.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + checkPw(); + } + }); + + //完成 + binding.tvComplete.setOnClickListener(v -> { + String nickName = binding.etNickName.getText().toString(); + String password = binding.etPassword01.getText().toString(); + if (LCUser.getCurrentUser() != null) { + LCUser.getCurrentUser().setPassword(password); + LCUser.getCurrentUser().put("nickname", nickName); + LCUser.getCurrentUser().saveInBackground().subscribe(); + ((App) Utils.getApp()).isUserStatusChanged = true; + } + finish(); + }); + } + + private void checkPw() { + String nickName = binding.etNickName.getText().toString(); + String pw1 = binding.etPassword01.getText().toString(); + String pw2 = binding.etPassword02.getText().toString(); + boolean isEmptyNickName = StringUtils.isEmpty(nickName); + boolean isEmptyPw01 = StringUtils.isEmpty(pw1); + boolean isEmptyPw02 = StringUtils.isEmpty(pw2); + if (!isEmptyNickName && !isEmptyPw01 && !isEmptyPw02 && pw1.equals(pw2)) { + binding.tvComplete.setEnabled(true); + binding.tvComplete.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvComplete.setEnabled(false); + binding.tvComplete.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + public static void start(Context context) { + context.startActivity(new Intent(context, EditNicknamePasswordActivity.class)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/InputEmailActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/InputEmailActivity.java new file mode 100644 index 0000000..8c678b9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/InputEmailActivity.java @@ -0,0 +1,107 @@ +package com.bingce.controlnetwork.activity.user; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.utils.IntentUtil; +import com.bingce.utils.ValidateUtil; + +import org.polaric.colorful.ColorfulActivity; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityInputEmailBinding; + +public class InputEmailActivity extends ColorfulActivity { + public static final String KEY_EMAIL = "email"; + public static final String KEY_TODO = "todo"; + private ActivityInputEmailBinding binding; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityInputEmailBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + getSupportActionBar().setTitle(R.string.email_verify); + if (getEmail() != null) { + binding.etEmail.setText(getEmail()); + binding.etEmail.setEnabled(false); + if (checkEmail()) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + } + + binding.etEmail.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + if (checkEmail()) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + } + }); + + ActivityResultLauncher verifyCodeLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + Intent data = result.getData(); + if (data != null) { + setResult(RESULT_OK, data); + finish(); + } + }); + //下一步 + binding.tvNextPage.setOnClickListener(v -> { + String email = binding.etEmail.getText().toString(); + VerifyEmailCodeActivity.start(this, email, getToDo(), verifyCodeLauncher); + }); + } + + private boolean checkEmail() { + return ValidateUtil.isEmail(binding.etEmail.getText().toString()); + } + + public static void start(Context context, String email, int todo, ActivityResultLauncher launcher) { + Intent intent = new Intent(context, InputEmailActivity.class); + intent.putExtra(KEY_EMAIL, email); + intent.putExtra(KEY_TODO, todo); + launcher.launch(intent); + } + + + private String getEmail() { + return IntentUtil.stringExtra(getIntent(), KEY_EMAIL); + } + + + private int getToDo() { + return IntentUtil.intExtra(getIntent(), KEY_TODO); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/InputPhoneNumberActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/InputPhoneNumberActivity.java new file mode 100644 index 0000000..a92c5de --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/InputPhoneNumberActivity.java @@ -0,0 +1,93 @@ +package com.bingce.controlnetwork.activity.user; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.utils.IntentUtil; + +import org.polaric.colorful.ColorfulActivity; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityInputPhoneNumberBinding; + +public class InputPhoneNumberActivity extends ColorfulActivity { + public static final String KEY_PHONE = "phone_number"; + public static final String KEY_EMAIL = "email"; + public static final String KEY_UNION_ID = "unionid"; + public static final String KEY_TODO = "todo"; + private ActivityInputPhoneNumberBinding binding; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityInputPhoneNumberBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + getSupportActionBar().setTitle(R.string.mobile_phone_verify); + + binding.ccp.registerCarrierNumberEditText(binding.etPhoneNumber); + binding.ccp.setPhoneNumberValidityChangeListener(isValidNumber -> { + if (isValidNumber) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + }); + if (getPhoneNumber() != null) { + binding.etPhoneNumber.setText(getPhoneNumber().replaceFirst("\\+86", "")); + binding.etPhoneNumber.setEnabled(false); + binding.ccp.setCcpClickable(false); + } + + ActivityResultLauncher verifyCodeLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + Intent data = result.getData(); + if (data != null && data.hasExtra("isMail") && data.hasExtra("phoneNumberOrEmail")) { + setResult(RESULT_OK, data); + finish(); + } + }); + //下一步 + binding.tvNextPage.setOnClickListener(v -> { + String phoneNumber = binding.ccp.getFullNumberWithPlus(); + VerifySMSCodeActivity.start(this, phoneNumber, getEmail(), getUnionId(), getToDo(), verifyCodeLauncher); + }); + } + + public static void start(Context context, String phoneNumber, String email, String unionid, int todo, ActivityResultLauncher launcher) { + Intent intent = new Intent(context, InputPhoneNumberActivity.class); + intent.putExtra(KEY_PHONE, phoneNumber); + intent.putExtra(KEY_EMAIL, email); + intent.putExtra(KEY_UNION_ID, unionid); + intent.putExtra(KEY_TODO, todo); + launcher.launch(intent); + } + + private String getPhoneNumber() { + return IntentUtil.stringExtra(getIntent(), KEY_PHONE); + } + + + private String getEmail() { + return IntentUtil.stringExtra(getIntent(), KEY_EMAIL); + } + + private String getUnionId() { + return IntentUtil.stringExtra(getIntent(), KEY_UNION_ID); + } + + private int getToDo() { + return IntentUtil.intExtra(getIntent(), KEY_TODO); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/LoginActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/LoginActivity.java new file mode 100644 index 0000000..f771c4b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/LoginActivity.java @@ -0,0 +1,579 @@ +package com.bingce.controlnetwork.activity.user; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.Nullable; + +import com.bingce.AppChannel; +import com.bingce.BaseApp; +import com.bingce.activity.UserCloudFunction; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityLoginBinding; +import com.bingce.controlnetwork.wxapi.MD5; +import com.bingce.data.sync.utils.LeanCloudUserLoginStateUtils; +import com.bingce.event.WxRespCodeEvent; +import com.bingce.ui.TabEntity; +import com.bingce.utils.ActivityUtils; +import com.bingce.utils.ValidateUtil; +import com.bingce.utils.VipManager; +import com.flyco.tablayout.listener.CustomTabEntity; +import com.flyco.tablayout.listener.OnTabSelectListener; +import com.hbb20.CountryCodePicker; +import com.tencent.mm.opensdk.modelmsg.SendAuth; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.polaric.colorful.ColorfulActivity; + +import java.util.ArrayList; +import java.util.Random; + +import alibaba.fastjson.JSON; +import alibaba.fastjson.JSONObject; +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCException; +import cn.leancloud.LCUser; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +public class LoginActivity extends ColorfulActivity { + + private ActivityLoginBinding binding; + private final String[] mTitles = new String[]{Utils.getApp().getString(R.string.phone_number), Utils.getApp().getString(R.string.e_mail)}; + private final ArrayList tabEntityList = new ArrayList<>(); + private boolean isLoginPassword = true, isLoginByEmail = false; + + private ProgressDialog progressDialog; + private String wxRespCode; + private String finishTo; + private ActivityResultLauncher signUpOrLoginLauncher; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityLoginBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + setSupportActionBar(binding.getRoot().findViewById(R.id.toolbar)); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + EventBus.getDefault().register(this); + + finishTo = getIntent().getStringExtra("finishTo"); + + //绑定Tab数据 + for (String mTitle : mTitles) { + tabEntityList.add(new TabEntity(mTitle)); + } + binding.tabLoginMode.setTabData(tabEntityList); + + //切换手机号、邮箱 + binding.tabLoginMode.setOnTabSelectListener(new OnTabSelectListener() { + @Override + public void onTabSelect(int position) { + isLoginByEmail = position != 0; + onSelectTabPhoneEmail(); + } + + @Override + public void onTabReselect(int position) { + + } + }); + + //切换验证码、密码 + binding.tvLoginPasswordCode.setOnClickListener(v -> { + onClickBtnPassword(); + }); + + binding.ccp.registerCarrierNumberEditText(binding.etPhoneNumber); + binding.ccp.setPhoneNumberValidityChangeListener(new CountryCodePicker.PhoneNumberValidityChangeListener() { + @Override + public void onValidityChanged(boolean isValidNumber) { + if (isValidNumber) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + } + }); + //下一步 + binding.tvNextPage.setOnClickListener(v -> { + if (checkValid()) { + if (isLoginByEmail) { + String email = binding.etEmail.getText().toString().trim(); + if (!isLoginPassword) {//验证码登录 + VerifyEmailCodeActivity.start(this, email, VerifyEmailCodeActivity.TO_SIGNUP_OR_LOGIN_BY_EMAIL, signUpOrLoginLauncher); + } else { + String password = binding.etPassword.getText().toString(); + loginByEmailPassword(email, password); + } + } else { + String phoneNumber = binding.ccp.getFullNumberWithPlus(); + if (!isLoginPassword) {//验证码登录 + VerifySMSCodeActivity.start(this, phoneNumber, null, null, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_PHONE_NUMBER, signUpOrLoginLauncher); + } else { + String password = binding.etPassword.getText().toString(); + if (phoneNumber.startsWith("+86")) { + phoneNumber = phoneNumber.replaceFirst("\\+86", ""); + } + loginByPhonePassword(phoneNumber, password); + } + } + } + }); + + binding.ivWechatLogin.setOnClickListener(v -> { + wxLogin(); + }); + signUpOrLoginLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result.getResultCode() == Activity.RESULT_OK) { + Intent data = result.getData(); + if (data != null) { + if (data.hasExtra("sessionToken") && data.hasExtra("newUser")) { + String sessionToken = data.getStringExtra("sessionToken"); + boolean newUser = data.getBooleanExtra("newUser", false); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + LCUser.becomeWithSessionTokenInBackground(sessionToken, true).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCUser lcUser) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + loginSuccess(); + if (newUser) { + EditNicknamePasswordActivity.start(LoginActivity.this); + } + } + + @Override + public void onError(Throwable e) { + ToastUtils.showShort(getString(R.string.error_code) + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + } + } + }); + + binding.etPassword.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + checkValid(); + } + }); + } + + public static void start(Context context) { + context.startActivity(new Intent(context, LoginActivity.class)); + } + + public void onSelectTabPhoneEmail() { + binding.etPassword.setText(""); + if (!isLoginByEmail) {//手机号登录 + binding.llPhoneNumber.setVisibility(View.VISIBLE); + binding.llEmail.setVisibility(View.GONE); + binding.etPhoneNumber.setText(""); + if (isLoginPassword) { + binding.signUpHint.setText(R.string.if_you_do_not_have_an_account_you_can_use_a_verification_code_to_sign_up_and_log_in); + } else { + binding.signUpHint.setText(R.string.unsigned_up_mobile_phone_number_will_be_automatically_signed_up_and_logged_in); + } + } else {//邮箱登录 + binding.llPhoneNumber.setVisibility(View.GONE); + binding.llEmail.setVisibility(View.VISIBLE); + binding.etEmail.setText(""); + if (isLoginPassword) { + binding.signUpHint.setText(R.string.if_you_do_not_have_an_account_you_can_use_a_verification_code_to_sign_up_and_log_in); + } else { + binding.signUpHint.setText(R.string.unsigned_up_email_will_be_automatically_signed_up_and_logged_in); + } + } + checkValid(); + } + + public void onClickBtnPassword() { + isLoginPassword = !isLoginPassword; + if (!isLoginPassword) {//现在改为验证码登录 + binding.llPassword.setVisibility(View.GONE); + binding.tvNextPage.setText(R.string.next); + binding.tvLoginPasswordCode.setText(R.string.log_in_with_password); + if (!isLoginByEmail) {//手机号登录 + binding.signUpHint.setText(R.string.unsigned_up_mobile_phone_number_will_be_automatically_signed_up_and_logged_in); + } else { + binding.signUpHint.setText(R.string.unsigned_up_email_will_be_automatically_signed_up_and_logged_in); + } + } else {//现在改为密码登录 + binding.llPassword.setVisibility(View.VISIBLE); + binding.tvNextPage.setText(R.string.log_in); + binding.tvLoginPasswordCode.setText(R.string.log_in_using_verify_code); + binding.signUpHint.setText(R.string.if_you_do_not_have_an_account_you_can_use_a_verification_code_to_sign_up_and_log_in); + } + checkValid(); + } + + public boolean checkValid() { + if (!isLoginPassword) {//现在改为验证码登录 + if (isLoginByEmail) { + if (ValidateUtil.isEmail(binding.etEmail.getText().toString().trim())) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + return false; + } + } else { + if (binding.ccp.isValidFullNumber()) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + return false; + } + } + } else {//现在改为密码登录 + if (isLoginByEmail) { + if (ValidateUtil.isEmail(binding.etEmail.getText().toString().trim()) && !StringUtils.isEmpty(binding.etPassword.getText().toString().trim())) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + return false; + } + } else { + if (binding.ccp.isValidFullNumber() && !StringUtils.isEmpty(binding.etPassword.getText().toString().trim())) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + return false; + } + } + } + return true; + } + + public void wxLogin() { + wxRespCode = null; + if (Utils.getApp() instanceof BaseApp) { + if (((BaseApp) Utils.getApp()).getWxApi() != null) { + if (!((BaseApp) Utils.getApp()).getWxApi().isWXAppInstalled()) { + ToastUtils.showShort(R.string.you_do_not_have_the_wechat_app_installed); + } else { + final SendAuth.Req req = new SendAuth.Req(); + //应用授权作用域,如获取用户个人信息则填写 snsapi_userinfo + req.scope = "snsapi_userinfo"; + //用于保持请求和回调的状态,授权请求后原样带回给第三方。 + //该参数可用于防止 csrf 攻击(跨站请求伪造攻击), + //建议第三方带上该参数,可设置为简单的随机数加 session 进行校验 + req.state = getNonceStr(); + if (((BaseApp) Utils.getApp()).getWxApi() != null) + ((BaseApp) Utils.getApp()).getWxApi().sendReq(req); + } + } + } + } + + //生成随机号,防重发 + private String getNonceStr() { + Random random = new Random(); + return MD5.getMessageDigest((System.currentTimeMillis() + String.valueOf(random.nextInt(10000))).getBytes()); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(WxRespCodeEvent event) { + wxRespCode = event.getCode(); + } + + @Override + protected void onResume() { + super.onResume(); + if (wxRespCode != null) { + loginByWxCode(); + wxRespCode = null; + } + } + + private void loginByWxCode() { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + UserCloudFunction.loginByWxCode(wxRespCode, AppChannel.customChannel, new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + LCUser.becomeWithSessionTokenInBackground(sessionToken, true).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCUser lcUser) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + if (newUser) { + EditNicknamePasswordActivity.start(LoginActivity.this); + } + ((App) Utils.getApp()).isUserStatusChanged = true; + setResult(RESULT_OK); + finish(); + } + + @Override + public void onError(Throwable e) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + if (code == 321 || code == 322) {//321此微信未绑定用户,请使用其他方式登录,322缺少手机号或手机号未验证 + JSONObject jsonObject = JSON.parseObject(resp); + if (jsonObject.containsKey("data")) { + JSONObject data = jsonObject.getJSONObject("data"); + if (data.containsKey("unionid")) { + String unionid = data.getString("unionid"); + InputPhoneNumberActivity.start(LoginActivity.this, null, null, unionid, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_WEIXIN_BIND_PHONE, signUpOrLoginLauncher); + } + } + } else { + ToastUtils.showLong(msg); + } + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + } + + + private void loginSuccess() { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + VipManager.getInstance().controlSdkRefresh(LoginActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + if (!StringUtils.isEmpty(finishTo)) { + try { + Intent intent = new Intent(LoginActivity.this, Class.forName(finishTo)); + intent.putExtras(getIntent()); + startActivity(intent); + } catch (ClassNotFoundException | NullPointerException ex) { + ex.printStackTrace(); + } + } + + ((App) Utils.getApp()).isUserStatusChanged = true; + LeanCloudUserLoginStateUtils.onLogIn(); + setResult(RESULT_OK); + finish(); + } + + @Override + public void onRefreshFailed(int errorCode) { + ToastUtils.showShort(getString(R.string.error_code) + ":" + errorCode); + } + }); + } + + private void loginByEmailPassword(String email, String password) { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + UserCloudFunction.loginByEmailPassword(email, password, AppChannel.customChannel, new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + LCUser.becomeWithSessionTokenInBackground(sessionToken, true).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCUser lcUser) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + loginSuccess(); + if (newUser) { + EditNicknamePasswordActivity.start(LoginActivity.this); + } + } + + @Override + public void onError(Throwable e) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + if (code == 303) {//缺少手机号或未验证 + InputPhoneNumberActivity.start(LoginActivity.this, null, email, null, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_EMAIL_BIND_PHONE, signUpOrLoginLauncher); + } else if (code == 304) {//邮箱未验证 + InputEmailActivity.start(LoginActivity.this, email, VerifyEmailCodeActivity.TO_SIGNUP_OR_LOGIN_BY_EMAIL, signUpOrLoginLauncher); + } else { + if (msg != null) + ToastUtils.showLong(msg); + } + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + } + + private void loginByPhonePassword(String phoneNumber, String password) { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + UserCloudFunction.loginByPhonePassword(phoneNumber, password, AppChannel.customChannel, new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + LCUser.becomeWithSessionTokenInBackground(sessionToken, true).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCUser lcUser) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + loginSuccess(); + if (newUser) { + EditNicknamePasswordActivity.start(LoginActivity.this); + } + } + + @Override + public void onError(Throwable e) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + if (code == 303) {//手机号未验证 + InputPhoneNumberActivity.start(LoginActivity.this, phoneNumber, null, null, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_PHONE_NUMBER, signUpOrLoginLauncher); + } else { + if (msg != null) + ToastUtils.showLong(msg); + } + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + } +} 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 new file mode 100644 index 0000000..b172ff9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/OpeningRenewalVipActivity.java @@ -0,0 +1,534 @@ +package com.bingce.controlnetwork.activity.user; + +import android.content.DialogInterface; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.net.Uri; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageView; +import android.widget.RadioGroup; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityOpeningRenewalBinding; +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.event.PayOverEvent; +import com.bingce.pay.OrderType; +import com.bingce.pay.WxPayV3; +import com.bingce.surveyor.agentweb.AgentWebActivity; +import com.bingce.utils.ActivityUtils; +import com.bingce.utils.DateUtils; +import com.bingce.utils.StringUtil; +import com.bingce.utils.Util; +import com.bingce.utils.VipManager; +import com.bumptech.glide.Glide; +import com.huawei.hms.hmsscankit.ScanUtil; +import com.huawei.hms.hmsscankit.WriterException; +import com.huawei.hms.ml.scan.HmsBuildBitmapOption; +import com.huawei.hms.ml.scan.HmsScan; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.polaric.colorful.ColorfulActivity; + +import java.util.Date; + +import blankj.utilcode.util.AppUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCUser; + +public class OpeningRenewalVipActivity extends ColorfulActivity { + private int total_fee = -1; + private ImageView qrImageView; + private int queryCount = 0; + private int oneMonthPrice = -1, threeMonthsPrice = -1, oneYearPrice = -1; + private MaterialDialog payingDialog; + private ActivityOpeningRenewalBinding binding; + private String orderType = OrderType.ORDER_TYPE_SURVEYOR_365; + private boolean hasPayResult = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityOpeningRenewalBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + setSupportActionBar(binding.getRoot().findViewById(R.id.toolbar)); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + EventBus.getDefault().register(this); + + binding.activityOpeningRenewalTvVersion.setText("V" + AppUtils.getAppVersionName()); + + if (VipManager.getInstance().expireDate != null) { + binding.activityOpeningRenewalTvExpirationDate.setText(getString(R.string.current_expiration_date) + ":" + DateUtils.toFull(VipManager.getInstance().expireDate)); + } else { + binding.activityOpeningRenewalTvExpirationDate.setText(getString(R.string.current_expiration_date) + ":无"); + } + + binding.activityOpeningRenewalRadiogroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + if (oneMonthPrice <= 0 || threeMonthsPrice <= 0 || oneYearPrice <= 0) { + ToastUtils.showShort("请先联网获取套餐价格"); + return; + } + if (checkedId == binding.activityOpeningRenewalRadiobuttonOneMonth.getId()) { + total_fee = oneMonthPrice; + orderType = OrderType.ORDER_TYPE_SURVEYOR_30; + } else if (checkedId == binding.activityOpeningRenewalRadiobuttonThreeMonths.getId()) { + total_fee = threeMonthsPrice; + orderType = OrderType.ORDER_TYPE_SURVEYOR_90; + } else if (checkedId == binding.activityOpeningRenewalRadiobuttonOneYear.getId()) { + total_fee = oneYearPrice; + orderType = OrderType.ORDER_TYPE_SURVEYOR_365; + } + if (total_fee <= 0) { + binding.activityOpeningRenewalTvTotalFee.setText("联网获取价格"); + } else { + binding.activityOpeningRenewalTvTotalFee.setText(Util.formatDouble2StringDotAuto(total_fee / 100.0) + "元"); + } + } + }); + + if (VipManager.getInstance().checkReg()) { + new AlertDialog.Builder(this) + .setTitle(R.string.hint) + .setMessage("此手机已经绑定激活,请确定是否需要购买会员,绑定激活和购买会员可以二选其一") + .setPositiveButton(R.string.i_know, null) + .show(); + } + + LeanCloudConfigLoader.findInBackground("opening_renewal_fee", instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", "opening_renewal_fee") +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (!ActivityUtils.isLiving(OpeningRenewalVipActivity.this)) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String value = /*avObjects.get(0).getString("value")*/instance.value; + String value2 = /*avObjects.get(0).getString("value2")*/instance.value2; + String[] valueArr = value.split(","); + String[] value2Arr = value2.split(","); + if (valueArr.length == 3 && value2Arr.length == 3) { + try { + oneMonthPrice = Integer.parseInt(valueArr[0]); + threeMonthsPrice = Integer.parseInt(valueArr[1]); + oneYearPrice = Integer.parseInt(valueArr[2]); + binding.activityOpeningRenewalRadiobuttonOneMonth.setText(value2Arr[0] + " " + oneMonthPrice / 100.0 + "元"); + binding.activityOpeningRenewalRadiobuttonThreeMonths.setText(value2Arr[1] + " " + threeMonthsPrice / 100.0 + "元"); + binding.activityOpeningRenewalRadiobuttonOneYear.setText(value2Arr[2] + " " + oneYearPrice / 100.0 + "元"); + if (binding.activityOpeningRenewalRadiobuttonOneMonth.isChecked()) { + total_fee = oneMonthPrice; + } else if (binding.activityOpeningRenewalRadiobuttonThreeMonths.isChecked()) { + total_fee = threeMonthsPrice; + } else if (binding.activityOpeningRenewalRadiobuttonOneYear.isChecked()) { + total_fee = oneYearPrice; + } + if (total_fee <= 0) { + binding.activityOpeningRenewalTvTotalFee.setText("联网获取价格"); + } else { + binding.activityOpeningRenewalTvTotalFee.setText(Util.formatDouble2StringDotAuto(total_fee / 100.0) + "元"); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + } else { + binding.activityOpeningRenewalTvTotalFee.setText("联网获取价格"); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + LeanCloudConfigLoader.findInBackground("opening_renewal_activity", instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", "opening_renewal_activity") +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (!ActivityUtils.isLiving(OpeningRenewalVipActivity.this)) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String activity = /*avObjects.get(0).getString("value")*/instance.value; + binding.activityOpeningRenewalTvActivity.setText(activity); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + + String adsQueryUrl = "android_opening_renewal_vip_img_ads"; + LeanCloudConfigLoader.findInBackground(adsQueryUrl, instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", adsQueryUrl) +// .limit(1) +// .findInBackground() +// .subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (!ActivityUtils.isLiving(OpeningRenewalVipActivity.this)) return; + if (/*avObjects != null && !avObjects.isEmpty()*/instance != null) { + String adsUrl = /*avObjects.get(0).getString("value")*/instance.value; + if (adsUrl != null) { + binding.activityOpeningRenewalImgAds.setVisibility(View.VISIBLE); + Glide.with(OpeningRenewalVipActivity.this).load(adsUrl).into(binding.activityOpeningRenewalImgAds); + + String actionUrl = /*avObjects.get(0).getString("value2")*/instance.value2; + if (actionUrl != null) { + binding.activityOpeningRenewalImgAds.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.setData(Uri.parse(actionUrl)); +// startActivity(intent); + AgentWebActivity.navigation2( + OpeningRenewalVipActivity.this, + Uri.parse(actionUrl)); + } + }); + } + } + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + + binding.activityOpeningRenewalBtnTaobaoLink.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "taobaoUrl"); +// startActivity(intent); + AgentWebActivity.navigation2( + OpeningRenewalVipActivity.this, + "taobaoUrl"); + } + }); + binding.activityOpeningRenewalBtnContactCustomerService.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "android_url_contact_author"); +// startActivity(intent); + AgentWebActivity.navigation2( + OpeningRenewalVipActivity.this, + "android_url_contact_author" + ); + } + }); + + binding.activityOpeningRenewalBtnWepay.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (total_fee <= 0) { + ToastUtils.showShort("请联网获取价格"); + return; + } + binding.activityOpeningRenewalRadiobuttonOneYear.setEnabled(false); + binding.activityOpeningRenewalRadiobuttonOneMonth.setEnabled(false); + binding.activityOpeningRenewalRadiobuttonThreeMonths.setEnabled(false); + showPayListDialog(); + } + }); + + binding.activityOpeningRenewalBtnOpeningRenewalVipTutorial.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "android_url_opening_renewal_tutorial"); +// startActivity(intent); + AgentWebActivity.navigation2( + OpeningRenewalVipActivity.this, + "android_url_opening_renewal_tutorial" + ); + } + }); + } + + public void showPayListDialog() { + if (LCUser.getCurrentUser() == null) { + ToastUtils.showShort("请重新登录"); + return; + } + if (LCUser.getCurrentUser().getMobilePhoneNumber() == null) { + ToastUtils.showShort("账号绑定的手机号为空,请绑定后再试"); + return; + } + int fee = total_fee <= 0 ? 50000 : total_fee; + nativeOrder(fee);//由于云引擎appid是测量员的,所以无法调用app下单,只能二维码下单 +// new MaterialDialog.Builder(this) +// .title(R.string.choose_wechat_pay_type) +// .items(new String[]{getString(R.string.wechat_direct_pay), getString(R.string.wechat_qr_pay)}) +// .itemsCallback(new MaterialDialog.ListCallback() { +// @Override +// public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) { +// switch (which) { +// case 0: +// appOrder(fee); +// break; +// case 1: +// nativeOrder(fee); +// break; +// } +// binding.activityOpeningRenewalBtnWepay.setEnabled(false); +// } +// }).show(); + } + + /** + * 二维码下单 + * + * @param fee 金额,单位分 + */ + private void nativeOrder(int fee) { + WxPayV3.getInstance().generateNativeVipOrder(this, + LCUser.getCurrentUser().getSessionToken(), + "导线助手会员", + fee, + orderType, + new WxPayV3.nativeOrderGenerateListener() { + @Override + public void onOrderGenerateSuccess(String code_url) { + showQrCode(code_url); + } + + @Override + public void onOrderGenerateFailed(String errorMsg) { + ToastUtils.showLong(errorMsg); + } + }); + } + + /** + * App跳转微信支付,下单 + * + * @param fee 金额,单位分 + */ + private void appOrder(int fee) { + //查询订单是否支付成功 + payingDialog = new MaterialDialog.Builder(OpeningRenewalVipActivity.this) + .title(R.string.hint) + .content("正在支付……稍后请点击\"支付完成\"") + .positiveText(R.string.pay_over) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + //查询订单是否支付成功 + queryOrderStatus(); + } + }) + .show(); + + WxPayV3.getInstance().generateAppVipOrder(this, + LCUser.getCurrentUser().getSessionToken(), + "导线助手会员", + fee, + orderType, + new WxPayV3.appOrderGenerateListener() { + @Override + public void onOrderGenerateSuccess() { + hasPayResult = false; + WxPayV3.getInstance().pay(); + } + + @Override + public void onOrderGenerateFailed(String errorMsg) { + ToastUtils.showLong(errorMsg); + } + }); + } + + /** + * 查询订单支付状态 + */ + private void queryOrderStatus() { + binding.activityOpeningRenewalBtnWepay.setEnabled(true); + if (payingDialog != null) + payingDialog.dismiss(); + WxPayV3.getInstance().queryVipOrder(this, new WxPayV3.VipOrderQueryListener() { + @Override + public void onOrderPaySuccess(String orderType, Date paySuccessDate) { + VipManager.getInstance().controlSdkRefresh(OpeningRenewalVipActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + binding.activityOpeningRenewalTvExpirationDate.setText(String.format("%s:%s", getString(R.string.current_expiration_date), DateUtils.toFull(VipManager.getInstance().expireDate))); + new AlertDialog.Builder(OpeningRenewalVipActivity.this) + .setTitle(R.string.success) + .setMessage("续费成功,当前到期时间为" + DateUtils.toFull(VipManager.getInstance().expireDate)) + .setPositiveButton(R.string.confirm, null) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + setResult(RESULT_OK); + finish(); + } + }) + .show(); + } + + @Override + public void onRefreshFailed(int errorCode) { + ToastUtils.showShort(getString(R.string.error_code) + ":" + errorCode); + } + }); + } + + @Override + public void onOrderQueryFailed(String errorMsg) { + tryQueryPayResultAgain(getString(R.string.pay_failed), errorMsg); + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + setResult(RESULT_OK); + finish(); + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void onResume() { + super.onResume(); + if (hasPayResult) { + queryOrderStatus(); + hasPayResult = false; + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(PayOverEvent event) { + hasPayResult = true; + } + + /** + * 查询失败后再次显示查询查询 + */ + private void tryQueryPayResultAgain(String title, String message) { + if (!ActivityUtils.isLiving(this)) { + return; + } + new AlertDialog.Builder(OpeningRenewalVipActivity.this) + .setTitle(title) + .setMessage(message) + .setPositiveButton(R.string.query_again, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (queryCount >= 5) { + ToastUtils.showLong(R.string.query_times_cannot_bigger_than_five); + return; + } + queryCount++; + //查询订单是否支付成功 + queryOrderStatus(); + } + }) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + /** + * 生成二维码 + */ + public void showQrCode(String code_url) { + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.wechat_qr_pay) + .customView(R.layout.dialog_register_pay_qr_code, false) + .positiveText(this.getString(R.string.pay_over)) + .dismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialogInterface) { + //查询订单是否支付成功 + queryOrderStatus(); + } + }) + .build(); + + qrImageView = dialog.getCustomView().findViewById(R.id.dialog_register_pay_qr_code_imageview); + try { + HmsBuildBitmapOption options = new HmsBuildBitmapOption.Creator() + .setBitmapMargin(1) + .setBitmapColor(Color.BLACK) + .setBitmapBackgroundColor(Color.WHITE) + .create(); + Bitmap resultImage = ScanUtil.buildBitmap(code_url, HmsScan.QRCODE_SCAN_TYPE, 700, 700, options); + qrImageView.setImageBitmap(resultImage); + } catch (WriterException e) { + ToastUtils.showShort("二维码参数错误!"); + } + if (!ActivityUtils.isLiving(this)) { + return; + } + dialog.show(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + if (payingDialog != null) { + payingDialog.dismiss(); + payingDialog = null; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/RedeemVipActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/RedeemVipActivity.java new file mode 100644 index 0000000..c77c3b9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/RedeemVipActivity.java @@ -0,0 +1,171 @@ +package com.bingce.controlnetwork.activity.user; + +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.graphics.Color; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; + +import androidx.appcompat.app.AlertDialog; + +import com.bingce.AppChannel; +import com.bingce.activity.VipCloudFunction; +import com.bingce.controlapphelper.util.HideKeyUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityRedeemBinding; +import com.bingce.utils.DateUtils; +import com.bingce.utils.VipManager; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.Date; + +import blankj.utilcode.util.AppUtils; +import blankj.utilcode.util.ToastUtils; +import cn.leancloud.LCObject; +import cn.leancloud.LCUser; + +public class RedeemVipActivity extends ColorfulActivity { + private ProgressDialog progressDialog; + private LCObject cashVoucherLCObject; + private ActivityRedeemBinding binding; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityRedeemBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + setSupportActionBar(binding.getRoot().findViewById(R.id.toolbar)); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + initMaterialEditTextColor(); + + binding.activityRedeemTvVersion.setText("V" + AppUtils.getAppVersionName()); + + if (LCUser.getCurrentUser() != null) { + if (VipManager.getInstance().expireDate != null) { + binding.activityRedeemTvExpirationDate.setText(getString(R.string.current_expiration_date) + ":" + DateUtils.toFull(VipManager.getInstance().expireDate)); + } else { + binding.activityRedeemTvExpirationDate.setText(getString(R.string.current_expiration_date) + ":无"); + } + } else { + ToastUtils.showShort(R.string.not_log_in); + finish(); + } + + if (VipManager.getInstance().checkReg()) { + new AlertDialog.Builder(this) + .setTitle(R.string.hint) + .setMessage("此手机已经绑定激活,请确定是否需要购买会员,绑定激活和购买会员可以二选其一") + .setPositiveButton(R.string.i_know, null) + .show(); + } + + binding.activityRedeemMetRedeemCode.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + binding.activityRedeemBtnRedeem.setEnabled(!"".equals(binding.activityRedeemMetRedeemCode.getText().toString().trim())); + } + }); + + binding.activityRedeemBtnRedeem.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (LCUser.getCurrentUser() == null) { + ToastUtils.showShort(R.string.not_log_in); + return; + } + HideKeyUtil.hideSoftInput(); + if (binding.activityRedeemMetRedeemCode.getText().toString().trim().length() != 24) { + ToastUtils.showShort(R.string.cash_voucher_code_length_must_be_24); + return; + } + + progressDialog = new ProgressDialog(RedeemVipActivity.this); + progressDialog.setMessage(getString(R.string.please_wait)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + + String cashVoucherCode = binding.activityRedeemMetRedeemCode.getText().toString().trim().toLowerCase(); + VipCloudFunction.redeemVip(LCUser.getCurrentUser().getSessionToken(), cashVoucherCode, AppChannel.customChannel, new VipCloudFunction.OnRedeemVipListener() { + @Override + public void onRedeemSuccess(Date newExpireDate) { + if (progressDialog != null) + progressDialog.dismiss(); + + savePayLog(cashVoucherCode, newExpireDate); + + new AlertDialog.Builder(RedeemVipActivity.this) + .setTitle(R.string.success) + .setMessage("续费成功,当前到期时间为" + DateUtils.toFull(newExpireDate)) + .setPositiveButton(R.string.confirm, null) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + setResult(RESULT_OK); + finish(); + } + }) + .show(); + } + + @Override + public void onRedeemFailed(String errorMsg) { + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(errorMsg); + } + }); + } + }); + } + + private void savePayLog(String cashVoucher, Date newExpireDate) { + final LCObject payLog = new LCObject("PayLog"); + payLog.put("payFor", "兑换会员"); + payLog.put("user", LCUser.getCurrentUser()); + payLog.put("currentExpireDate", newExpireDate); + payLog.put("client", "android"); + payLog.put("channel", "cashVoucher"); + payLog.put("total_fee", "0"); + payLog.put("cash_fee", "0"); + payLog.put("versionCode", AppUtils.getAppVersionCode()); + payLog.put("cashVoucher", cashVoucher); + payLog.saveInBackground().subscribe(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + private void initMaterialEditTextColor() { + if (SettingValueUtil.isThemeDark()) { + binding.activityRedeemMetRedeemCode.setMetTextColor(Color.WHITE); + + binding.activityRedeemMetRedeemCode.setPrimaryColor(Color.LTGRAY); + + binding.activityRedeemMetRedeemCode.setFocusFraction(1.0f); + + binding.activityRedeemMetRedeemCode.setMetHintTextColor(Color.GRAY); + + binding.activityRedeemMetRedeemCode.setUnderlineColor(Color.GRAY); + } + } +} 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 new file mode 100644 index 0000000..0fba0a6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/RegisterActivity.java @@ -0,0 +1,394 @@ +package com.bingce.controlnetwork.activity.user; + +import android.Manifest; +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.os.Build; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.util.CheckRegUtil; +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.device.enums.SpecialDeviceEnum; +import com.bingce.device.ui.dialog.DialogUtil; +import com.bingce.surveyor.agentweb.AgentWebActivity; +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; +import com.hjq.permissions.OnPermissionCallback; +import com.hjq.permissions.Permission; +import com.hjq.permissions.XXPermissions; +import com.huawei.hms.hmsscankit.ScanUtil; +import com.huawei.hms.hmsscankit.WriterException; +import com.huawei.hms.ml.scan.HmsBuildBitmapOption; +import com.huawei.hms.ml.scan.HmsScan; +import com.rengwuxian.materialedittext.MaterialEditText; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.List; +import java.util.Locale; + +import blankj.utilcode.util.AppUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCException; +import cn.leancloud.LCObject; +import cn.leancloud.LCQuery; +import cn.leancloud.LCUser; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +public class RegisterActivity extends ColorfulActivity { + private MaterialEditText met_machine_code, met_activate_code; + private Button mBtnCopy, mBtnActivate, mBtnTaobaoLink, mBtnContactAuthor, mBtnMachineQr, mBtnActivateTutorial; + private TextView mTextViewActivity, mTextViewVersion; + private String mMachineCode = "", mOriginalMachineCode = ""; + private Toolbar mToolbar; + boolean hasAndroidPermission = false; + private ProgressDialog progressDialog; + private ImageView qrImageView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_activate); + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + initWidget(); + initMaterialEditTextColor(); + + mTextViewVersion.setText("V" + AppUtils.getAppVersionName()); + + if (!AppUtil.isZhCN() && 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; + for (SpecialDeviceEnum device : SpecialDeviceEnum.values()) { + if (device.getModel().equals(PropertiesGet.getModel()) + && device.getDevice().equals(PropertiesGet.getDevice()) + && device.getBoard().equals(PropertiesGet.getBoard()) + && device.getBrand().equals(PropertiesGet.getBrand()) + && device.getCpuAbi().equals(PropertiesGet.getCpuAbi()) + && device.getHardware().equals(PropertiesGet.getHardware()) + && device.getManufacturer().equals(PropertiesGet.getManufacturer())) { + isSpecial = true; + break; + } + } +// if (!isSpecial && Build.VERSION.SDK_INT >= 29) { +// mBtnTaobaoLink.setVisibility(View.GONE); +// new AlertDialog.Builder(this) +// .setMessage("由于安卓10及以上系统限制App读取硬件信息,原来绑定手机激活的方式已经不可用,如果您之前绑定手机激活过,很遗憾,现在只能刷机降级到安卓9或安卓8重新输入激活才可以。如果您不想刷机,可以购买会员继续使用") +// .setPositiveButton(R.string.user_vip_activate, new DialogInterface.OnClickListener() { +// @Override +// public void onClick(DialogInterface dialog, int which) { +// if (LCUser.getCurrentUser() == null) { +// Intent intent = new Intent(Utils.getApp(), LoginActivity.class); +// intent.putExtra("finishTo", UserInfoActivity.class.getName()); +// startActivity(intent); +// } else { +// startActivity(new Intent(RegisterActivity.this, UserInfoActivity.class)); +// } +// } +// }) +// .setNeutralButton(R.string.opening_vip_tutorial, new DialogInterface.OnClickListener() { +// @Override +// public void onClick(DialogInterface dialog, int which) { +//// Intent intent = new Intent(); +//// intent.setClass(Utils.getApp(), AgentWebActivity.class); +//// intent.putExtra("short_url", "android_url_opening_renewal_tutorial"); +//// startActivity(intent); +// AgentWebActivity.navigation2(RegisterActivity.this, +// "android_url_opening_renewal_tutorial"); +// } +// }) +// .setNegativeButton(R.string.cancel, null) +// .setOnDismissListener(new DialogInterface.OnDismissListener() { +// @Override +// public void onDismiss(DialogInterface dialog) { +// if (!hasAndroidPermission) +// finish(); +// } +// }).show(); +// } else { +// int checkStoragePermission = ContextCompat.checkSelfPermission(Utils.getApp(), Manifest.permission.READ_PHONE_STATE); +// if (checkStoragePermission != PackageManager.PERMISSION_GRANTED) { +// requestPhoneStatePermission(this); +// } else { +// if ("".equals(RegisterUtil.getOriginalMachineCode()) || "SERIALNUMBERunknown".equals(RegisterUtil.getOriginalMachineCode()) || "SERIALNUMBERnull".equals(RegisterUtil.getOriginalMachineCode())) { +// new MaterialDialog.Builder(this) +// .title(R.string.hint) +// .content("此手机机器码未知,请关闭相关限制软件请重启软件") +// .positiveText(R.string.i_know) +// .dismissListener(new DialogInterface.OnDismissListener() { +// @Override +// public void onDismiss(DialogInterface dialog) { +// finish(); +// } +// }).show(); +// } +// } +// } + if (CheckRegUtil.checkReg(((App) Utils.getApp()).registerCodeV2)) { + getSupportActionBar().setTitle(R.string.activated); + met_activate_code.setText(((App) Utils.getApp()).registerCodeV2); + mBtnActivate.setEnabled(false); + met_activate_code.setEnabled(false); + mBtnActivate.setText(R.string.activated); + } + + mMachineCode = RegisterUtil.getEncryptMachineCodeInfo(); + mOriginalMachineCode = RegisterUtil.getOriginalMachineCode(); + if (mMachineCode != null) { + met_machine_code.setText(mMachineCode); + } else { + met_machine_code.setText(getString(R.string.get_machine_code_fail)); + } + String queryUrl = "activate_activity_for_control_network"; + LeanCloudConfigLoader.findInBackground(queryUrl, instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", queryUrl) +// .limit(1) +// .findInBackground() +// .subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (isFinishing()) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String activity = /*avObjects.get(0).getString("value")*/instance.value; + mTextViewActivity.setText(activity); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + mBtnCopy.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + if (mMachineCode != null) { + ClipboardUtils.copyText(mMachineCode); + ToastUtils.showShort(R.string.has_copy_to_clipboard); + } else { + ToastUtils.showShort(R.string.get_machine_code_fail); + } + } + }); + mBtnActivate.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + 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); + return; + } + if ("".equals(met_activate_code.getText().toString().trim())) { + ToastUtils.showShort(R.string.please_input_register_code); + return; + } + if (registerCode.length() != 16) { + ToastUtils.showShort(R.string.register_code_is_16_characters); + return; + } + if (CheckRegUtil.checkReg(registerCode)){ + ((App) Utils.getApp()).registerCodeV2 = registerCode; + Util.putPreference("registerCodeV2", registerCode); + } + } + }); + mBtnTaobaoLink.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "taobaoUrl"); +// startActivity(intent); + AgentWebActivity.navigation2(RegisterActivity.this, "taobaoUrl"); + } + }); + mBtnContactAuthor.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "android_url_contact_author"); +// startActivity(intent); + AgentWebActivity.navigation2(RegisterActivity.this, + "android_url_contact_author"); + } + }); + + mBtnMachineQr.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (!mMachineCode.isEmpty()) + showMachineCodeQr(mMachineCode); + } + }); + + mBtnActivateTutorial.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "android_url_activate_tutorial"); +// startActivity(intent); + AgentWebActivity.navigation2( + RegisterActivity.this, + "android_url_activate_tutorial"); + } + }); + } + + private void initWidget() { + met_machine_code = findViewById(R.id.activity_activate_met_machine_code); + met_activate_code = findViewById(R.id.activity_activate_met_activate_code); + mBtnCopy = findViewById(R.id.activity_activate_btn_copy); + mBtnActivate = findViewById(R.id.activity_activate_btn_activate); + mBtnTaobaoLink = findViewById(R.id.activity_activate_btn_taobao_link); + mBtnContactAuthor = findViewById(R.id.activity_activate_btn_contact_customer_service); + mBtnMachineQr = findViewById(R.id.activity_activate_btn_machine_code_qr_code); + mBtnActivateTutorial = findViewById(R.id.activity_activate_btn_activate_tutorial); + mTextViewActivity = findViewById(R.id.activity_activate_tv_activity); + mTextViewVersion = findViewById(R.id.activity_activate_tv_version); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 12) { + if (resultCode == Activity.RESULT_OK) { + met_activate_code.setText(((App) Utils.getApp()).registerCodeV2); + getSupportActionBar().setTitle(R.string.activated); + mBtnActivate.setEnabled(false); + met_activate_code.setEnabled(false); + } + } + } + + private void initMaterialEditTextColor() { + if (SettingValueUtil.isThemeDark()) { + met_machine_code.setMetTextColor(Color.WHITE); + met_activate_code.setMetTextColor(Color.WHITE); + + met_machine_code.setPrimaryColor(Color.LTGRAY); + met_activate_code.setPrimaryColor(Color.LTGRAY); + + met_machine_code.setFocusFraction(1.0f); + met_activate_code.setFocusFraction(1.0f); + + met_machine_code.setMetHintTextColor(Color.GRAY); + met_activate_code.setMetHintTextColor(Color.GRAY); + + met_machine_code.setUnderlineColor(Color.GRAY); + met_activate_code.setUnderlineColor(Color.GRAY); + } + } + + /** + * 生成机器码的二维码 + */ + public void showMachineCodeQr(String mMachineCode) { + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.machine_code) + .customView(R.layout.dialog_machine_code_qr_code, false) + .positiveText(this.getString(R.string.close)) + .build(); + + qrImageView = dialog.getCustomView().findViewById(R.id.dialog_machine_code_qr_code_imageview); + try { + HmsBuildBitmapOption options = new HmsBuildBitmapOption.Creator() + .setBitmapMargin(1) + .setBitmapColor(Color.BLACK) + .setBitmapBackgroundColor(Color.WHITE) + .create(); + Bitmap resultImage = ScanUtil.buildBitmap(mMachineCode, HmsScan.QRCODE_SCAN_TYPE, 700, 700, options); + qrImageView.setImageBitmap(resultImage); + } catch (WriterException e) { + ToastUtils.showShort("二维码参数错误!"); + } + dialog.show(); + } + + public static void requestPhoneStatePermission(Context context) { + new MaterialDialog.Builder(context) + .title(R.string.mobile_phone_permissions) + .content(R.string.verify_imei_imsi_code_to_prevent_account_theft) + .canceledOnTouchOutside(false) + .positiveText(R.string.to_allow) + .negativeText(R.string.refuse) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + XXPermissions.with(context) + .permission(Permission.READ_PHONE_STATE) + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + ToastUtils.showShort(R.string.manually_enable_the_phone_state_permission_to_bind_hardware_devices); + } else { + ToastUtils.showShort(R.string.please_open_permission_to_activation); + requestPhoneStatePermission(context); + } + } + }); + } + }) + .show(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifyEmailCodeActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifyEmailCodeActivity.java new file mode 100644 index 0000000..cb42cf1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifyEmailCodeActivity.java @@ -0,0 +1,234 @@ +package com.bingce.controlnetwork.activity.user; + +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.style.TextAppearanceSpan; +import android.view.View; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.AppChannel; +import com.bingce.activity.UserCloudFunction; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityVerifyCodeBinding; +import com.bingce.utils.ActivityUtils; +import com.bingce.utils.IntentUtil; +import com.bingce.utils.SendCodeCountDownManager; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import blankj.utilcode.util.ToastUtils; + +public class VerifyEmailCodeActivity extends ColorfulActivity { + + public static final String KEY_EMAIL = "email"; + public static final String KEY_TODO = "todo"; + private static ActivityResultLauncher mLauncher; + + public static final int TO_VERIFY_EMAIL = 0; + public static final int TO_SIGNUP_OR_LOGIN_BY_EMAIL = 1; + + private ActivityVerifyCodeBinding binding; + private ProgressDialog progressDialog; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityVerifyCodeBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + getSupportActionBar().setTitle(R.string.verify); + + binding.tvInputHintTitle.setText(R.string.enter_email_verification_code); + + String trip = String.format(getString(R.string.format_enter_verification_code), getEmail()); + binding.tvInputTrip.setText(matcherChangeText(trip, getEmail()));//+前需要转义 + + SendCodeCountDownManager.getInstance().start(this, 60000, 1000, binding.tvSendAuthCode, new SendCodeCountDownManager.OnCountDownListener() { + @Override + public void onSendValid() { + sendCode(); + } + + @Override + public void onSendInvalid() { + + } + }); + binding.tvSendAuthCode.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + SendCodeCountDownManager.getInstance().start(VerifyEmailCodeActivity.this, 60000, 1000, binding.tvSendAuthCode, new SendCodeCountDownManager.OnCountDownListener() { + @Override + public void onSendValid() { + sendCode(); + } + + @Override + public void onSendInvalid() { + + } + }); + } + }); + + binding.etInputAuthCode.setOnInputListener(code -> { + verifyCode(code); + }); + } + + private void sendCode() { + if (getEmail() == null) { + ToastUtils.showShort(R.string.email_address_illegal); + return; + } + UserCloudFunction.sendEmailCode(getEmail(), new UserCloudFunction.OnSendCodeListener() { + @Override + public void onCodeSendSuccess() { + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(R.string.send_success); + } + + @Override + public void onCodeSendFailed(String errorMsg) { + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(errorMsg); + } + }); + } + + private void verifyCode(String code) { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(VerifyEmailCodeActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + switch (getToDo()) { + case TO_VERIFY_EMAIL: + if (getEmail() == null) { + ToastUtils.showShort(R.string.email_address_illegal); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.verifyEmailCode(getEmail(), code, new UserCloudFunction.OnVerifyCodeListener() { + @Override + public void onCodeVerifySuccess() { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("isMail", true); + intent.putExtra("phoneNumberOrEmail", getEmail()); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onCodeVerifyFailed(String errorMsg) { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(errorMsg); + } + }); + break; + case TO_SIGNUP_OR_LOGIN_BY_EMAIL: + if (getEmail() == null) { + ToastUtils.showShort(R.string.email_address_illegal); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.signUpOrLoginByEmail(getEmail(), code, AppChannel.customChannel, + new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("sessionToken", sessionToken); + intent.putExtra("newUser", newUser); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + if (code == 303) {//缺少手机号或未验证 + SendCodeCountDownManager.getInstance().resetRemainingTime(); + InputPhoneNumberActivity.start(VerifyEmailCodeActivity.this, null, getEmail(), null, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_EMAIL_BIND_PHONE, mLauncher); + finish(); + } else { + ToastUtils.showLong(msg); + } + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + break; + } + } + + + private String getEmail() { + return IntentUtil.stringExtra(getIntent(), KEY_EMAIL); + } + + private int getToDo() { + return IntentUtil.intExtra(getIntent(), KEY_TODO); + } + + public static void start(Context context, String email, int todo, ActivityResultLauncher launcher) { + Intent intent = new Intent(context, VerifyEmailCodeActivity.class); + intent.putExtra(KEY_EMAIL, email); + intent.putExtra(KEY_TODO, todo); + mLauncher = launcher; + launcher.launch(intent); + } + + private SpannableString matcherChangeText(String str, String keyword) { + SpannableString ss = new SpannableString(str); + Pattern pattern = Pattern.compile(keyword); + Matcher matcher = pattern.matcher(ss); + while (matcher.find()) { + int start = matcher.start(); + int end = matcher.end(); + ss.setSpan(new TextAppearanceSpan(this, R.style.style_color_black), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//new ForegroundColorSpan(color) + } + return ss; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifySMSCodeActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifySMSCodeActivity.java new file mode 100644 index 0000000..e05ca85 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifySMSCodeActivity.java @@ -0,0 +1,329 @@ +package com.bingce.controlnetwork.activity.user; + +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.style.TextAppearanceSpan; +import android.view.View; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.AppChannel; +import com.bingce.activity.UserCloudFunction; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityVerifyCodeBinding; +import com.bingce.utils.ActivityUtils; +import com.bingce.utils.IntentUtil; +import com.bingce.utils.SendCodeCountDownManager; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import blankj.utilcode.util.ToastUtils; + +public class VerifySMSCodeActivity extends ColorfulActivity { + public static final String KEY_PHONE = "phone_number"; + public static final String KEY_EMAIL = "email"; + public static final String KEY_UNION_ID = "unionid"; + public static final String KEY_TODO = "todo"; + + public static final int TO_VERIFY_PHONE_NUMBER = 0; + public static final int TO_SIGNUP_OR_LOGIN_BY_PHONE_NUMBER = 1; + public static final int TO_SIGNUP_OR_LOGIN_BY_EMAIL_BIND_PHONE = 2; + public static final int TO_SIGNUP_OR_LOGIN_BY_WEIXIN_BIND_PHONE = 3; + private ActivityVerifyCodeBinding binding; + private ProgressDialog progressDialog; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityVerifyCodeBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + getSupportActionBar().setTitle(R.string.verify); + + binding.tvInputHintTitle.setText(R.string.enter_sms_verification_code); + + String phoneOrEmail = getPhoneNumber(); + String trip = String.format(getString(R.string.format_enter_verification_code), phoneOrEmail); + binding.tvInputTrip.setText(matcherChangeText(trip, phoneOrEmail.startsWith("+") ? ("\\" + phoneOrEmail) : phoneOrEmail));//+前需要转义 + + SendCodeCountDownManager.getInstance().start(this, 60000, 1000, binding.tvSendAuthCode, new SendCodeCountDownManager.OnCountDownListener() { + @Override + public void onSendValid() { + sendCode(); + } + + @Override + public void onSendInvalid() { + + } + }); + binding.tvSendAuthCode.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + SendCodeCountDownManager.getInstance().start(VerifySMSCodeActivity.this, 60000, 1000, binding.tvSendAuthCode, new SendCodeCountDownManager.OnCountDownListener() { + @Override + public void onSendValid() { + sendCode(); + } + + @Override + public void onSendInvalid() { + + } + }); + } + }); + + binding.etInputAuthCode.setOnInputListener(code -> { + verifyCode(code); + }); + } + + private void sendCode() { + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + return; + } + UserCloudFunction.sendSMSCode(getPhoneNumber(), new UserCloudFunction.OnSendCodeListener() { + @Override + public void onCodeSendSuccess() { + ToastUtils.showShort(R.string.send_success); + } + + @Override + public void onCodeSendFailed(String errorMsg) { + ToastUtils.showLong(errorMsg); + } + }); + } + + private void verifyCode(String code) { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(VerifySMSCodeActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + + switch (getTodo()) { + case TO_VERIFY_PHONE_NUMBER: + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.verifySMSCode(getPhoneNumber(), code, new UserCloudFunction.OnVerifyCodeListener() { + @Override + public void onCodeVerifySuccess() { + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("isMail", false); + intent.putExtra("phoneNumberOrEmail", getPhoneNumber()); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onCodeVerifyFailed(String errorMsg) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(errorMsg); + } + }); + break; + case TO_SIGNUP_OR_LOGIN_BY_PHONE_NUMBER: + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.signUpOrLoginByMobilePhone(getPhoneNumber(), code, AppChannel.customChannel, + new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("sessionToken", sessionToken); + intent.putExtra("newUser", newUser); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + break; + case TO_SIGNUP_OR_LOGIN_BY_EMAIL_BIND_PHONE: + if (getEmail() == null) { + ToastUtils.showShort(R.string.email_address_illegal); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.loginByEmailBindPhone(getEmail(), getPhoneNumber(), code, AppChannel.customChannel, + new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("sessionToken", sessionToken); + intent.putExtra("newUser", newUser); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + break; + case TO_SIGNUP_OR_LOGIN_BY_WEIXIN_BIND_PHONE: + if (getUnionId() == null) { + ToastUtils.showShort(R.string.wechat_unionid_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.loginByWxUnionIdBindPhone(getUnionId(), getPhoneNumber(), AppChannel.customChannel, + new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("sessionToken", sessionToken); + intent.putExtra("newUser", newUser); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + break; + } + + } + + private String getPhoneNumber() { + return IntentUtil.stringExtra(getIntent(), KEY_PHONE); + } + + private String getEmail() { + return IntentUtil.stringExtra(getIntent(), KEY_EMAIL); + } + + private String getUnionId() { + return IntentUtil.stringExtra(getIntent(), KEY_UNION_ID); + } + + + private int getTodo() { + return IntentUtil.intExtra(getIntent(), KEY_TODO); + } + + public static void start(Context context, String phoneNumber, String email, String unionid, int todo, ActivityResultLauncher launcher) { + Intent intent = new Intent(context, VerifySMSCodeActivity.class); + intent.putExtra(KEY_PHONE, phoneNumber); + intent.putExtra(KEY_EMAIL, email); + intent.putExtra(KEY_UNION_ID, unionid); + intent.putExtra(KEY_TODO, todo); + launcher.launch(intent); + } + + private SpannableString matcherChangeText(String str, String keyword) { + SpannableString ss = new SpannableString(str); + Pattern pattern = Pattern.compile(keyword); + Matcher matcher = pattern.matcher(ss); + while (matcher.find()) { + int start = matcher.start(); + int end = matcher.end(); + ss.setSpan(new TextAppearanceSpan(this, R.style.style_color_black), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//new ForegroundColorSpan(color) + } + return ss; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/AbstractPointSelectAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/AbstractPointSelectAdapter.java new file mode 100644 index 0000000..cdd0d1e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/AbstractPointSelectAdapter.java @@ -0,0 +1,176 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.vh.GroupParentViewHolder; +import com.bingce.controlnetwork.ui.vh.TextSelectableViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/* + * 限差详情adapter + * */ +public abstract class AbstractPointSelectAdapter extends BaseExpandableListAdapter { + private final ArrayList selectedId = new ArrayList<>(); + private final ArrayList selectedName = new ArrayList<>(); + private final int maxCount; + private final Context context; + + public AbstractPointSelectAdapter(PickPointResult defaultValue, + int maxCount, + Context context) { + this.maxCount = maxCount; + if (defaultValue != null) { + List ids = defaultValue.getSelectedIds(); + if (ids != null) { + selectedId.addAll(ids); + } + + List names = defaultValue.getSelectedNames(); + if (names != null) { + selectedName.addAll(names); + } + } + this.context = context; + } + + protected Context context() { + return context; + } + + public ArrayList getSelectedId() { + return selectedId; + } + + public ArrayList getSelectedName() { + return selectedName; + } + + public abstract int getGroupCount(); + + public abstract int getChildrenCount(int groupPosition); + + public abstract String getGroup(int groupPosition); + + public abstract PointRecord getChild(int groupPosition, int childPosition); + + @Override + final public long getGroupId(int groupPosition) { + return groupPosition; + } + + @Override + final public long getChildId(int groupPosition, int childPosition) { + return groupPosition * 10000L + childPosition; + } + + @Override + public boolean hasStableIds() { + return true; + } + + protected boolean showGroupArrow() { + return true; + } + + @Override + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { + GroupParentViewHolder viewHolder = null; + if (convertView == null) { + convertView = ViewFactory.generatorView(parent.getContext(), parent, ViewItemType.groupParent); + viewHolder = new GroupParentViewHolder(convertView); + convertView.setTag(viewHolder); + } else { + viewHolder = (GroupParentViewHolder) convertView.getTag(); + } + if (viewHolder != null) { + String groupName = getGroup(groupPosition); + if (viewHolder.name != null) { + viewHolder.name.setText(groupName); + } + if (viewHolder.expandIcon != null) { + if (showGroupArrow()) { + viewHolder.expandIcon.setImageResource(isExpanded ? R.drawable.ic_arrow_up : R.drawable.ic_arrow_down); + viewHolder.expandIcon.setVisibility(View.VISIBLE); + } else { + viewHolder.expandIcon.setVisibility(View.GONE); + } + } + } + return convertView; + } + + @Override + public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { + PointRecord record = getChild(groupPosition, childPosition); + RecyclerView.ViewHolder viewHolder = null; + if (convertView == null) { + viewHolder = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.textSelectable); + if (viewHolder == null) { + return null; + } + convertView = viewHolder.itemView; + convertView.setTag(viewHolder); + } else { + viewHolder = (RecyclerView.ViewHolder) convertView.getTag(); + } + //更新item内容 + if (viewHolder instanceof TextSelectableViewHolder) { + TextSelectableViewHolder titleWithSubtitleViewHolder = (TextSelectableViewHolder) viewHolder; + titleWithSubtitleViewHolder.name.setText(record.getName()); + if (selectedId.contains(record.getId())) { + titleWithSubtitleViewHolder.status.setVisibility(View.VISIBLE); + } else { + titleWithSubtitleViewHolder.status.setVisibility(View.GONE); + } + } + convertView.setOnClickListener(v -> { + if (!selectedId.contains(record.getId())) { +// if (singlePick) { +// selectedId.clear(); +// selectedName.clear(); +// } +// selectedId.add(record.getId()); +// selectedName.add(record.getName()); + if (maxCount == 1) { + selectedId.clear(); + selectedName.clear(); + selectedId.add(record.getId()); + selectedName.add(record.getName()); + } else if (maxCount < 0) { + selectedId.add(record.getId()); + selectedName.add(record.getName()); + } else if (selectedId.size() >= maxCount) { + ToastUtils.showShort(Tools.getString(R.string.max_select_hint, maxCount)); + } else { + selectedId.add(record.getId()); + selectedName.add(record.getName()); + } + } else { + selectedId.remove(record.getId()); + selectedName.remove(record.getName()); + } + notifyDataSetChanged(); + }); + return convertView; + } + + @Override + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseAdapter.java new file mode 100644 index 0000000..5c2f52c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseAdapter.java @@ -0,0 +1,57 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public abstract class BaseAdapter extends RecyclerView.Adapter { + private final List mValues; + + public BaseAdapter(List items) { + mValues = items; + } + + public void updateData(List list) { + mValues.clear(); + if (list != null && !list.isEmpty()) { + mValues.addAll(list); + } + notifyDataSetChanged(); + } + + protected abstract VH createVH(@NotNull ViewGroup parent, int viewType); + + @Override + public @NotNull + VH onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { + VH viewHolder = createVH(parent, viewType); + assert viewHolder != null; + return viewHolder; + } + + protected T getItem(int position) { + return mValues.get(position); + } + + protected boolean clickEnable(int position) { + return true; + } + + @Override + public int getItemCount() { + if (mValues == null) { + return 0; + } + return mValues.size(); + } + + public interface IOnItemClick> { + void onItemClick(T item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexPrefixTextWithContextMenuAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexPrefixTextWithContextMenuAdapter.java new file mode 100644 index 0000000..82078e9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexPrefixTextWithContextMenuAdapter.java @@ -0,0 +1,61 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextWithPrefixViewHolder; + +public abstract class BaseIndexPrefixTextWithContextMenuAdapter> + extends IndexWithTextAndPrefixAdapter + implements View.OnCreateContextMenuListener { + private int currentLongPressIndex = -1; + private final IAdapterContextMenu adapterContextMenu; + + public BaseIndexPrefixTextWithContextMenuAdapter(List items, + IOnItemClick callback, + IAdapterContextMenu adapterContextMenu) { + super(items, callback); + this.adapterContextMenu = adapterContextMenu; + } + + @Override + final public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + if (holder instanceof IndexTextWithPrefixViewHolder) { + onSetPrefix(((IndexTextWithPrefixViewHolder) holder).prefix, getItem(position)); + } + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + 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(getItem(currentLongPressIndex), item)); + } + } + } + + protected abstract void onSetPrefix(TextView prefixTextView, T item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexTextWithContextMenuAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexTextWithContextMenuAdapter.java new file mode 100644 index 0000000..738f542 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexTextWithContextMenuAdapter.java @@ -0,0 +1,54 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; + +public class BaseIndexTextWithContextMenuAdapter> + extends IndexWithTextAdapter + implements View.OnCreateContextMenuListener { + private int currentLongPressIndex = -1; + private final IAdapterContextMenu adapterContextMenu; + + public BaseIndexTextWithContextMenuAdapter(List items, + IOnItemClick callback, + IAdapterContextMenu adapterContextMenu) { + super(items, callback); + this.adapterContextMenu = adapterContextMenu; + } + + @Override + final public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + 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(getItem(currentLongPressIndex), item)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseSelectableIndexTextWithContextMenuAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseSelectableIndexTextWithContextMenuAdapter.java new file mode 100644 index 0000000..cabe047 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseSelectableIndexTextWithContextMenuAdapter.java @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; + +public class BaseSelectableIndexTextWithContextMenuAdapter> + extends SelectableIndexWithTextAdapter + implements View.OnCreateContextMenuListener { + private int currentLongPressIndex = -1; + private final IAdapterContextMenu adapterContextMenu; + + public BaseSelectableIndexTextWithContextMenuAdapter(String selectedId, + List items, + IOnItemClick callback, + IAdapterContextMenu adapterContextMenu) { + super(selectedId, items, callback); + this.adapterContextMenu = adapterContextMenu; + } + + @Override + final public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + 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(getItem(currentLongPressIndex), item)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseTitleAndSubtitleWithContextMenuAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseTitleAndSubtitleWithContextMenuAdapter.java new file mode 100644 index 0000000..caa98be --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseTitleAndSubtitleWithContextMenuAdapter.java @@ -0,0 +1,51 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; + +import com.bingce.controlapphelper.model.IUniversalListItemWithTitleAndSubtitle; +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.TitleWithSubtitleViewHolder; + +import java.util.List; + +public class BaseTitleAndSubtitleWithContextMenuAdapter> + extends TitleWithSubtitleAdapter + implements View.OnCreateContextMenuListener { + private int currentLongPressIndex = -1; + private final IAdapterContextMenu adapterContextMenu; + + public BaseTitleAndSubtitleWithContextMenuAdapter(List items, + IOnItemClick callback, + IAdapterContextMenu adapterContextMenu) { + super(items, callback); + this.adapterContextMenu = adapterContextMenu; + } + + @Override + final public void onBindViewHolder(TitleWithSubtitleViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + 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(getItem(currentLongPressIndex), item)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/GlobalControlPointSelectAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/GlobalControlPointSelectAdapter.java new file mode 100644 index 0000000..804e4e7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/GlobalControlPointSelectAdapter.java @@ -0,0 +1,49 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlnetwork.R; + +import java.util.List; + +/* + * 限差详情adapter + * */ +public class GlobalControlPointSelectAdapter extends AbstractPointSelectAdapter { + private final List pointRecordList; + + public GlobalControlPointSelectAdapter(List pointRecords, + PickPointResult defaultValue, + int maxCount,//boolean singlePick, + Context context) { + super(defaultValue, maxCount, context); + this.pointRecordList = pointRecords; + } + + @Override + public int getGroupCount() { + return 1; + } + + @Override + public int getChildrenCount(int groupPosition) { + return pointRecordList.size(); + } + + @Override + public String getGroup(int groupPosition) { + return context().getString(R.string.global_control_point); + } + + @Override + public PointRecord getChild(int groupPosition, int childPosition) { + return pointRecordList.get(childPosition); + } + + @Override + protected boolean showGroupArrow() { + return false; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/IOnContextItemSelectedCallback.java b/app/src/main/java/com/bingce/controlnetwork/adapter/IOnContextItemSelectedCallback.java new file mode 100644 index 0000000..ebec77c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/IOnContextItemSelectedCallback.java @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.MenuItem; + +import androidx.annotation.NonNull; + +public interface IOnContextItemSelectedCallback { + void onContextItemSelected(@NonNull MenuItem item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/IUpdateListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/IUpdateListAdapter.java new file mode 100644 index 0000000..f408f72 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/IUpdateListAdapter.java @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.adapter; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import java.util.List; + +public interface IUpdateListAdapter> { + void updateData(List list); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAdapter.java new file mode 100644 index 0000000..25c4c2b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAdapter.java @@ -0,0 +1,88 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +public class IndexWithTextAdapter> extends BaseAdapter { + private IOnItemClick callback; + private boolean showIndex = true; + + public IndexWithTextAdapter(List items, IOnItemClick callback) { + super(items); + this.callback = callback; + } + + public IndexWithTextAdapter(List items) { + super(items); + this.callback = null; + } + + public void setCallback(IOnItemClick callback) { + this.callback = callback; + } + + protected ViewItemType itemType() { + return ViewItemType.indexWithName; + } + + @Override + final protected IndexTextViewHolder createVH(@NotNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder viewHolder = ViewFactory.generatorViewHolder(parent.getContext(), parent, itemType()); + if (viewHolder instanceof IndexTextViewHolder) { + return (IndexTextViewHolder) viewHolder; + } + return null; + } + + protected void hideIndex() { + showIndex = false; + notifyDataSetChanged(); + } + + protected void showIndex() { + showIndex = true; + notifyDataSetChanged(); + } + + protected boolean clickEnable(int position) { + return true; + } + + @Override + public void onBindViewHolder(final @NotNull IndexTextViewHolder holder, int position) { + T item = getItem(position); + if (showIndex) { + holder.index.setVisibility(View.VISIBLE); + holder.index.setText(String.valueOf(position + 1)); + } else { + holder.index.setVisibility(View.GONE); + } + onSetName(holder.name, item); + holder.itemView.setOnClickListener(v -> { + if (callback != null && clickEnable(position)) { + callback.onItemClick(item); + } + }); + } + + protected void onSetName(TextView nameTextView, T item) { + nameTextView.setText(item.getName()); + } + + public interface IOnItemClick> { + void onItemClick(T item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAndPrefixAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAndPrefixAdapter.java new file mode 100644 index 0000000..953da51 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAndPrefixAdapter.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.adapter; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import java.util.List; + +public class IndexWithTextAndPrefixAdapter> extends IndexWithTextAdapter { + public IndexWithTextAndPrefixAdapter(List items, IOnItemClick callback) { + super(items, callback); + } + + public IndexWithTextAndPrefixAdapter(List items) { + super(items); + } + + protected ViewItemType itemType() { + return ViewItemType.indexWithNameAndPrefix; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureAngleDistanceAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureAngleDistanceAdapter.java new file mode 100644 index 0000000..fd11fbb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureAngleDistanceAdapter.java @@ -0,0 +1,122 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IAdapter; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.IMeasureCache; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; + +import com.bingce.controlnetwork.ui.vh.SurveyorDataAloneDistanceViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +/** + * 测量记录adapter + * 井定向-距离 + */ +public class MeasureAngleDistanceAdapter extends RecyclerView.Adapter + implements IAdapter, IDistanceTypeChangeListener { + + public static final String TYPE_ANGLE = "TYPE_ANGLE"; + public static final String TYPE_DISTANCE = "TYPE_DISTANCE"; + + private final IMeasureCache cachedData; + private final ISurveyorData surveyorData; + private final ICycleRecorder cycleRecorder; + private boolean showSlopDistance = true; + private final String stationId; + private final String type;//区分水平还是距离 + + + public MeasureAngleDistanceAdapter( + String stationId, + IMeasureCache cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData, + String type) { + this.stationId = stationId; + this.cachedData = cachedData; + this.surveyorData = surveyorData; + this.cycleRecorder = cycleRecorder; + this.type = type; + //注册数据监听 + cachedData.register(this); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder vh = null; + switch (type) { + case TYPE_ANGLE: + vh = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.surveyorStationPointItem); + break; + case TYPE_DISTANCE: + vh = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.aloneDistanceMeasure); + break; + } + assert vh != null; + return vh; + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof SurveyorDataAloneDistanceViewHolder) { + SurveyorDataAloneDistanceViewHolder holderDistance = (SurveyorDataAloneDistanceViewHolder) holder; + holderDistance.setup(position, + stationId, + showSlopDistance, + (CachedDataAloneDistance) cachedData, + cycleRecorder, + surveyorData); + } else if (holder instanceof SurveyorDataViewHolder) { + SurveyorDataViewHolder holderHorizontalAngle = (SurveyorDataViewHolder) holder; + holderHorizontalAngle.setup(position, + stationId, + showSlopDistance, + (ICachedData) cachedData, + cycleRecorder, + surveyorData); + } + + holder.itemView.setOnClickListener(v -> { + if (iItemClickListener != null) { + iItemClickListener.click(position); + } + }); + } + + @Override + public int getItemCount() { + return cachedData.pointCount(); + } + + @Override + public void onDataChange() { + notifyDataSetChanged(); + } + + @Override + public void onShowSlopDistance(boolean value) { + this.showSlopDistance = value; + } + + + private IItemClickListener iItemClickListener; + + public void setOnItemClickListener(IItemClickListener iItemClickListener) { + this.iItemClickListener = iItemClickListener; + } + + public interface IItemClickListener { + void click(int position); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureHeightTraverseAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureHeightTraverseAdapter.java new file mode 100644 index 0000000..7b9d85a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureHeightTraverseAdapter.java @@ -0,0 +1,98 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IAdapter; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.IMeasureCache; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; + +import java.util.Objects; + +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolderHeightTraverse; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +/** + * 高程导线数据适配器 + */ +public class MeasureHeightTraverseAdapter extends RecyclerView.Adapter + implements IAdapter, IDistanceTypeChangeListener { + + private final IMeasureCache cachedData; + private final ISurveyorData surveyorData; + private final ICycleRecorder cycleRecorder; + private boolean showSlopDistance = true; + private final String stationId; + private final int typeBackOrFront;//区分后视还是前视 + + + public MeasureHeightTraverseAdapter( + String stationId, + IMeasureCache cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData, + int typeBackOrFront) { + this.stationId = stationId; + this.cachedData = cachedData; + this.surveyorData = surveyorData; + this.cycleRecorder = cycleRecorder; + this.typeBackOrFront = typeBackOrFront; + //注册数据监听 + cachedData.register(this); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return Objects.requireNonNull(ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.heightTraverseSurveyor)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + SurveyorDataViewHolderHeightTraverse viewHolder = (SurveyorDataViewHolderHeightTraverse) holder; + viewHolder.setup(position, + stationId, + showSlopDistance, + (ICachedData) cachedData, + cycleRecorder, + surveyorData); + + holder.itemView.setOnClickListener(v -> { + if (iItemClickListener != null) { + iItemClickListener.click(position); + } + }); + } + + @Override + public int getItemCount() { + return cachedData.pointCount(); + } + + @Override + public void onDataChange() { + notifyDataSetChanged(); + } + + @Override + public void onShowSlopDistance(boolean value) { + this.showSlopDistance = value; + } + + + private IItemClickListener iItemClickListener; + + public void setOnItemClickListener(IItemClickListener iItemClickListener) { + this.iItemClickListener = iItemClickListener; + } + + public interface IItemClickListener { + void click(int position); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/MultipleSelectableIndexWithTextAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/MultipleSelectableIndexWithTextAdapter.java new file mode 100644 index 0000000..ae6dc00 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/MultipleSelectableIndexWithTextAdapter.java @@ -0,0 +1,71 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.widget.ImageView; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; + +public class MultipleSelectableIndexWithTextAdapter> extends IndexWithTextAdapter { + private final List selectedIds = new ArrayList<>(); + + public MultipleSelectableIndexWithTextAdapter(List selectedIds, + List items, + IOnItemClick callback) { + super(items); + setCallback(item -> { + onItemClicked(item.getId()); + if (callback == null) { + return; + } + callback.onItemClick(item); + }); + this.selectedIds.addAll(selectedIds); + } + + protected void onItemClicked(String id) { + if (selectedIds.contains(id)) { + selectedIds.remove(id); + } else { + selectedIds.add(id); + } + notifyDataSetChanged(); + } + + @Override + protected ViewItemType itemType() { + return ViewItemType.indexWithNameSelectable; + } + + @Override + public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + //设置状态 + T t = getItem(position); + if (t == null) { + return; + } + if (holder instanceof IndexTextSelectableViewHolder) { + ImageView iv = ((IndexTextSelectableViewHolder) holder).status; + if (iv != null) { + if (selectedIds.contains(t.getId())) { + iv.setVisibility(View.VISIBLE); + } else { + iv.setVisibility(View.GONE); + } + } + } + } + + public List selectedIds() { + return selectedIds; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/PointRecordAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/PointRecordAdapter.java new file mode 100644 index 0000000..2bf3fc1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/PointRecordAdapter.java @@ -0,0 +1,75 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit; +import com.bingce.controlnetwork.fragment.PointFragment; +import com.bingce.controlnetwork.ui.widget.dialog.LoadingUtil; + +public class PointRecordAdapter extends BaseIndexTextWithContextMenuAdapter { + public PointRecordAdapter(List items, + @NonNull FragmentActivity activity) { + super(items, + item -> editRecord(activity, item), + new ContextMenuDeleteEdit() { + @Override + protected void delete(PointRecord item) { + deletePoint(activity, item); + } + + @Override + protected void edit(PointRecord item) { + editRecord(activity, item); + } + + /** + * 删除点 + * 项目里这个点只要有数据就不能删除 + * + * @param item + */ + private void deletePoint(Context context, PointRecord item) { + LoadingUtil.show(context, null); + + ThreadPoolUtil.execute(() -> { + String msg = PointUtil.getUsedMsg(item.getId()); + if (msg != null) { + ToastUtils.showShort(msg); + dismissLoading(); + return; + } + SurveyorDatabaseFactory + .instance + .getPointDataSource() + .delete(item); + + dismissLoading(); + }); + } + + private void dismissLoading() { + ThreadPoolUtil.executeInMain(LoadingUtil::dismiss); + } + + }); + } + + + private static void editRecord(FragmentActivity activity, PointRecord record) { + PointFragment.edit(activity.getSupportFragmentManager(), + record.projectId, + record.getName(), record.getId(), record.getPointType(), record.getX(), record.getY(), record.getZ()); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java new file mode 100644 index 0000000..9eec0f0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java @@ -0,0 +1,61 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.model.KnownAndUnknownPoints; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlnetwork.R; + +import java.util.List; + +public class PointSelectAdapter extends AbstractPointSelectAdapter { + private final KnownAndUnknownPoints data; + private final List globalPoints; + + public PointSelectAdapter(KnownAndUnknownPoints points, + List globalPoints, + PickPointResult defaultValue, + int maxCount, + Context context) { + super(defaultValue, maxCount, context); + this.data = points; + this.globalPoints = globalPoints; + } + + @Override + public int getGroupCount() { +// return data.groupCount() + 1; + return data.groupCount() ; + } + + @Override + public int getChildrenCount(int groupPosition) { + if (groupPosition >= data.groupCount()) { + if (globalPoints == null) { + return 0; + } + return globalPoints.size(); + } + return data.childrenCount(groupPosition); + } + + @Override + public String getGroup(int groupPosition) { + if (groupPosition >= data.groupCount()) { + return context().getString(R.string.global_control_point); + } + return data.groupName(groupPosition, context()); + } + + @Override + public PointRecord getChild(int groupPosition, int childPosition) { + if (groupPosition >= data.groupCount()) { + if (globalPoints == null) { + return null; + } + return globalPoints.get(childPosition); + } + return data.child(groupPosition, childPosition); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/PrismMagegeAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/PrismMagegeAdapter.java new file mode 100644 index 0000000..74f418d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/PrismMagegeAdapter.java @@ -0,0 +1,94 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.PrismManageViewHolder; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class PrismMagegeAdapter extends BaseAdapter + implements View.OnCreateContextMenuListener { + private IOnItemClick callback; + + private int currentLongPressIndex = -1; + + private final IAdapterContextMenu adapterContextMenu; + + public PrismMagegeAdapter(List items, IOnItemClick callback, IAdapterContextMenu adapterContextMenu) { + super(items); + this.callback = callback; + this.adapterContextMenu = adapterContextMenu; + } + + public void setCallback(IOnItemClick callback) { + this.callback = callback; + } + + @Override + final protected PrismManageViewHolder createVH(@NotNull ViewGroup parent, int viewType) { + View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_prism_manager, parent, false); + PrismManageViewHolder prismManageViewHolder = new PrismManageViewHolder(itemView); + return prismManageViewHolder; + } + + protected boolean clickEnable(int position) { + return true; + } + + @Override + public void onBindViewHolder(final @NotNull PrismManageViewHolder holder, int position) { + //长按出菜单 + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + + PrismRecord item = getItem(position); + + holder.tvName.setText(item.getShowPrismTypeName()); + holder.tvType.setText(item.prismTypeLarge); + + //绝对常数 + holder.tvConstant.setText(item.prismTypeConstant); + + holder.itemView.setOnClickListener(v -> { + if (callback != null && clickEnable(position)) { + callback.onItemClick(item); + } + }); + } + + public interface IOnItemClick { + void onItemClick(T item); + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + if (adapterContextMenu == null) { + return; + } + PrismRecord currentItem = getItem(currentLongPressIndex); + if (currentItem.modify == PrismRecord.MODIFY_DEFAULT) { + 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(menuItemBack -> + adapterContextMenu.onMenuItemClick(currentItem, menuItemBack)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/ProjectListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/ProjectListAdapter.java new file mode 100644 index 0000000..33c0f1c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/ProjectListAdapter.java @@ -0,0 +1,28 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.util.IUIRunner; + +import java.util.ArrayList; + +import com.bingce.controlnetwork.adapter.contextmenu.ProjectAdapterContextMenu; + +public class ProjectListAdapter extends BaseIndexTextWithContextMenuAdapter + implements IUpdateListAdapter { + + public ProjectListAdapter(IOnItemClick callback, + @NonNull Context context, + @NonNull IUIRunner iuiRunner, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull FragmentManager fragmentManager) { + super(new ArrayList<>(), + callback, + new ProjectAdapterContextMenu(context, iuiRunner, lifecycleOwner, fragmentManager)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/ReSurveyorCycleAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/ReSurveyorCycleAdapter.java new file mode 100644 index 0000000..180f5fe --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/ReSurveyorCycleAdapter.java @@ -0,0 +1,56 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import java.util.List; + +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +public class ReSurveyorCycleAdapter extends BaseAdapter, IndexTextSelectableViewHolder> { + + private final List> dataList; + private final ICallBack callBack; + + private int selectPosition = -1; + + public ReSurveyorCycleAdapter(List> dataList, ICallBack callBack) { + super(dataList); + this.dataList = dataList; + this.callBack = callBack; + } + + @Override + protected IndexTextSelectableViewHolder createVH(@NonNull ViewGroup parent, int viewType) { + return (IndexTextSelectableViewHolder) ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.indexWithNameSelectable); + } + + @Override + public void onBindViewHolder(@NonNull IndexTextSelectableViewHolder holder, int position) { + holder.index.setVisibility(View.GONE); + holder.name.setText(dataList.get(position).getName()); + + if (position == selectPosition) { + holder.status.setVisibility(View.VISIBLE); + } else { + holder.status.setVisibility(View.GONE); + } + + holder.itemView.setOnClickListener(v -> { + selectPosition = holder.getAbsoluteAdapterPosition(); + notifyItemRangeChanged(0, dataList.size()); + callBack.back(selectPosition); + }); + } + + public interface ICallBack { + void back(int cycleIndex); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/ResurveyorPointsAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/ResurveyorPointsAdapter.java new file mode 100644 index 0000000..c22efe4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/ResurveyorPointsAdapter.java @@ -0,0 +1,61 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsFragment; + +public class ResurveyorPointsAdapter extends MultipleSelectableIndexWithTextAdapter { + private final FragmentManager fragmentManager; + private final LifecycleOwner lifecycleOwner; + private final Context context; + + public ResurveyorPointsAdapter(List selectedIds, + List items, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner) { + super(selectedIds, items, null); + this.fragmentManager = fragmentManager; + this.lifecycleOwner = lifecycleOwner; + this.context = context; + } + + @Override + protected void onItemClicked(String id) { + //判断上限数据 + if (!selectedIds().contains(id)) { + if (selectedIds().size() + 1 > getItemCount() / 3) { + TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, + context.getString(R.string.tips_resurveyor_count_exceed_1_3)); + return; + } + } + if (getItem(0) != null && getItem(0).getId().equals(id)) { + ToastUtils.showShort(R.string.tips_resurveyor_must_select_0_point); + return; + } + super.onItemClicked(id); + } + + public static class Item extends UniversalListItem { + public Item(String name, String id) { + super(name, id, null); + } + + @Override + public ViewItemType getType() { + return null; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SelectableIndexWithTextAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SelectableIndexWithTextAdapter.java new file mode 100644 index 0000000..7f920f9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SelectableIndexWithTextAdapter.java @@ -0,0 +1,99 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.widget.ImageView; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; + +public class SelectableIndexWithTextAdapter> extends IndexWithTextAdapter { + private String selectedId; + private final List enableList = new ArrayList<>(); + + public SelectableIndexWithTextAdapter(String selectedId, List items, List enableIndex, IOnItemClick callback) { + super(items); + setCallback(item -> { + updateCurrentSelectedId(item.getId()); + if (callback == null) { + return; + } + callback.onItemClick(item); + }); + if (enableIndex != null) { + enableList.addAll(enableIndex); + } + this.selectedId = selectedId; + } + + public SelectableIndexWithTextAdapter(String selectedId, List items, IOnItemClick callback) { + this(selectedId, items, null, callback); + } + + protected void updateCurrentSelectedId(String id) { + selectedId = id; + notifyDataSetChanged(); + } + + // @Override +// protected RecyclerView.ViewHolder createVH(@NotNull ViewGroup parent, int viewType) { +// return ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewFactory.ItemType.indexWithNameSelectable); +// } + @Override + protected ViewItemType itemType() { + return ViewItemType.indexWithNameSelectable; + } + + @Override + protected boolean clickEnable(int position) { + if (enableList.isEmpty() || enableList.contains(String.valueOf(position))) { + return super.clickEnable(position); + } + return false; + } + + @Override + public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + //设置状态 + T t = getItem(position); + if (t == null) { + return; + } + if (holder instanceof IndexTextSelectableViewHolder) { + ImageView iv = ((IndexTextSelectableViewHolder) holder).status; + if (iv != null) { + if (t.getId().equals(selectedId)) { + iv.setVisibility(View.VISIBLE); + } else { + iv.setVisibility(View.GONE); + } + } + + if (!enableList.isEmpty()) { + if (enableList.contains(String.valueOf(position))) { + ((IndexTextSelectableViewHolder) holder).mask.setVisibility(View.GONE); + ((IndexTextSelectableViewHolder) holder).item.setAlpha(1f); + } else { + ((IndexTextSelectableViewHolder) holder).mask.setVisibility(View.VISIBLE); + ((IndexTextSelectableViewHolder) holder).item.setAlpha(.5f); + } + } + } + } + + protected String currentSelectedItemId() { + return selectedId; + } + + protected boolean isItemSelected(int index) { + return currentSelectedItemId().equals(getItem(index).getId()); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SpinnerAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SpinnerAdapter.java new file mode 100644 index 0000000..c3a5219 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SpinnerAdapter.java @@ -0,0 +1,83 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; + +public class SpinnerAdapter extends BaseAdapter { + + private final Context context; + + private final List lists; + + + public SpinnerAdapter(Context context, List list) { + this.context = context; + this.lists = new ArrayList<>(); + lists.addAll(list); + } + + @Override + public int getCount() { + return lists.size(); + } + + @Override + public String getItem(int position) { + return lists.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + convertView = getConvertView(convertView, parent); + ViewHodler viewHodler = (ViewHodler) convertView.getTag(); + viewHodler.textView.setText(getItem(position)); + return convertView; + } + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + convertView = getConvertView(convertView, parent); + ViewHodler viewHodler = (ViewHodler) convertView.getTag(); + viewHodler.imageView.setVisibility(position == 0 ? View.VISIBLE : View.GONE); + viewHodler.textView.setText(getItem(position)); + return convertView; + } + + + private View getConvertView(View convertView, ViewGroup parent) { + if (convertView == null) { + ViewHodler viewHodler = new ViewHodler(); + convertView = LayoutInflater.from(context).inflate(R.layout.item_spinner_content, parent, false); + viewHodler.textView = convertView.findViewById(R.id.tv); + viewHodler.imageView = convertView.findViewById(R.id.ivArrow); + convertView.setTag(viewHodler); + } + return convertView; + } + + private class ViewHodler { + public TextView textView; + public ImageView imageView; + } + + public void setLists(List lists) { + this.lists.clear(); + this.lists.addAll(lists); + notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorPeriodAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorPeriodAdapter.java new file mode 100644 index 0000000..a581d91 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorPeriodAdapter.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.adapter; + +import android.os.Bundle; + +import androidx.fragment.app.DialogFragment; + +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; + +import java.util.ArrayList; + +import com.bingce.controlnetwork.adapter.contextmenu.SurveyorPeriodAdapterContextMenu; +import com.bingce.controlnetwork.fragment.BottomSheetSurveyorPeriodFragment; + +public class SurveyorPeriodAdapter extends BaseSelectableIndexTextWithContextMenuAdapter { + public SurveyorPeriodAdapter(String selectedId, DialogFragment fragment) { + super(selectedId, + new ArrayList<>(), + item -> { + Bundle args = new Bundle(); + args.putString(BottomSheetSurveyorPeriodFragment.KEY_RESULT_ID, item.getValue()); + args.putString(BottomSheetSurveyorPeriodFragment.KEY_RESULT_NAME, item.getName()); + fragment.getParentFragmentManager().setFragmentResult(BottomSheetSurveyorPeriodFragment.KEY_REQUEST_TIME, args); + fragment.dismiss(); + }, + new SurveyorPeriodAdapterContextMenu(fragment.getContext(), selectedId, + fragment.getViewLifecycleOwner(), fragment.getChildFragmentManager())); + } + + public void changeCurrentSelect(String id) { + updateCurrentSelectedId(id); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationListAdapter.java new file mode 100644 index 0000000..6c026c6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationListAdapter.java @@ -0,0 +1,287 @@ +package com.bingce.controlnetwork.adapter; + + +import static com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord.isLineStation; + +import android.content.Context; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.LiveData; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.ISurveyorRecordDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuEdit; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationdetail.SingleStationDetailAndEditFragment; +import com.bingce.controlnetwork.util.SurveyorStationUtil; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SurveyorStationListAdapter extends BaseIndexPrefixTextWithContextMenuAdapter { + private final LifecycleOwner lifecycleOwner; + + public SurveyorStationListAdapter(List items, + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner, + Context context, + IOnItemClick itemClick, + boolean editAble) { + super(items, itemClick, + contextMenu(fragmentManager, lifecycleOwner, iuiRunner, context, editAble)); + this.lifecycleOwner = lifecycleOwner; + } + + @Override + protected void onSetName(TextView nameTextView, SurveyorStationRecord item) { + String pointId = item.getItems().get(0).getPointId(); + nameTextView.setText(cachedId2Name.get(pointId)); + + if (item.getItems() == null || item.getItems().isEmpty()) { + return; + } + //停止原livedata订阅 + Object tag = nameTextView.getTag(); + LiveData pointRecordLiveData; + if (tag instanceof LiveData) { + pointRecordLiveData = (LiveData) tag; + pointRecordLiveData.removeObservers(lifecycleOwner); + } + //创建新订阅 + pointRecordLiveData = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findById(pointId); + nameTextView.setTag(pointRecordLiveData); + + //监听 + pointRecordLiveData.observe(lifecycleOwner, pointRecord -> { + if (pointRecord == null) { + return; + } + nameTextView.setText(pointRecord.getName()); + cachedId2Name.put(pointRecord.id, pointRecord.getName()); + }); + } + + @Override + protected void onSetPrefix(TextView prefixTextView, SurveyorStationRecord item) { + String lineId = item.getLineId(); + if (cachedId2LineName.containsKey(lineId)) { + prefixTextView.setText(cachedId2LineName.get(lineId)); + } else { + prefixTextView.setText(StationUtil.mulCycleAngleStationPrefix()); + } + + if (lineId == null || lineId.isEmpty()) { + return; + } + //停止原livedata订阅 + Object tag = prefixTextView.getTag(); + LiveData lineRecordLiveData; + if (tag instanceof LiveData) { + lineRecordLiveData = (LiveData) tag; + lineRecordLiveData.removeObservers(lifecycleOwner); + } + //创建新订阅 + lineRecordLiveData = SurveyorDatabaseFactory + .instance + .getLineRecordDatabase() + .liveData(lineId); + prefixTextView.setTag(lineRecordLiveData); + + //监听 + lineRecordLiveData.observe(lifecycleOwner, lineRecord -> { + if (lineRecord == null) { + return; + } + prefixTextView.setText(lineRecord.name + "-"); + cachedId2LineName.put(lineRecord.id, lineRecord.name); + cachedId2LineType.put(lineRecord.id, lineRecord.type); + }); + } + + private static final Map cachedId2Name = new HashMap<>(); + private static final Map cachedId2LineName = new HashMap<>(); + private static final Map cachedId2LineType = new HashMap<>(); + + private static ContextMenuEdit contextMenu( + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner, + Context context, + boolean editAble) { + if (!editAble) { + return null; + } + return new ContextMenuEdit() { + @Override + protected void edit(SurveyorStationRecord item) { + if (SurveyorStationRecord.isLineWell(cachedId2LineType.get(item.getLineId()))) { + TipsWith2OptionFragment.tips(fragmentManager, lifecycleOwner, + context.getString(R.string.button_edit_station), + context.getString(R.string.button_delete_station), + context.getString(R.string.tips_select_default_station_operator_well), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + SurveyorStationUtil.editLine(context, item.getLineId()); + } + + @Override + public void onCancel() { + try2DeleteLine(item.getLineId(), context, fragmentManager, lifecycleOwner, iuiRunner); + } + }); + return; + } + + + //检测是否属于导线测量 + if (isLineStation(item.getLineId())) { + String lineId = item.getLineId(); + TipsWith2OptionFragment.tips(fragmentManager, lifecycleOwner, + context.getString(R.string.button_edit_line), + context.getString(R.string.button_delete_line), + context.getString(R.string.tips_forbid_delete_station_because_batch), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + try2EditLine(lineId, context, fragmentManager, lifecycleOwner, iuiRunner); + } + + @Override + public void onCancel() { + try2DeleteLine(lineId, context, fragmentManager, lifecycleOwner, iuiRunner); + } + }); + } else { + TipsWith2OptionFragment.tips(fragmentManager, lifecycleOwner, + context.getString(R.string.button_edit_station), + context.getString(R.string.button_delete_station), + context.getString(R.string.tips_select_default_station_operator), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + ThreadPoolUtil.execute(() -> { + String stationName = StationUtil.getStationName(item); + String lineType = StationUtil.getLineTypeFromStation(item); + SingleStationDetailAndEditFragment.start(context, item.getId(), stationName, item.getProjectId(), lineType); + }); + } + + @Override + public void onCancel() { + String stationId = item.getId(); + try2DeleteStation(stationId, context, fragmentManager, lifecycleOwner, iuiRunner); + } + }); + } + } + }; + } + + @WorkerThread + private static boolean isStationHasData(String stationId) { + ISurveyorRecordDataSource surveyorRecordDataSource = + SurveyorDatabaseFactory.instance.getSurveyorRecordDataSource(); + return surveyorRecordDataSource.recordCount(stationId) > 0; + } + + @WorkerThread + private static boolean isLineHasData(String lineId) { + boolean lineHasData = Tools.isLineHasData(lineId); +// ISurveyorStationDataSource stationDataSource = +// SurveyorDatabaseFactory.instance.getSurveyorStation(); +// List stationRecordList = stationDataSource.getDataListByLine(lineId); +// if (stationRecordList == null || stationRecordList.isEmpty()) { +// return false; +// } +// ISurveyorRecordDataSource surveyorRecordDataSource = +// SurveyorDatabaseFactory.instance.getSurveyorRecordDataSource(); +// boolean hasData = false; +// for (SurveyorStationRecord stationRecord : stationRecordList) { +// if (stationRecord == null) { +// continue; +// } +// if (surveyorRecordDataSource.recordCount(stationRecord.getId()) <= 0) { +// continue; +// } +// hasData = true; +// break; +// } + return lineHasData; + } + + public static void try2DeleteLine(String lineId, Context context, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner) { + ThreadPoolUtil.execute(() -> { + if (isLineHasData(lineId)) { + iuiRunner.runOnUI(() -> TipsFragment.cancelAbleTips(fragmentManager, lifecycleOwner, context, + context.getString(R.string.tips_is_sure_to_delete_line_with_record), + 4, + () -> SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .deleteByLineId(lineId))); + } else { + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .deleteByLineId(lineId); + } + }); + } + + public static void try2EditLine(String lineId, Context context, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner) { + ThreadPoolUtil.execute(() -> { + if (isLineHasData(lineId)) { + iuiRunner.runOnUI(() -> TipsFragment.cancelAbleTips(fragmentManager, lifecycleOwner, context, + context.getString(R.string.tips_is_sure_to_edit_line_with_record), + 4, + () -> SurveyorStationUtil.editLine(context, lineId))); + } else { + SurveyorStationUtil.editLine(context, lineId); + } + }); + } + + public static void try2DeleteStation(String stationId, Context context, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner) { + ThreadPoolUtil.execute(() -> { + if (isStationHasData(stationId)) { + iuiRunner.runOnUI(() -> TipsFragment.cancelAbleTips(fragmentManager, lifecycleOwner, context, + context.getString(R.string.tips_is_sure_to_delete_station_with_record), + 4, + () -> SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .deleteById(stationId))); + } else { + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .deleteById(stationId); + } + }); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationRecordsAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationRecordsAdapter.java new file mode 100644 index 0000000..61ff774 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationRecordsAdapter.java @@ -0,0 +1,77 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IAdapter; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; + +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +/* + * 测量记录adapter + * */ +public class SurveyorStationRecordsAdapter extends RecyclerView.Adapter + implements IAdapter, IDistanceTypeChangeListener { + private final ICachedData cachedData; + private final ISurveyorData surveyorData; + private final ICycleRecorder cycleRecorder; + private boolean showSlopDistance = true; + private final String stationId; + + public SurveyorStationRecordsAdapter( + String stationId, + ICachedData cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData) { + this.stationId = stationId; + this.cachedData = cachedData; + this.surveyorData = surveyorData; + this.cycleRecorder = cycleRecorder; + //注册数据监听 + cachedData.register(this); + } + + @NonNull + @NotNull + @Override + public SurveyorDataViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder vh = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.surveyorStationPointItem); + assert vh != null; + return (SurveyorDataViewHolder) vh; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull SurveyorDataViewHolder holder, int position) { + holder.setup(position, + stationId, + showSlopDistance, + cachedData, + cycleRecorder, + surveyorData); + } + + @Override + public int getItemCount() { + return cachedData.pointCount(); + } + + @Override + public void onDataChange() { + notifyItemRangeChanged(0, getItemCount()); + } + + @Override + public void onShowSlopDistance(boolean value) { + this.showSlopDistance = value; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/TitleWithSubtitleAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/TitleWithSubtitleAdapter.java new file mode 100644 index 0000000..caac1da --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/TitleWithSubtitleAdapter.java @@ -0,0 +1,76 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IUniversalListItemWithTitleAndSubtitle; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.TitleWithSubtitleViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class TitleWithSubtitleAdapter> + extends RecyclerView.Adapter { + + private final List mValues; + private final TitleWithSubtitleAdapter.IOnItemClick callback; + + public TitleWithSubtitleAdapter(List items, TitleWithSubtitleAdapter.IOnItemClick callback) { + mValues = items; + this.callback = callback; + } + + public void updateData(List list) { + if (mValues != null) { + mValues.clear(); + } + if (list != null) { + mValues.addAll(list); + } + notifyDataSetChanged(); + } + + protected RecyclerView.ViewHolder createVH(@NotNull ViewGroup parent, int viewType) { + return ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.titleWithSubtitle); + } + + @Override + public @NotNull + TitleWithSubtitleViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder viewHolder = createVH(parent, viewType); + assert viewHolder != null; + return (TitleWithSubtitleViewHolder) viewHolder; + } + + protected T getItem(int position) { + return mValues.get(position); + } + + @Override + public void onBindViewHolder(final TitleWithSubtitleViewHolder holder, int position) { + T item = getItem(position); + holder.title.setText(item.getTitle()); + holder.subTitle.setText(item.getSubtitle()); + holder.itemView.setOnClickListener(v -> { + if (callback != null) { + callback.onItemClick(item); + } + }); + } + + @Override + public int getItemCount() { + if (mValues == null) { + return 0; + } + return mValues.size(); + } + + public interface IOnItemClick> { + void onItemClick(T item); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java new file mode 100644 index 0000000..777b4ba --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java @@ -0,0 +1,136 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.interfacee.IProjectTolerance; +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.util.NumUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.vh.GroupParentViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyBoolViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyValueViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +import java.util.Arrays; +import java.util.List; + +/* + * 限差详情adapter + * */ +public class ToleranceDetailAdapter extends BaseExpandableListAdapter { + private IProjectTolerance data; + private static final List childTypes = + Arrays.asList( + ViewItemType.nameWithBool, + ViewItemType.nameWithText); + + public ToleranceDetailAdapter(IProjectTolerance limit) { + data = limit; + } + + public void updateData(IProjectTolerance limit) { + this.data = limit; + notifyDataSetChanged(); + } + + @Override + public int getGroupCount() { + return data.groupCount(); + } + + @Override + public int getChildrenCount(int groupPosition) { + return data.childrenCount(groupPosition); + } + + @Override + public String getGroup(int groupPosition) { + return data.groupName(groupPosition); + } + + @Override + public UniversalListItem getChild(int groupPosition, int childPosition) { + return data.child(groupPosition, childPosition); + } + + @Override + public long getGroupId(int groupPosition) { + return groupPosition; + } + + @Override + public long getChildId(int groupPosition, int childPosition) { + return groupPosition * 10L + childPosition; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { + GroupParentViewHolder viewHolder = null; + if (convertView == null) { + convertView = ViewFactory.generatorView(parent.getContext(), parent, ViewItemType.groupParent); + viewHolder = new GroupParentViewHolder(convertView); + convertView.setTag(viewHolder); + } else { + viewHolder = (GroupParentViewHolder) convertView.getTag(); + } + if (viewHolder != null) { + String groupName = getGroup(groupPosition); + if (viewHolder.name != null) { + viewHolder.name.setText(groupName); + } + if (viewHolder.expandIcon != null) { + viewHolder.expandIcon.setImageResource(isExpanded ? R.drawable.ic_arrow_up : R.drawable.ic_arrow_down); + } + } + return convertView; + } + + @Override + public int getChildTypeCount() { + return childTypes.size(); + } + + @Override + public int getChildType(int groupPosition, int childPosition) { + return childTypes.indexOf(getChild(groupPosition, childPosition).getType()); + } + + @Override + public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { + UniversalListItem item = getChild(groupPosition, childPosition); + RecyclerView.ViewHolder viewHolder = null; + if (convertView == null) { + viewHolder = ViewFactory.generatorViewHolder(parent.getContext(), parent, item.getType()); + convertView = viewHolder.itemView; + convertView.setTag(viewHolder); + } else { + viewHolder = (RecyclerView.ViewHolder) convertView.getTag(); + } + if (viewHolder instanceof KeyValueViewHolder) { + KeyValueViewHolder kvHolder = (KeyValueViewHolder) viewHolder; + kvHolder.key.setText(item.getName()); + kvHolder.value.setText(NumUtil.formatScientificNotation(item.getValue().toString())); + } else if (viewHolder instanceof KeyBoolViewHolder) { + KeyBoolViewHolder kvHolder = (KeyBoolViewHolder) viewHolder; + kvHolder.key.setText(item.getName()); + kvHolder.checkBox.setChecked((Boolean) item.getValue()); + } + return convertView; + } + + @Override + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDelete.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDelete.java new file mode 100644 index 0000000..9a8331d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDelete.java @@ -0,0 +1,28 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.view.MenuItem; + +import com.bingce.controlnetwork.R; + +public abstract class ContextMenuDelete implements IAdapterContextMenu { + @Override + public int menuItemSize() { + return 1; + } + + @Override + public int menuItemName(int index) { + return R.string.menu_delete; + } + + @Override + final public boolean onMenuItemClick(T item, MenuItem menuItem) { + if (menuItem.getItemId() == 0) { + delete(item); + return true; + } + return false; + } + + protected abstract void delete(T item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDeleteEdit.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDeleteEdit.java new file mode 100644 index 0000000..74d807f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDeleteEdit.java @@ -0,0 +1,37 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.view.MenuItem; + +import com.bingce.controlnetwork.R; + +public abstract class ContextMenuDeleteEdit implements IAdapterContextMenu { + @Override + final public int menuItemSize() { + return 2; + } + + @Override + final public int menuItemName(int index) { + if (index == 0) { + return R.string.menu_delete; + } + return R.string.menu_edit; + } + + @Override + final public boolean onMenuItemClick(T item, MenuItem menuItem) { + if (menuItem.getItemId() == 0) { + delete(item); + return true; + } + if (menuItem.getItemId() == 1) { + edit(item); + return true; + } + return false; + } + + protected abstract void delete(T item); + + protected abstract void edit(T item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuEdit.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuEdit.java new file mode 100644 index 0000000..dab433c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuEdit.java @@ -0,0 +1,28 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.view.MenuItem; + +import com.bingce.controlnetwork.R; + +public abstract class ContextMenuEdit implements IAdapterContextMenu { + @Override + public int menuItemSize() { + return 1; + } + + @Override + public int menuItemName(int index) { + return R.string.menu_edit; + } + + @Override + final public boolean onMenuItemClick(T item, MenuItem menuItem) { + if (menuItem.getItemId() == 0) { + edit(item); + return true; + } + return false; + } + + protected abstract void edit(T item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/IAdapterContextMenu.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/IAdapterContextMenu.java new file mode 100644 index 0000000..4754b32 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/IAdapterContextMenu.java @@ -0,0 +1,14 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.view.MenuItem; + +import androidx.annotation.StringRes; + +public interface IAdapterContextMenu { + int menuItemSize(); + + @StringRes + int menuItemName(int index); + + boolean onMenuItemClick(T item, MenuItem menuItem); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ProjectAdapterContextMenu.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ProjectAdapterContextMenu.java new file mode 100644 index 0000000..bcb5494 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ProjectAdapterContextMenu.java @@ -0,0 +1,49 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.ProjectHelper; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.util.IUIRunner; + +import com.bingce.controlnetwork.fragment.projectedit.AbstractProjectEditFragment; + +public class ProjectAdapterContextMenu extends ContextMenuDeleteEdit { + private @NonNull + final FragmentManager fragmentManager; + private @NonNull + final Context context; + private final @NonNull + IUIRunner iuiRunner; + private final @NonNull + LifecycleOwner lifecycleOwner; + + private final ProjectHelper projectHelper; + + public ProjectAdapterContextMenu( + @NonNull Context context, + @NonNull IUIRunner iuiRunner, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull FragmentManager fragmentManager) { + this.fragmentManager = fragmentManager; + this.context = context; + this.iuiRunner = iuiRunner; + this.lifecycleOwner = lifecycleOwner; + projectHelper = new ProjectHelper(lifecycleOwner.getLifecycle()); + } + + @Override + protected void delete(ProjectRecord item) { + projectHelper.deleteProject(fragmentManager, lifecycleOwner, context, item); + } + + @Override + protected void edit(ProjectRecord item) { + AbstractProjectEditFragment.editProject(fragmentManager, context, item.getId(), item.getProjectTypeFault(), + item.getToleranceId(), item.getProjectName()); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/SurveyorPeriodAdapterContextMenu.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/SurveyorPeriodAdapterContextMenu.java new file mode 100644 index 0000000..441b054 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/SurveyorPeriodAdapterContextMenu.java @@ -0,0 +1,84 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +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.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.fragment.StringInputFragment; +import com.bingce.utils.ThreadPoolUtil; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.StringInputFragment; + +public class SurveyorPeriodAdapterContextMenu extends ContextMenuDeleteEdit { + private @NonNull + final LifecycleOwner lifecycleOwner; + private @NonNull + final FragmentManager fragmentManager; + private final String selectedId; + private final Context context; + + public SurveyorPeriodAdapterContextMenu(Context context, String selectedId, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull FragmentManager fragmentManager) { + this.context = context; + this.selectedId = selectedId; + this.lifecycleOwner = lifecycleOwner; + this.fragmentManager = fragmentManager; + } + + @Override + protected void delete(SurveyorPeriodRecord item) { + String id = item.getId(); + if (selectedId.equals(id)) { + ToastUtils.showShort(Tools.getString(R.string.current_period_selected_not_delete)); + } else { + SurveyorDatabaseFactory + .instance + .getSurveyorPeriod() + .deleteById(id); + //检测是否需要修改默认测期 + ThreadPoolUtil.execute(new Runnable() { + @Override + public void run() { + IConfigDataSource configDataSource = + SurveyorDatabaseFactory + .instance.getConfigDataSource(); + ConfigRecord configRecord = configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_PERIOD_ID); + if (configRecord != null && id.equals(configRecord.getConfigValue())) { + configDataSource.set(ConfigConstants.KEY_DEFAULT_PERIOD_ID, selectedId); + } + } + }); + } + } + + @Override + protected void edit(SurveyorPeriodRecord item) { + StringInputFragment + .input( + fragmentManager, + Tools.getString(R.string.modify_period_name), + item.getName(), + lifecycleOwner, + string -> { + if (string != null && !string.isEmpty()) { + item.setName(string); + SurveyorDatabaseFactory + .instance + .getSurveyorPeriod() + .saveRecord(item); + } + }); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/BaseStationDetailAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/BaseStationDetailAdapter.java new file mode 100644 index 0000000..bd0419e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/BaseStationDetailAdapter.java @@ -0,0 +1,227 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.text.TextUtils; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import java.util.ArrayList; +import java.util.List; + +public abstract class BaseStationDetailAdapter extends AbstractDraggableRecycleViewAdapter { + private final boolean adjustable; + private final IOnSelectPointDelegate selectPointCallback; + + protected BaseStationDetailAdapter(IOnSelectPointDelegate selectPointCallback, + List items, + boolean adjustable) { + super(items); + this.adjustable = adjustable; + this.selectPointCallback = selectPointCallback; + } + + public void setStationPoint(String id, String name) { + StationDetailItem item = getItem(1); + if (item != null) { + if (StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType())) { + setItem(1, new StationDetailItem( + name, StationDetailItem.ITEM_TYPE_STATION_ITEM, id)); + notifyItemChanged(1); + } else { + StationDetailItem newInstance = new StationDetailItem( + name, StationDetailItem.ITEM_TYPE_STATION_ITEM, id); + insert(1, newInstance); + notifyItemInserted(1); + } + } + } + + public void setSurveyorPoint(List ids, List names) { + List items = new ArrayList<>(); + for (int index = 0; index < ids.size(); index++) { + StationDetailItem item = new StationDetailItem( + names.get(index), StationDetailItem.ITEM_TYPE_POINT_ITEM, ids.get(index)); + items.add(item); + } + if (items == null || items.isEmpty()) { + return; + } + for (int i = getItemCount() - 1; i >= 0; i--) { + StationDetailItem item = getItem(i); + if (TextUtils.equals(item.getType(), StationDetailItem.ITEM_TYPE_POINT_ITEM)) { + remove(item); + } + } + insertAll(items); + notifyDataSetChanged(); + } + + private StationDetailItem getStationItem() { + StationDetailItem o = getItem(1); + if (o != null && StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(o.getType())) { + return o; + } + return null; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof DraggableTextViewHolder) { + DraggableTextViewHolder draggableTextViewHolder = (DraggableTextViewHolder) viewHolder; + DraggableTextViewHolder.update(draggableTextViewHolder, item, adjustable); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder = ((StationGroupItemViewHolder) viewHolder); + StationGroupItemViewHolder.update( + surveyorStationSetupGroupParentViewHolder, + item, + adjustable, + (itemType, surveyorStationSetupGroupParentViewHolder1) -> { + if (StationDetailItem.ITEM_TYPE_STATION_GROUP.equals(item.getType())) { + View.OnClickListener listener = v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + StationDetailItem stationItem = getStationItem(); + if (stationItem != null) { + pickPointResult.getSelectedIds().add(stationItem.getOriginalPointId()); + pickPointResult.getSelectedNames().add(stationItem.getName()); + } + ArrayList filters = new ArrayList<>(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_POINT_ITEM.equals(obj.getType())) { + filters.add(obj.getOriginalPointId()); + } + } + selectPointCallback.onSelectStationPoint(pickPointResult, filters); + } + }; + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(listener); + surveyorStationSetupGroupParentViewHolder1.switchView.setOnClickListener(listener); + StationDetailItem stationItem = getStationItem(); + if (stationItem != null) { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.INVISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.VISIBLE); + } else { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.VISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.INVISIBLE); + } + } else if (StationDetailItem.ITEM_TYPE_POINT_GROUP.equals(item.getType())) { + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem o = getItem(index); + if (o == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_POINT_ITEM.equals(o.getType())) { + pickPointResult.getSelectedIds().add(o.getOriginalPointId()); + pickPointResult.getSelectedNames().add(o.getName()); + } + } + String filterId = ""; + StationDetailItem filter = getStationItem(); + if (filter != null) { + filterId = filter.getOriginalPointId(); + } + ArrayList filters = new ArrayList<>(); + if (!filterId.isEmpty()) { + filters.add(filterId); + } + selectPointCallback.onSelectSurveyorPoint(pickPointResult, filters); + } + }); + } + }); + } + } + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.ITEM_TYPE_POINT_GROUP.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_STATION_GROUP.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } + return super.getItemViewType(position); + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (!adjustable || item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_STATION_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (!adjustable || item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_STATION_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_POINT_GROUP.equals(item.getType()); + } + + public List collectData() { + List stationItems = new ArrayList<>(); + for (int index = 0; index < getItemCount(); index++) { + StationDetailItem item = getItem(index); + if (item == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType())) { + SurveyorPoint stationItem = new SurveyorPoint(); + stationItem.setOriginalPointId(item.getOriginalPointId()); + stationItem.setType(SurveyorPoint.TYPE_STATION); + stationItems.add(stationItem); + } else if (StationDetailItem.ITEM_TYPE_POINT_ITEM.equals(item.getType())) { + SurveyorPoint stationItem = new SurveyorPoint(); + stationItem.setOriginalPointId(item.getOriginalPointId()); + stationItem.setType(SurveyorPoint.TYPE_POINT); + stationItems.add(stationItem); + } + } + return stationItems; + } + + public int surveyorPointSize() { + int size = getItemCount(); + int count = 0; + for (int index = 0; index < size; index++) { + StationDetailItem item = getItem(index); + if (item == null || !StationDetailItem.ITEM_TYPE_POINT_ITEM.equals(item.getType())) { + continue; + } + count++; + } + return count; + } + + public interface IOnSelectPointDelegate { + void onSelectStationPoint(PickPointResult pickPointResult, ArrayList filters); + + void onSelectSurveyorPoint(PickPointResult pickPointResult, ArrayList filters); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/EditableStationDetailAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/EditableStationDetailAdapter.java new file mode 100644 index 0000000..746dff6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/EditableStationDetailAdapter.java @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import java.util.List; + +public class EditableStationDetailAdapter extends BaseStationDetailAdapter { + public EditableStationDetailAdapter(IOnSelectPointDelegate selectPointCallback, List items) { + super(selectPointCallback, items, true); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/NoEditableStationDetailAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/NoEditableStationDetailAdapter.java new file mode 100644 index 0000000..b79df48 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/NoEditableStationDetailAdapter.java @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import java.util.List; + +public class NoEditableStationDetailAdapter extends BaseStationDetailAdapter { + public NoEditableStationDetailAdapter(List items) { + super(null, items, false); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineKnownUnknownKnownAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineKnownUnknownKnownAdapter.java new file mode 100644 index 0000000..bdea324 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineKnownUnknownKnownAdapter.java @@ -0,0 +1,354 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * (复合、无定向)导线创建 known1-unknown-known2格式 + */ +public class StationCreateLineKnownUnknownKnownAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + public StationCreateLineKnownUnknownKnownAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + this.selectPointCallback = selectPointCallback; + } + + public void setKnownPoints1(List ids, List names) { + if (ids == null || names == null || ids.size() != names.size()) { + return; + } + //先移除之前known point + List knownItems = knownItems1(); + for (StationDetailItem item : knownItems) { + remove(item); + } + //添加新的known point + for (int index = 0; index < ids.size(); index++) { + insert( + 1 + index, + new StationDetailItem( + names.get(index), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM1, + ids.get(index))); + } + //通知变化 + if (knownItems.size() == ids.size()) { + notifyItemRangeChanged(1, ids.size()); + } else { + notifyItemRangeChanged(1, getItemCount() - 1); + } + } + + public void setUnknownPoints(List ids, List names) { + if (ids == null || names == null || ids.size() != names.size()) { + return; + } + //先移除之前unknown point + List unknowns = unknownItems(); + for (StationDetailItem item : unknowns) { + remove(item); + } + //搜索unknown-group索引 + int targetIndex = -1; + for (int index = 0; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj != null && StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(obj.getType())) { + targetIndex = index; + break; + } + } + if (targetIndex >= 0) { + //添加新的unknown point + for (int index = 0; index < ids.size(); index++) { + insert( + targetIndex + 1 + index, + new StationDetailItem( + names.get(index), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM, + ids.get(index))); + } + } + //通知变化 + if (unknowns.size() == ids.size()) { + notifyItemRangeChanged(targetIndex + 1, ids.size()); + } else { + notifyItemRangeChanged(targetIndex + 1, getItemCount() - 1); + } + } + + public void setKnownPoints2(List ids, List names) { + if (ids == null || names == null || ids.size() != names.size()) { + return; + } + //搜索known-group2索引 + int targetIndex = -1; + for (int index = 0; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj != null && StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(obj.getType())) { + targetIndex = index; + break; + } + } + List items = new ArrayList<>(); + for (int index = 0; index < ids.size(); index++) { + StationDetailItem item = new StationDetailItem( + names.get(index), StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM2, ids.get(index)); + items.add(item); + } + if (targetIndex > 0) { + replace(targetIndex + 1, items); + notifyItemRangeChanged(targetIndex + 1, items.size()); + } + } + + public List knownItems1() { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM1.equals(obj.getType())) { + break; + } + items.add(obj); + } + return items; + } + + public List unknownItems() { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(obj.getType())) { + continue; + } + items.add(obj); + } + return items; + } + + public List knownItems2() { + List items = new ArrayList<>(); + int targetIndex = -1; + for (int index = getItemCount() - 1; index >= 0; index--) { + StationDetailItem obj = getItem(index); + if (obj != null && StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(obj.getType())) { + targetIndex = index; + break; + } + } + if (targetIndex < 0) { + return items; + } + for (int index = targetIndex + 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM2.equals(obj.getType())) { + break; + } + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof DraggableTextViewHolder) { + DraggableTextViewHolder draggableTextViewHolder = (DraggableTextViewHolder) viewHolder; + DraggableTextViewHolder.update(draggableTextViewHolder, item, true); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder = ((StationGroupItemViewHolder) viewHolder); + StationGroupItemViewHolder.update( + surveyorStationSetupGroupParentViewHolder, + item, + true, + (itemType, surveyorStationSetupGroupParentViewHolder1) -> { + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1.equals(item.getType())) { + View.OnClickListener listener = v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (StationDetailItem obj : knownItems1()) { + pickPointResult.getSelectedIds().add(obj.getOriginalPointId()); + pickPointResult.getSelectedNames().add(obj.getName()); + } + ArrayList filters = new ArrayList<>(); + for (StationDetailItem obj : unknownItems()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + for (StationDetailItem obj : knownItems2()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + selectPointCallback.onSelectKnownPoint1(pickPointResult, filters); + } + }; + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(listener); + surveyorStationSetupGroupParentViewHolder1.switchView.setOnClickListener(listener); + + List knownItems = knownItems1(); + if (knownItems.isEmpty()) { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.VISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.INVISIBLE); + } else { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.INVISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.VISIBLE); + } + } else if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType())) { + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem o = getItem(index); + if (o == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(o.getType())) { + pickPointResult.getSelectedIds().add(o.getOriginalPointId()); + pickPointResult.getSelectedNames().add(o.getName()); + } + } + ArrayList filters = new ArrayList<>(); + for (StationDetailItem obj : knownItems1()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + for (StationDetailItem obj : knownItems2()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + selectPointCallback.onSelectUnknownPoint(pickPointResult, filters); + } + }); + } else if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(item.getType())) { + View.OnClickListener listener = v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (StationDetailItem obj : knownItems2()) { + pickPointResult.getSelectedIds().add(obj.getOriginalPointId()); + pickPointResult.getSelectedNames().add(obj.getName()); + } + ArrayList filters = new ArrayList<>(); + for (StationDetailItem obj : knownItems1()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + for (StationDetailItem obj : unknownItems()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + selectPointCallback.onSelectKnownPoint2(pickPointResult, filters); + } + }; + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(listener); + surveyorStationSetupGroupParentViewHolder1.switchView.setOnClickListener(listener); + + List knownItems = knownItems2(); + if (knownItems.isEmpty()) { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.VISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.INVISIBLE); + } else { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.INVISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.VISIBLE); + } + } + }); + } + } + + private static final int ITEM_TYPE_KNOWN_POINT1 = 11; + private static final int ITEM_TYPE_UNKNOWN_POINT = ITEM_TYPE_KNOWN_POINT1 + 1; + private static final int ITEM_TYPE_KNOWN_POINT2 = ITEM_TYPE_UNKNOWN_POINT + 1; + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM1.equals(item.getType())) { + return ITEM_TYPE_KNOWN_POINT1; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(item.getType())) { + return ITEM_TYPE_UNKNOWN_POINT; + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM2.equals(item.getType())) { + return ITEM_TYPE_KNOWN_POINT2; + } + return super.getItemViewType(position); + } + + @NonNull + @NotNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (ITEM_TYPE_KNOWN_POINT1 == viewType || ITEM_TYPE_UNKNOWN_POINT == viewType || ITEM_TYPE_KNOWN_POINT2 == viewType) { + return super.onCreateViewHolder(parent, ViewItemType.draggableItem.ordinal()); + } + return super.onCreateViewHolder(parent, viewType); + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(item.getType()); + } + + public interface IOnSelectPointDelegate { + void onSelectKnownPoint1(PickPointResult pickPointResult, ArrayList filters); + + void onSelectUnknownPoint(PickPointResult pickPointResult, ArrayList filters); + + void onSelectKnownPoint2(PickPointResult pickPointResult, ArrayList filters); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineSingleAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineSingleAdapter.java new file mode 100644 index 0000000..3d057a8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineSingleAdapter.java @@ -0,0 +1,238 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * 支导线创建 + */ +public class StationCreateLineSingleAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + public StationCreateLineSingleAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + this.selectPointCallback = selectPointCallback; + } + + public void setKnownPoints(List ids, List names) { + if (ids == null || names == null || ids.size() != names.size()) { + return; + } + //先移除之前known point + List knownItems = knownItems(); + for (StationDetailItem item : knownItems) { + remove(item); + } + //添加新的known point + for (int index = 0; index < ids.size(); index++) { + insert( + 1 + index, + new StationDetailItem( + names.get(index), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM, + ids.get(index))); + } + //通知变化 + if (knownItems.size() == ids.size()) { + notifyItemRangeChanged(1, ids.size()); + } else { + notifyItemRangeChanged(1, getItemCount() - 1); + } + } + + public void setUnknownPoints(List ids, List names) { + List items = new ArrayList<>(); + for (int index = 0; index < ids.size(); index++) { + StationDetailItem item = new StationDetailItem( + names.get(index), StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM, ids.get(index)); + items.add(item); + } + + int index = -1; + for (int i = 0; i < getItemCount(); i++) { + StationDetailItem item = getItem(i); + if (item == null || !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType())) { + continue; + } + index = i; + break; + } + if (index > 0) { + replace(index + 1, items); + notifyItemRangeChanged(index + 1, items.size()); + } + } + + public List knownItems() { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM.equals(obj.getType())) { + break; + } + items.add(obj); + } + return items; + } + + public List unknownItems() { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(obj.getType())) { + continue; + } + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof DraggableTextViewHolder) { + DraggableTextViewHolder draggableTextViewHolder = (DraggableTextViewHolder) viewHolder; + DraggableTextViewHolder.update(draggableTextViewHolder, item, true); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder = ((StationGroupItemViewHolder) viewHolder); + StationGroupItemViewHolder.update( + surveyorStationSetupGroupParentViewHolder, + item, + true, + (itemType, surveyorStationSetupGroupParentViewHolder1) -> { + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP.equals(item.getType())) { + View.OnClickListener listener = v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (StationDetailItem obj : knownItems()) { + pickPointResult.getSelectedIds().add(obj.getOriginalPointId()); + pickPointResult.getSelectedNames().add(obj.getName()); + } + ArrayList filters = new ArrayList<>(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(obj.getType())) { + filters.add(obj.getOriginalPointId()); + } + } + selectPointCallback.onSelectKnownPoint(pickPointResult, filters); + } + }; + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(listener); + surveyorStationSetupGroupParentViewHolder1.switchView.setOnClickListener(listener); + + List knownItems = knownItems(); + if (knownItems.isEmpty()) { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.VISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.INVISIBLE); + } else { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.INVISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.VISIBLE); + } + } else if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType())) { + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem o = getItem(index); + if (o == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(o.getType())) { + pickPointResult.getSelectedIds().add(o.getOriginalPointId()); + pickPointResult.getSelectedNames().add(o.getName()); + } + } + ArrayList filters = new ArrayList<>(); + for (StationDetailItem obj : knownItems()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + selectPointCallback.onSelectUnknownPoint(pickPointResult, filters); + } + }); + } + }); + } + } + + private static final int ITEM_TYPE_KNOWN_POINT = 11; + private static final int ITEM_TYPE_UNKNOWN_POINT = ITEM_TYPE_KNOWN_POINT + 1; + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM.equals(item.getType())) { + return ITEM_TYPE_KNOWN_POINT; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(item.getType())) { + return ITEM_TYPE_UNKNOWN_POINT; + } + return super.getItemViewType(position); + } + + @NonNull + @NotNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (ITEM_TYPE_KNOWN_POINT == viewType || ITEM_TYPE_UNKNOWN_POINT == viewType) { + return super.onCreateViewHolder(parent, ViewItemType.draggableItem.ordinal()); + } + return super.onCreateViewHolder(parent, viewType); + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()); + } + + public interface IOnSelectPointDelegate { + void onSelectKnownPoint(PickPointResult pickPointResult, ArrayList filters); + + void onSelectUnknownPoint(PickPointResult pickPointResult, ArrayList filters); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellAdapter.java new file mode 100644 index 0000000..a6cbffa --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellAdapter.java @@ -0,0 +1,301 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.text.TextUtils; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 一井定向-创建站选点的适配器 + */ +public class StationCreateLineWellAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + private final Map groupPositionMap = new HashMap<>(); + private final Map lastSelectMap = new HashMap<>(); + + public StationCreateLineWellAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + for (int i = 0; i < items.size(); i++) { + groupPositionMap.put(items.get(i).getType(), i); + } + this.selectPointCallback = selectPointCallback; + } + + /** + * 设置地面连接方向点数据 + */ + public void setGroundLinkPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK, + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK + StationDetailItem._DATA); + } + + private void setPointsData(PickPointResult pickPointResult, String groupType, String dataType) { + if (pickPointResult == null || pickPointResult.getSelectedIds() == null + || pickPointResult.getSelectedNames() == null + || pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedNames().size()) { + return; + } + //记录选择的 + lastSelectMap.put(groupType, pickPointResult); + + List pointsOld = getPointsFromType(dataType); + removeAll(pointsOld); + + List newList = new ArrayList<>(); + for (int index = 0; index < pickPointResult.getSelectedIds().size(); index++) { + newList.add(new StationDetailItem( + pickPointResult.getSelectedNames().get(index), + dataType, + pickPointResult.getSelectedIds().get(index))); + } + + int insertPosition = groupPositionMap.get(groupType); + insertForWell(insertPosition + 1, newList); + + updateGroupPositionMap(); + + notifyItemRangeChanged(0, getItemCount()); + + } + + /** + * 更新group的基准位置 + */ + private void updateGroupPositionMap() { + for (int i = 0; i < getItemCount(); i++) { + String type = getItem(i).getType(); + if (type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK) + || type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE) + || type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE) + || type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE) + || type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK)) { + groupPositionMap.put(type, i); + } + } + } + + /** + * 设置地面近井点数据 + */ + public void setGroundSidePoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE, + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE + StationDetailItem._DATA); + } + + /** + * 设置钢丝点数据 + */ + public void setSteelWirePoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE, + StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE + StationDetailItem._DATA); + } + + /** + * 设置地下近井点数据 + */ + public void setUndergroudSidePoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE, + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE + StationDetailItem._DATA); + } + + /** + * 设置地下连接方向点数据 + */ + public void setUndergroudLinkPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK, + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK + StationDetailItem._DATA); + } + + + public List getPointsFromType(String dataType) { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !dataType.equals(obj.getType())) { + continue; + } + + if (dataType.contains(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE)) { + obj.setWellSteel(true); + } + + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof ItemWellViewHolder) { + ItemWellViewHolder itemWellViewHolder = (ItemWellViewHolder) viewHolder; + ItemWellViewHolder.update(itemWellViewHolder, item, true, (itemType, itemWellViewHolderBack) -> { +// itemWellViewHolder.switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { +// @Override +// public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { +// item.setWellSteel(isChecked); +// if (selectPointCallback != null) { +// selectPointCallback.onSelectOnlyMeasureHorAngle(isChecked); +// } +// } +// }); + }); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder stationGroupItemViewHolder = ((StationGroupItemViewHolder) viewHolder); + + StationGroupItemViewHolder.update( + stationGroupItemViewHolder, + item, + true, + (itemType, stationGroupItemViewHolderBack) -> { + stationGroupItemViewHolder.pick.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + backToData(itemType, stationGroupItemViewHolderBack); + } + }); + }); + } + } + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } else { + return ViewItemType.wellItem.ordinal(); + } + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE.equals(item.getType()) + && !StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE.equals(item.getType()) + && !StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE.equals(item.getType()) + && !StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE.equals(item.getType()) + && !StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK.equals(item.getType()); + } + + + public void removeItemForLastSelect(int adapterPosition) { + StationDetailItem item = getItem(adapterPosition); + assert item != null; + String groupType = item.getType().replaceAll(StationDetailItem._DATA, ""); + PickPointResult pickPointResult = lastSelectMap.get(groupType); + if (pickPointResult != null && !pickPointResult.getSelectedIds().isEmpty()) { + int index = pickPointResult.getSelectedIds().indexOf(item.getOriginalPointId()); + pickPointResult.getSelectedIds().remove(index); + pickPointResult.getSelectedNames().remove(index); + } else { + lastSelectMap.remove(groupType); + } + updateGroupPositionMap(); +// 原先只有这一句 lastSelectMap.put(item.getType().replaceAll(StationDetailItem._DATA, ""), null); + } + + public interface IOnSelectPointDelegate { + void onSelectGroundLink(PickPointResult pickPointResult, List filters); + + void onSelectGroundSide(PickPointResult pickPointResult, List filters); + + void onSelectSteelWire(PickPointResult pickPointResult, List filters); + + void onSelectUndergroundSide(PickPointResult pickPointResult, List filters); + + void onSelectUndergroundLink(PickPointResult pickPointResult, List filters); + +// void onSelectOnlyMeasureHorAngle(boolean measureHorAngle); + } + + /** + * 返回数据给上一级 + * + * @param itemType + * @param holder + */ + private void backToData(String itemType, StationGroupItemViewHolder holder) { + if (selectPointCallback == null) { + return; + } + + PickPointResult pickPointResult = lastSelectMap.get(itemType); + + List filterIds = getFilterIds(pickPointResult); + + switch (itemType) { + case StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK: + selectPointCallback.onSelectGroundLink(pickPointResult, filterIds); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE: + selectPointCallback.onSelectGroundSide(pickPointResult, filterIds); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE: + selectPointCallback.onSelectSteelWire(pickPointResult, filterIds); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE: + selectPointCallback.onSelectUndergroundSide(pickPointResult, filterIds); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK: + selectPointCallback.onSelectUndergroundLink(pickPointResult, filterIds); + break; + } + } + + private List getFilterIds(PickPointResult pickPointResult) { + List filterIds = new ArrayList<>(); + for (int i = 0; i < getItemCount(); i++) { + StationDetailItem item = getItem(i); + String pointId = item.getOriginalPointId(); + + if (!TextUtils.isEmpty(pointId)) { + if (pickPointResult == null) { + filterIds.add(pointId); + } else { + if (!pickPointResult.getSelectedIds().contains(pointId)) { + filterIds.add(pointId); + } + } + } + } + return filterIds; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleGroundAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleGroundAdapter.java new file mode 100644 index 0000000..9cfea74 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleGroundAdapter.java @@ -0,0 +1,296 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.text.TextUtils; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 二井定向-地上-创建站选点的适配器 + */ +public class StationCreateLineWellDoubleGroundAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + private final Map groupPositionMap = new HashMap<>(); + private final Map lastSelectMap = new HashMap<>(); + + public StationCreateLineWellDoubleGroundAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + for (int i = 0; i < items.size(); i++) { + groupPositionMap.put(items.get(i).getType(), i); + } + this.selectPointCallback = selectPointCallback; + } + + private void setPointsData(PickPointResult pickPointResult, String groupType, String dataType) { + if (pickPointResult == null || pickPointResult.getSelectedIds() == null + || pickPointResult.getSelectedNames() == null + || pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedNames().size()) { + return; + } + //记录选择的 + lastSelectMap.put(groupType, pickPointResult); + + List pointsOld = getPointsFromType(dataType); + removeAll(pointsOld); + + List newList = new ArrayList<>(); + for (int index = 0; index < pickPointResult.getSelectedIds().size(); index++) { + newList.add(new StationDetailItem( + pickPointResult.getSelectedNames().get(index), + dataType, + pickPointResult.getSelectedIds().get(index))); + } + + int insertPosition = groupPositionMap.get(groupType); + insertForWell(insertPosition + 1, newList); + + updateGroupPositionMap(); + + notifyItemRangeChanged(0, getItemCount()); + + } + + /** + * 更新group的基准位置 + */ + private void updateGroupPositionMap() { + for (int i = 0; i < getItemCount(); i++) { + String type = getItem(i).getType(); + if (type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B)) { + groupPositionMap.put(type, i); + } + } + } + + /** + * 设置地面连接点 左 + */ + public void setGroundLinkLeftPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT + StationDetailItem._DATA); + } + + /** + * 设置地面连接点 右 + */ + public void setGroundLinkRightPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT + StationDetailItem._DATA); + } + + /** + * 设置地面连接点 中 + */ + public void setGroundLinkMiddlePoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE + StationDetailItem._DATA); + } + + /** + * 设置地面近井点 A + */ + public void setGroundSideAPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A + StationDetailItem._DATA); + } + + + /** + * 设置地面近井点 B + */ + public void setGroundSideBPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B + StationDetailItem._DATA); + } + + + public List getPointsFromType(String dataType) { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !dataType.equals(obj.getType())) { + continue; + } + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof ItemWellViewHolder) { + ItemWellViewHolder itemWellViewHolder = (ItemWellViewHolder) viewHolder; + ItemWellViewHolder.update(itemWellViewHolder, item, true, (itemType, itemWellViewHolderBack) -> { +// itemWellViewHolder.switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { +// @Override +// public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { +// item.setWellSteel(isChecked); +// if (selectPointCallback!=null) { +// selectPointCallback.onSelectOnlyMeasureHorAngle(isChecked); +// } +// } +// }); + }); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder stationGroupItemViewHolder = ((StationGroupItemViewHolder) viewHolder); + + StationGroupItemViewHolder.update( + stationGroupItemViewHolder, + item, + true, + (itemType, stationGroupItemViewHolderBack) -> { + stationGroupItemViewHolder.pick.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + backToData(itemType, stationGroupItemViewHolderBack); + } + }); + }); + } + } + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } else { + return ViewItemType.wellItem.ordinal(); + } + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) && + !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE.equals(item.getType()) && + !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) && + !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE.equals(item.getType()) && + !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType()); + } + + public void removeItemForLastSelect(int adapterPosition) { + StationDetailItem item = getItem(adapterPosition); + assert item != null; + String groupType = item.getType().replaceAll(StationDetailItem._DATA, ""); + PickPointResult pickPointResult = lastSelectMap.get(groupType); + if (pickPointResult != null && !pickPointResult.getSelectedIds().isEmpty()) { + int index = pickPointResult.getSelectedIds().indexOf(item.getOriginalPointId()); + pickPointResult.getSelectedIds().remove(index); + pickPointResult.getSelectedNames().remove(index); + } else { + lastSelectMap.remove(groupType); + } + updateGroupPositionMap(); + } + + public interface IOnSelectPointDelegate { + void onSelectGroundLinkLeft(PickPointResult pickPointResult, List filters); + + void onSelectGroundLinkRight(PickPointResult pickPointResult, List filters); + + void onSelectGroundLinkMiddle(PickPointResult pickPointResult, List filters); + + void onSelectGroundSideA(PickPointResult pickPointResult, List filters); + + void onSelectGroundSideB(PickPointResult pickPointResult, List filters); + + void onSelectOnlyMeasureHorAngle(boolean measureHorAngle); + + } + + /** + * 返回数据给上一级 + * + * @param itemType + * @param holder + */ + private void backToData(String itemType, StationGroupItemViewHolder holder) { + if (selectPointCallback == null) { + return; + } + + PickPointResult pickPointResult = lastSelectMap.get(itemType); + + List filterIds = getFilterIds(pickPointResult); + + switch (itemType) { + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT: + selectPointCallback.onSelectGroundLinkLeft(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE: + selectPointCallback.onSelectGroundLinkMiddle(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT: + selectPointCallback.onSelectGroundLinkRight(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A: + selectPointCallback.onSelectGroundSideA(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B: + selectPointCallback.onSelectGroundSideB(pickPointResult, filterIds); + break; + } + } + + private List getFilterIds(PickPointResult pickPointResult) { + List filterIds = new ArrayList<>(); + for (int i = 0; i < getItemCount(); i++) { + StationDetailItem item = getItem(i); + String pointId = item.getOriginalPointId(); + + if (!TextUtils.isEmpty(pointId)) { + if (pickPointResult == null) { + filterIds.add(pointId); + } else { + if (!pickPointResult.getSelectedIds().contains(pointId)) { + filterIds.add(pointId); + } + } + } + } + return filterIds; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleUnderGroundAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleUnderGroundAdapter.java new file mode 100644 index 0000000..68a8174 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleUnderGroundAdapter.java @@ -0,0 +1,331 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.os.Handler; +import android.text.TextUtils; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 二井定向-地下-创建站选点的适配器 + */ +public class StationCreateLineWellDoubleUnderGroundAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + private final Map groupPositionMap = new HashMap<>(); + private final Map lastSelectMap = new HashMap<>(); + + public StationCreateLineWellDoubleUnderGroundAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + for (int i = 0; i < items.size(); i++) { + groupPositionMap.put(items.get(i).getType(), i); + } + this.selectPointCallback = selectPointCallback; + } + + private void setPointsData(PickPointResult pickPointResult, String groupType, String dataType) { + if (pickPointResult == null || pickPointResult.getSelectedIds() == null + || pickPointResult.getSelectedNames() == null + || pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedNames().size()) { + return; + } + //记录选择的 + lastSelectMap.put(groupType, pickPointResult); + + List pointsOld = getPointsFromType(dataType); + removeAll(pointsOld); + + List newList = new ArrayList<>(); + for (int index = 0; index < pickPointResult.getSelectedIds().size(); index++) { + newList.add(new StationDetailItem( + pickPointResult.getSelectedNames().get(index), + dataType, + pickPointResult.getSelectedIds().get(index))); + } + + int insertPosition = groupPositionMap.get(groupType); + insertForWell(insertPosition + 1, newList); + updateGroupPositionMap(); + notifyItemRangeChanged(0, getItemCount()); + } + + /** + * 更新group的基准位置 + */ + private void updateGroupPositionMap() { + for (int i = 0; i < getItemCount(); i++) { + String type = getItem(i).getType(); + if (type.equals(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B)) { + groupPositionMap.put(type, i); + } + } + } + + /** + * 设置地面连接点 左 + */ + public void setGroundLinkLeftPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT + StationDetailItem._DATA); + } + + /** + * 设置地面连接点 右 + */ + public void setGroundLinkRightPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT + StationDetailItem._DATA); + } + + /** + * 设置地面近井点 A + */ + public void setGroundSideAPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A + StationDetailItem._DATA); + } + + + /** + * 设置地面近井点 B + */ + public void setGroundSideBPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B + StationDetailItem._DATA); + } + + /** + * 设置钢丝A + */ + public void setSteelAPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A, + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A + StationDetailItem._DATA); + } + + /** + * 设置钢丝B + */ + public void setSteelBPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B, + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B + StationDetailItem._DATA); + } + + /** + * 设置地下连接方向 + */ + public void setUnderGroundLinkPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK, + StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK + StationDetailItem._DATA); + } + + + public List getPointsFromType(String dataType) { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !dataType.equals(obj.getType())) { + continue; + } + + if (dataType.contains(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE)) { + //注意是contains + obj.setWellSteel(true); + } + + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof ItemWellViewHolder) { + ItemWellViewHolder itemWellViewHolder = (ItemWellViewHolder) viewHolder; + ItemWellViewHolder.update(itemWellViewHolder, item, true, (itemType, itemWellViewHolderBack) -> { +// itemWellViewHolder.switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { +// @Override +// public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { +// item.setWellSteel(isChecked); +// if (selectPointCallback != null) { +// selectPointCallback.onSelectOnlyMeasureHorAngle(isChecked); +// } +// } +// }); + }); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder stationGroupItemViewHolder = ((StationGroupItemViewHolder) viewHolder); + + StationGroupItemViewHolder.update( + stationGroupItemViewHolder, + item, + true, + (itemType, stationGroupItemViewHolderBack) -> { + stationGroupItemViewHolder.pick.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + backToData(itemType, stationGroupItemViewHolderBack); + } + }); + }); + } + } + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK.equals(item.getType()) + ) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } else { + return ViewItemType.wellItem.ordinal(); + } + } + + @Override + public boolean isItemSwipeAble(int position) { + return isItemSwipeAbleOrItemDragAble(position); + } + + @Override + public boolean isItemDragAble(int position) { + return isItemSwipeAbleOrItemDragAble(position); + } + + private boolean isItemSwipeAbleOrItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK.equals(item.getType()); + } + + public void removeItemForLastSelect(int adapterPosition) { + StationDetailItem item = getItem(adapterPosition); + assert item != null; + String groupType = item.getType().replaceAll(StationDetailItem._DATA, ""); + PickPointResult pickPointResult = lastSelectMap.get(groupType); + if (pickPointResult != null && !pickPointResult.getSelectedIds().isEmpty()) { + int index = pickPointResult.getSelectedIds().indexOf(item.getOriginalPointId()); + pickPointResult.getSelectedIds().remove(index); + pickPointResult.getSelectedNames().remove(index); + } else { + lastSelectMap.remove(groupType); + } + //延迟更新groupType的位置 + new Handler().postDelayed(() -> updateGroupPositionMap(), 300); + } + + public interface IOnSelectPointDelegate { + void onSelectGroundLinkLeft(PickPointResult pickPointResult, List filters); + + void onSelectGroundLinkRight(PickPointResult pickPointResult, List filters); + + void onSelectGroundSideA(PickPointResult pickPointResult, List filters); + + void onSelectGroundSideB(PickPointResult pickPointResult, List filters); + + void onSelectSteelA(PickPointResult pickPointResult, List filters); + + void onSelectSteelB(PickPointResult pickPointResult, List filters); + + void onSelectUnderGroundLink(PickPointResult pickPointResult, List filters); + + void onSelectOnlyMeasureHorAngle(boolean measureHorAngle); + + } + + /** + * 返回数据给上一级 + * + * @param itemType + * @param holder + */ + private void backToData(String itemType, StationGroupItemViewHolder holder) { + if (selectPointCallback == null) { + return; + } + + PickPointResult pickPointResult = lastSelectMap.get(itemType); + + List filterIds = getFilterIds(pickPointResult); + + switch (itemType) { + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT: + selectPointCallback.onSelectGroundLinkLeft(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT: + selectPointCallback.onSelectGroundLinkRight(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A: + selectPointCallback.onSelectGroundSideA(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B: + selectPointCallback.onSelectGroundSideB(pickPointResult, filterIds); + break; + + case StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A: + selectPointCallback.onSelectSteelA(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B: + selectPointCallback.onSelectSteelB(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK: + selectPointCallback.onSelectUnderGroundLink(pickPointResult, filterIds); + break; + } + } + + private List getFilterIds(PickPointResult pickPointResult) { + List filterIds = new ArrayList<>(); + for (int i = 0; i < getItemCount(); i++) { + StationDetailItem item = getItem(i); + String pointId = item.getOriginalPointId(); + + if (!TextUtils.isEmpty(pointId)) { + if (pickPointResult == null) { + filterIds.add(pointId); + } else { + if (!pickPointResult.getSelectedIds().contains(pointId)) { + filterIds.add(pointId); + } + } + } + } + return filterIds; + } + +} 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/controller/Expression.java b/app/src/main/java/com/bingce/controlnetwork/controller/Expression.java new file mode 100644 index 0000000..d67d350 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/controller/Expression.java @@ -0,0 +1,1008 @@ +/* + * Copyright 2012 Udo Klimaschewski + * + * http://UdoJava.com/ + * http://about.me/udo.klimaschewski + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package com.bingce.controlnetwork.controller; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +/** + *

EvalEx - Java Expression Evaluator

+ *

+ *

Introduction

+ * EvalEx is a handy expression evaluator for Java, that allows to evaluate simple mathematical and boolean expressions. + *
+ * Key Features: + *
    + *
  • Uses BigDecimal for calculation and result
  • + *
  • Single class implementation, very compact
  • + *
  • No dependencies to external libraries
  • + *
  • Precision and rounding mode can be set
  • + *
  • Supports variables
  • + *
  • Standard boolean and mathematical operators
  • + *
  • Standard basic mathematical and boolean functions
  • + *
  • Custom functions and operators can be added at runtime
  • + *
+ *
+ *

Examples

+ *
+ *  BigDecimal result = null;
+ *
+ *  Expression expression = new Expression("1+1/3");
+ *  result = expression.eval():
+ *  expression.setPrecision(2);
+ *  result = expression.eval():
+ *
+ *  result = new Expression("(3.4 + -4.1)/2").eval();
+ *
+ *  result = new Expression("SQRT(a^2 + b^2").with("a","2.4").and("b","9.253").eval();
+ *
+ *  BigDecimal a = new BigDecimal("2.4");
+ *  BigDecimal b = new BigDecimal("9.235");
+ *  result = new Expression("SQRT(a^2 + b^2").with("a",a).and("b",b).eval();
+ *
+ *  result = new Expression("2.4/PI").setPrecision(128).setRoundingMode(RoundingMode.UP).eval();
+ *
+ *  result = new Expression("random() > 0.5").eval();
+ *
+ *  result = new Expression("not(x<7 || sqrt(max(x,9)) <= 3))").with("x","22.9").eval();
+ * 
+ *
+ *

Supported Operators

+ * + * + * + * + * + * + * + * + * + *
Mathematical Operators
OperatorDescription
+Additive operator
-Subtraction operator
*Multiplication operator
/Division operator
%Remainder operator (Modulo)
^Power operator
+ *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + *
Boolean Operators*
OperatorDescription
=Equals
==Equals
!=Not equals
<>Not equals
<Less than
<=Less than or equal to
>Greater than
>=Greater than or equal to
&&Boolean and
||Boolean or
+ * *Boolean operators result always in a BigDecimal value of 1 or 0 (zero). Any non-zero value is treated as a _true_ value. Boolean _not_ is implemented by a function. + *
+ *

Supported Functions

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Function*Description
NOT(expression)Boolean negation, 1 (means true) if the expression is not zero
RANDOM()Produces a random number between 0 and 1
MIN(e1,e2)Returns the smaller of both expressions
MAX(e1,e2)Returns the bigger of both expressions
ABS(expression)Returns the absolute (non-negative) value of the expression
ROUND(expression,precision)Rounds a value to a certain number of digits, uses the current rounding mode
LOG(expression)Returns the natural logarithm (base e) of an expression
SQRT(expression)Returns the square root of an expression
SIN(expression)Returns the trigonometric sine of an angle (in degrees)
COS(expression)Returns the trigonometric cosine of an angle (in degrees)
TAN(expression)Returns the trigonometric tangens of an angle (in degrees)
SINH(expression)Returns the hyperbolic sine of a value
COSH(expression)Returns the hyperbolic cosine of a value
TANH(expression)Returns the hyperbolic tangens of a value
RAD(expression)Converts an angle measured in degrees to an approximately equivalent angle measured in radians
DEG(expression)Converts an angle measured in radians to an approximately equivalent angle measured in degrees
+ * *Functions names are case insensitive. + *
+ *

Supported Constants

+ * + * + * + *
ConstantDescription
PIThe value of PI, exact to 100 digits
+ *

+ *

Add Custom Operators

+ *

+ * Custom operators can be added easily, simply create an instance of `Expression.Operator` and add it to the expression. + * Parameters are the operator string, its precedence and if it is left associative. The operators `eval()` method will be called with the BigDecimal values of the operands. + * All existing operators can also be overridden. + *
+ * For example, add an operator `x >> n`, that moves the decimal point of _x_ _n_ digits to the right: + *

+ *

+ * Expression e = new Expression("2.1234 >> 2");
+ *
+ * e.addOperator(e.new Operator(">>", 30, true) {
+ *     {@literal @}Override
+ *     public BigDecimal eval(BigDecimal v1, BigDecimal v2) {
+ *         return v1.movePointRight(v2.toBigInteger().intValue());
+ *     }
+ * });
+ *
+ * e.eval(); // returns 212.34
+ * 
+ *
+ *

Add Custom Functions

+ *

+ * Adding custom functions is as easy as adding custom operators. Create an instance of `Expression.Function`and add it to the expression. + * Parameters are the function name and the count of required parameters. The functions `eval()` method will be called with a list of the BigDecimal parameters. + * All existing functions can also be overridden. + *
+ * For example, add a function `average(a,b,c)`, that will calculate the average value of a, b and c: + *
+ *

+ * Expression e = new Expression("2 * average(12,4,8)");
+ *
+ * e.addFunction(e.new Function("average", 3) {
+ *     {@literal @}Override
+ *     public BigDecimal eval(List parameters) {
+ *         BigDecimal sum = parameters.get(0).add(parameters.get(1)).add(parameters.get(2));
+ *         return sum.divide(new BigDecimal(3));
+ *     }
+ * });
+ *
+ * e.eval(); // returns 16
+ * 
+ * The software is licensed under the MIT Open Source license (see LICENSE file). + *
+ *
    + *
  • The *power of* operator (^) implementation was copied from [Stack Overflow](http://stackoverflow.com/questions/3579779/how-to-do-a-fractional-power-on-bigdecimal-in-java) Thanks to Gene Marin
  • + *
  • The SQRT() function implementation was taken from the book [The Java Programmers Guide To numerical Computing](http://www.amazon.de/Java-Number-Cruncher-Programmers-Numerical/dp/0130460419) (Ronald Mak, 2002)
  • + *
+ * + * @author Udo Klimaschewski (http://about.me/udo.klimaschewski) + */ +public class Expression { + + /** + * Definition of PI as a constant, can be used in expressions as variable. + */ + public static final BigDecimal PI = new BigDecimal( + "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"); + + /** + * The {@link MathContext} to use for calculations. + */ + private MathContext mc = MathContext.DECIMAL32; + + /** + * The original infix expression. + */ + private String expression = null; + + /** + * The cached RPN (Reverse Polish Notation) of the expression. + */ + private List rpn = null; + + /** + * All defined operators with name and implementation. + */ + private final Map operators = new HashMap(); + + /** + * All defined functions with name and implementation. + */ + private final Map functions = new HashMap(); + + /** + * All defined variables with name and value. + */ + private final Map variables = new HashMap(); + + /** + * What character to use for decimal separators. + */ + private final char decimalSeparator = '.'; + + /** + * What character to use for minus sign (negative values). + */ + private final char minusSign = '-'; + + /** + * The expression evaluators exception class. + */ + public class ExpressionException extends RuntimeException { + private static final long serialVersionUID = 1118142866870779047L; + + public ExpressionException(String message) { + super(message); + } + } + + /** + * Abstract definition of a supported expression function. A function is + * defined by a name, the number of parameters and the actual processing + * implementation. + */ + public abstract class Function { + /** + * Name of this function. + */ + private final String name; + /** + * Number of parameters expected for this function. + */ + private final int numParams; + + /** + * Creates a new function with given name and parameter count. + * + * @param name The name of the function. + * @param numParams The number of parameters for this function. + */ + public Function(String name, int numParams) { + this.name = name.toUpperCase(); + this.numParams = numParams; + } + + public String getName() { + return name; + } + + public int getNumParams() { + return numParams; + } + + /** + * Implementation for this function. + * + * @param parameters Parameters will be passed by the expression evaluator as a + * {@link List} of {@link BigDecimal} values. + * @return The function must return a new {@link BigDecimal} value as a + * computing result. + */ + public abstract BigDecimal eval(List parameters); + } + + /** + * Abstract definition of a supported operator. An operator is defined by + * its name (pattern), precedence and if it is left- or right associative. + */ + public abstract class Operator { + /** + * This operators name (pattern). + */ + private final String oper; + /** + * Operators precedence. + */ + private final int precedence; + /** + * Operator is left associative. + */ + private final boolean leftAssoc; + + /** + * Creates a new operator. + * + * @param oper The operator name (pattern). + * @param precedence The operators precedence. + * @param leftAssoc true if the operator is left associative, + * else false. + */ + public Operator(String oper, int precedence, boolean leftAssoc) { + this.oper = oper; + this.precedence = precedence; + this.leftAssoc = leftAssoc; + } + + public String getOper() { + return oper; + } + + public int getPrecedence() { + return precedence; + } + + public boolean isLeftAssoc() { + return leftAssoc; + } + + /** + * Implementation for this operator. + * + * @param v1 Operand 1. + * @param v2 Operand 2. + * @return The result of the operation. + */ + public abstract BigDecimal eval(BigDecimal v1, BigDecimal v2); + } + + /** + * Expression tokenizer that allows to iterate over a {@link String} + * expression token by token. Blank characters will be skipped. + */ + private class Tokenizer implements Iterator { + + /** + * Actual position in expression string. + */ + private int pos = 0; + /** + * The original input expression. + */ + private final String input; + /** + * The previous token or null if none. + */ + private String previousToken; + + /** + * Creates a new tokenizer for an expression. + * + * @param input The expression string. + */ + public Tokenizer(String input) { + this.input = input; + } + + @Override + public boolean hasNext() { + return (pos < input.length()); + } + + /** + * Peek at the next character, without advancing the iterator. + * + * @return The next character or character 0, if at end of string. + */ + private char peekNextChar() { + if (pos < (input.length() - 1)) { + return input.charAt(pos + 1); + } else { + return 0; + } + } + + @Override + public String next() { + StringBuilder token = new StringBuilder(); + if (pos >= input.length()) { + return previousToken = null; + } + char ch = input.charAt(pos); + while (Character.isWhitespace(ch) && pos < input.length()) { + ch = input.charAt(++pos); + } + if (Character.isDigit(ch)) { + while ((Character.isDigit(ch) || ch == decimalSeparator) + && (pos < input.length())) { + token.append(input.charAt(pos++)); + ch = pos == input.length() ? 0 : input.charAt(pos); + } + } else if (ch == minusSign + && Character.isDigit(peekNextChar()) + && ("(".equals(previousToken) || ",".equals(previousToken) + || previousToken == null || operators + .containsKey(previousToken))) { + token.append(minusSign); + pos++; + token.append(next()); + } else if (Character.isLetter(ch)) { + while ((Character.isLetter(ch) || Character.isDigit(ch) || (ch == '_')) && (pos < input.length())) { + token.append(input.charAt(pos++)); + ch = pos == input.length() ? 0 : input.charAt(pos); + } + } else if (ch == '(' || ch == ')' || ch == ',') { + token.append(ch); + pos++; + } else { + while (!Character.isLetter(ch) && !Character.isDigit(ch) + && !Character.isWhitespace(ch) && ch != '(' + && ch != ')' && ch != ',' && (pos < input.length())) { + token.append(input.charAt(pos)); + pos++; + ch = pos == input.length() ? 0 : input.charAt(pos); + if (ch == minusSign) { + break; + } + } + if (!operators.containsKey(token.toString())) { + throw new ExpressionException("Unknown operator '" + token + + "' at position " + (pos - token.length() + 1)); + } + } + return previousToken = token.toString(); + } + + @Override + public void remove() { + throw new ExpressionException("remove() not supported"); + } + + } + + /** + * Creates a new expression instance from an expression string. + * + * @param expression The expression. E.g. "2.4*sin(3)/(2-4)" or + * "sin(y)>0 & max(z, 3)>3" + */ + public Expression(String expression) { + this.expression = expression; + addOperator(new Operator("+", 20, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.add(v2, mc); + } + }); + addOperator(new Operator("-", 20, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.subtract(v2, mc); + } + }); + addOperator(new Operator("*", 30, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.multiply(v2, mc); + } + }); + /*addOperator(new Operator("/", 30, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.divide(v2, mc); + } + });*/ + addOperator(new Operator("%", 30, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.remainder(v2, mc); + } + }); + addOperator(new Operator("^", 40, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + /*- + * Thanks to Gene Marin: + * http://stackoverflow.com/questions/3579779/how-to-do-a-fractional-power-on-bigdecimal-in-java + */ + int signOf2 = v2.signum(); + double dn1 = v1.doubleValue(); + v2 = v2.multiply(new BigDecimal(signOf2)); // n2 is now positive + BigDecimal remainderOf2 = v2.remainder(BigDecimal.ONE); + BigDecimal n2IntPart = v2.subtract(remainderOf2); + BigDecimal intPow = v1.pow(n2IntPart.intValueExact(), mc); + BigDecimal doublePow = BigDecimal.valueOf(Math.pow(dn1, + remainderOf2.doubleValue())); + + BigDecimal result = intPow.multiply(doublePow, mc); + if (signOf2 == -1) { + result = BigDecimal.ONE.divide(result, mc.getPrecision(), + RoundingMode.HALF_UP); + } + return result; + } + }); + addOperator(new Operator("&&", 4, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + boolean b1 = !v1.equals(BigDecimal.ZERO); + boolean b2 = !v2.equals(BigDecimal.ZERO); + return b1 && b2 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator("||", 2, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + boolean b1 = !v1.equals(BigDecimal.ZERO); + boolean b2 = !v2.equals(BigDecimal.ZERO); + return b1 || b2 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator(">", 10, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) == 1 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator(">=", 10, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) >= 0 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator("<", 10, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) == -1 ? BigDecimal.ONE + : BigDecimal.ZERO; + } + }); + + addOperator(new Operator("<=", 10, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) <= 0 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator("=", 7, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) == 0 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + addOperator(new Operator("==", 7, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return operators.get("=").eval(v1, v2); + } + }); + + addOperator(new Operator("!=", 7, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) != 0 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + addOperator(new Operator("<>", 7, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return operators.get("!=").eval(v1, v2); + } + }); + + addFunction(new Function("NOT", 1) { + @Override + public BigDecimal eval(List parameters) { + boolean zero = parameters.get(0).compareTo(BigDecimal.ZERO) == 0; + return zero ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addFunction(new Function("RANDOM", 0) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.random(); + return new BigDecimal(d, mc); + } + }); + /*addFunction(new Function("SIN", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.sin(Math.toRadians(parameters.get(0) + .doubleValue())); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("COS", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.cos(Math.toRadians(parameters.get(0) + .doubleValue())); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("TAN", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.tan(Math.toRadians(parameters.get(0) + .doubleValue())); + return new BigDecimal(d, mc); + } + });*/ + addFunction(new Function("SINH", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.sinh(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("COSH", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.cosh(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("TANH", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.tanh(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("RAD", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.toRadians(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("DEG", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.toDegrees(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("MAX", 2) { + @Override + public BigDecimal eval(List parameters) { + BigDecimal v1 = parameters.get(0); + BigDecimal v2 = parameters.get(1); + return v1.compareTo(v2) > 0 ? v1 : v2; + } + }); + addFunction(new Function("MIN", 2) { + @Override + public BigDecimal eval(List parameters) { + BigDecimal v1 = parameters.get(0); + BigDecimal v2 = parameters.get(1); + return v1.compareTo(v2) < 0 ? v1 : v2; + } + }); + addFunction(new Function("ABS", 1) { + @Override + public BigDecimal eval(List parameters) { + return parameters.get(0).abs(mc); + } + }); + addFunction(new Function("LOG", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.log(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("ROUND", 2) { + @Override + public BigDecimal eval(List parameters) { + BigDecimal toRound = parameters.get(1); + int precision = parameters.get(0).intValue(); + return toRound.setScale(precision, mc.getRoundingMode()); + } + }); + /*addFunction(new Function("SQRT", 1) { + @Override + public BigDecimal eval(List parameters) { + /* + * From The Java Programmers Guide To numerical Computing + * (Ronald Mak, 2003) + */ + /*BigDecimal x = parameters.get(0); + if (x.compareTo(BigDecimal.ZERO) == 0) { + return new BigDecimal(0); + } + if (x.signum() < 0) { + throw new ExpressionException( + "Argument to SQRT() function must not be negative"); + } + BigInteger n = x.movePointRight(mc.getPrecision() << 1) + .toBigInteger(); + + int bits = (n.bitLength() + 1) >> 1; + BigInteger ix = n.shiftRight(bits); + BigInteger ixPrev; + + do { + ixPrev = ix; + ix = ix.add(n.divide(ix)).shiftRight(1); + // Give other threads a chance to work; + Thread.yield(); + } while (ix.compareTo(ixPrev) != 0); + + return new BigDecimal(ix, mc.getPrecision()); + } + });*/ + + variables.put("PI", PI); + + } + + /** + * Is the string a number? + * + * @param st The string. + * @return true, if the input string is a number. + */ + private boolean isNumber(String st) { + if (st.charAt(0) == minusSign && st.length() == 1) + return false; + for (char ch : st.toCharArray()) { + if (!Character.isDigit(ch) && ch != minusSign + && ch != decimalSeparator) + return false; + } + return true; + } + + /** + * Implementation of the Shunting Yard algorithm to transform an + * infix expression to a RPN expression. + * + * @param expression The input expression in infx. + * @return A RPN representation of the expression, with each token as a list + * member. + */ + private List shuntingYard(String expression) { + List outputQueue = new ArrayList(); + Stack stack = new Stack(); + + Tokenizer tokenizer = new Tokenizer(expression); + + String lastFunction = null; + while (tokenizer.hasNext()) { + String token = tokenizer.next(); + if (isNumber(token)) { + outputQueue.add(token); + } else if (variables.containsKey(token)) { + outputQueue.add(variables.get(token).toPlainString()); + } else if (functions.containsKey(token.toUpperCase())) { + stack.push(token); + lastFunction = token; + } else if (Character.isLetter(token.charAt(0))) { + stack.push(token); + } else if (",".equals(token)) { + while (!stack.isEmpty() && !"(".equals(stack.peek())) { + outputQueue.add(stack.pop()); + } + if (stack.isEmpty()) { + throw new ExpressionException("Parse error for function '" + + lastFunction + "'"); + } + } else if (operators.containsKey(token)) { + Operator o1 = operators.get(token); + String token2 = stack.isEmpty() ? null : stack.peek(); + while (operators.containsKey(token2) + && ((o1.isLeftAssoc() && o1.getPrecedence() <= operators + .get(token2).getPrecedence()) || (o1 + .getPrecedence() < operators.get(token2) + .getPrecedence()))) { + outputQueue.add(stack.pop()); + token2 = stack.isEmpty() ? null : stack.peek(); + } + stack.push(token); + } else if ("(".equals(token)) { + stack.push(token); + } else if (")".equals(token)) { + while (!stack.isEmpty() && !"(".equals(stack.peek())) { + outputQueue.add(stack.pop()); + } + if (stack.isEmpty()) { + throw new RuntimeException("Mismatched parentheses"); + } + stack.pop(); + if (!stack.isEmpty() + && functions.containsKey(stack.peek().toUpperCase())) { + outputQueue.add(stack.pop()); + } + } + } + while (!stack.isEmpty()) { + String element = stack.pop(); + if ("(".equals(element) || ")".equals(element)) { + throw new RuntimeException("Mismatched parentheses"); + } + if (!operators.containsKey(element)) { + throw new RuntimeException("Unknown operator or function: " + + element); + } + outputQueue.add(element); + } + return outputQueue; + } + + /** + * Evaluates the expression. + * + * @return The result of the expression. + */ + public BigDecimal eval() { + + Stack stack = new Stack(); + + for (String token : getRPN()) { + if (operators.containsKey(token)) { + BigDecimal v1 = stack.pop(); + BigDecimal v2 = stack.pop(); + stack.push(operators.get(token).eval(v2, v1)); + } else if (functions.containsKey(token.toUpperCase())) { + Function f = functions.get(token.toUpperCase()); + ArrayList p = new ArrayList( + f.getNumParams()); + for (int i = 0; i < f.numParams; i++) { + p.add(stack.pop()); + } + BigDecimal fResult = f.eval(p); + stack.push(fResult); + } else { + stack.push(new BigDecimal(token, mc)); + } + } + return stack.pop().stripTrailingZeros(); + } + + /** + * Sets the precision for expression evaluation. + * + * @param precision The new precision. + * @return The expression, allows to chain methods. + */ + public Expression setPrecision(int precision) { + this.mc = new MathContext(precision); + return this; + } + + /** + * Sets the rounding mode for expression evaluation. + * + * @param roundingMode The new rounding mode. + * @return The expression, allows to chain methods. + */ + public Expression setRoundingMode(RoundingMode roundingMode) { + this.mc = new MathContext(mc.getPrecision(), roundingMode); + return this; + } + + /** + * Adds an operator to the list of supported operators. + * + * @param operator The operator to add. + * @return The previous operator with that name, or null if + * there was none. + */ + public Operator addOperator(Operator operator) { + return operators.put(operator.getOper(), operator); + } + + /** + * Adds a function to the list of supported functions + * + * @param function The function to add. + * @return The previous operator with that name, or null if + * there was none. + */ + public Function addFunction(Function function) { + return functions.put(function.getName(), function); + } + + /** + * Sets a variable value. + * + * @param variable The variable name. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression setVariable(String variable, BigDecimal value) { + variables.put(variable, value); + return this; + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression setVariable(String variable, String value) { + variables.put(variable, new BigDecimal(value)); + return this; + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression with(String variable, BigDecimal value) { + return setVariable(variable, value); + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression and(String variable, String value) { + return setVariable(variable, value); + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression and(String variable, BigDecimal value) { + return setVariable(variable, value); + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression with(String variable, String value) { + return setVariable(variable, value); + } + + /** + * Get an iterator for this expression, allows iterating over an expression + * token by token. + * + * @return A new iterator instance for this expression. + */ + public Iterator getExpressionTokenizer() { + return new Tokenizer(this.expression); + } + + /** + * Cached access to the RPN notation of this expression, ensures only one + * calculation of the RPN per expression instance. If no cached instance + * exists, a new one will be created and put to the cache. + * + * @return The cached RPN instance. + */ + private List getRPN() { + if (rpn == null) { + rpn = shuntingYard(this.expression); + } + return rpn; + } + + /** + * Get a string representation of the RPN (Reverse Polish Notation) for this + * expression. + * + * @return A string with the RPN representation for this expression. + */ + public String toRPN() { + String result = ""; + for (String st : getRPN()) { + result = "".equals(result) ? result : result + " "; + result += st; + //System.out.println("Watch out this is only possible with api 9+"); + } + return result; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/controller/KeyEventAction.java b/app/src/main/java/com/bingce/controlnetwork/controller/KeyEventAction.java new file mode 100644 index 0000000..c36e96b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/controller/KeyEventAction.java @@ -0,0 +1,12 @@ +package com.bingce.controlnetwork.controller; + +public class KeyEventAction { + public final static String NONE = "0"; + public final static String CAL = "1"; + public final static String SURVEY = "2"; + public final static String RECORD = "3"; + public final static String LAST = "4"; + public final static String NEXT = "5"; + public final static String SURVEY_NO_SEND = "6"; + public final static String SURVEY_AND_RECORD = "7"; +} 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/AbstractFullScreenDialogFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractFullScreenDialogFragment.java new file mode 100644 index 0000000..dd9c790 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractFullScreenDialogFragment.java @@ -0,0 +1,125 @@ +package com.bingce.controlnetwork.fragment; + +import android.graphics.drawable.ColorDrawable; +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.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; + +import com.bingce.utils.SoftKeyUtils; + +import com.bingce.controlnetwork.R; + +public abstract class AbstractFullScreenDialogFragment extends AppCompatDialogFragment { + + private View viewSpace; + private View confirm; + + @Nullable + @Override + final public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); + View contentView = inflater.inflate(R.layout.fragment_fullscreen_dialog_layout, container, false); + FrameLayout contentContainer = contentView.findViewById(R.id.content_container); + contentView.setOnClickListener(v -> { + if (quitWhenTouchBg()) { + doDismiss(); + } else { + hideSoft(); + } + }); + + if (getArguments() != null) { + TextView title = contentView.findViewById(R.id.title); + if (title != null) { + String string = getArguments().getString(KEY_TITLE_NAME); + if (string == null || string.isEmpty()) { + title.setVisibility(View.GONE); + } else { + title.setText(string); + } + } + TextView subTitle = contentView.findViewById(R.id.sub_title); + if (subTitle != null) { + String string = getArguments().getString(KEY_SUB_TITLE_NAME); + if (string == null || string.isEmpty()) { + subTitle.setVisibility(View.GONE); + } else { + subTitle.setText(string); + } + } + } + + View cancel = contentView.findViewById(R.id.cancel_button); + if (cancel != null) { + cancel.setOnClickListener(v -> onCancel()); + } + viewSpace = contentView.findViewById(R.id.viewSpace); + confirm = contentView.findViewById(R.id.confirm_button); + if (confirm != null) { + confirm.setOnClickListener(v -> { + hideSoft(); + onConfirm(); + }); + } + + contentContainer.addView(createContentView(inflater, contentContainer, savedInstanceState)); + return contentView; + } + + protected void onCancel() { + doDismiss(); + } + + protected void onConfirm() { + dismiss(); + } + + protected abstract View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState); + + private void doDismiss() { + hideSoft(); + dismiss(); + } + + private void hideSoft() { + SoftKeyUtils.hideSoftKey(); + } + + protected boolean quitWhenTouchBg() { + return true; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0x33000000)); + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT); + } + + protected AbstractFullScreenDialogFragment() { + } + + private static final String KEY_SUB_TITLE_NAME = "__ATTRIBUTE__NAME__"; + private static final String KEY_TITLE_NAME = "__GROUP__NAME__"; + + protected static void setArgs(Bundle args, String title, String subTitle) { + args.putString(KEY_SUB_TITLE_NAME, subTitle); + args.putString(KEY_TITLE_NAME, title); + } + + protected void setHideConfirm() { + viewSpace.setVisibility(View.GONE); + confirm.setVisibility(View.GONE); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java new file mode 100644 index 0000000..fc8333b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java @@ -0,0 +1,211 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; + +import org.jetbrains.annotations.NotNull; + +public abstract class AbstractHierarchicalListFragment extends Fragment { + private View layout1; + private View layout2; + private View back1; + private View back2; + private TextView title1; + private TextView title2; + private RecyclerView recyclerView1; + private RecyclerView recyclerView2; + private boolean is1Layout = true;//通知当前显示的是layout1还是layout2 + private int currentListIndex = 0;//当前显示的list在所有集合中的index + private final IndexWithTextAdapter.IOnItemClick> callback = item -> onItemClicked(currentListIndex, item); + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.fragment_hierarchical_list_layout, container, false); + + layout1 = root.findViewById(R.id.layout1); + if (layout1 != null) { + recyclerView1 = layout1.findViewById(R.id.list1); + } + back1 = root.findViewById(R.id.back1); + if (back1 != null) { + back1.setOnClickListener(v -> onBackClicked(currentListIndex)); + } + title1 = root.findViewById(R.id.title1); + + layout2 = root.findViewById(R.id.layout2); + if (layout2 != null) { + recyclerView2 = layout2.findViewById(R.id.list2); + } + back2 = root.findViewById(R.id.back2); + if (back2 != null) { + back2.setOnClickListener(v -> onBackClicked(currentListIndex)); + } + title2 = root.findViewById(R.id.title2); + + //初始化 + if (layout2 != null) { + layout2.setVisibility(View.GONE); + } + //加载list1 + setupList(0, title1, recyclerView1, callback); + return root; + } + + //执行back + final protected void back2(int listIndex) { + currentListIndex = listIndex; + is1Layout = !is1Layout; + + updateButtonVisibility(); + + doSwitch(layout1, layout2, title1, title2, recyclerView1, recyclerView2, this, + callback, + is1Layout, listIndex, false); + } + + //执行forward + final protected void forward2(int listIndex) { + currentListIndex = listIndex; + is1Layout = !is1Layout; + + updateButtonVisibility(); + + doSwitch(layout1, layout2, title1, title2, recyclerView1, recyclerView2, this, + callback, + is1Layout, listIndex, true); + } + + private void updateButtonVisibility() { + if (is1Layout && back1 != null) { + back1.setVisibility(!isFirstIndex(currentListIndex) ? View.VISIBLE : View.GONE); + } else if (!is1Layout && back2 != null) { + back2.setVisibility(!isFirstIndex(currentListIndex) ? View.VISIBLE : View.GONE); + } + } + + protected boolean isFirstIndex(int index) { + return index == 0; + } + + protected int preIndexOf(int index) { + return index - 1; + } + + final boolean doBack() { + if (currentListIndex > 0) { + back2(preIndexOf(currentListIndex)); + return true; + } + return false; + } + + private static void doSwitch(View layout1, View layout2, TextView title1, TextView title2, + RecyclerView recyclerView1, + RecyclerView recyclerView2, + AbstractHierarchicalListFragment fragment, + final IndexWithTextAdapter.IOnItemClick> callback, + boolean targetLayoutIsLayout1, + int listIndex, + boolean moveForward) { + //先更新界面,再执行动画 + View currentLayout = layout1; + View targetLayout = layout1; + TextView targetTitle = title1; + RecyclerView targetRecycleView = recyclerView1; + + if (targetLayoutIsLayout1) { + currentLayout = layout2; + } else { + targetLayout = layout2; + targetTitle = title2; + targetRecycleView = recyclerView2; + } + + //先设置数据 + fragment.setupList(listIndex, targetTitle, targetRecycleView, callback); + + //执行动画 + Animation outAnimation = AnimationUtils.loadAnimation(fragment.getContext(), + moveForward ? R.anim.slide_out_left : R.anim.slide_out_right); + outAnimation.setFillAfter(true); + View finalCurrentLayout = currentLayout; + outAnimation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + } + + @Override + public void onAnimationEnd(Animation animation) { + finalCurrentLayout.clearAnimation(); + finalCurrentLayout.setVisibility(View.GONE); + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + }); + + Animation inAnimation = AnimationUtils.loadAnimation(fragment.getContext(), + moveForward ? R.anim.slide_in_right : R.anim.slide_in_left); + inAnimation.setFillAfter(true); + targetLayout.setVisibility(View.VISIBLE); + + currentLayout.startAnimation(outAnimation); + targetLayout.startAnimation(inAnimation); + } + + //通知child,通知list的item被点击,下一步执行 forward或结束加载 + 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); + + protected static class Item implements IUniversalListItem { + private final String name; + private final String id; + + Item(String name, String id) { + this.name = name; + this.id = id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getId() { + return id; + } + + @Override + public String getValue() { + return id; + } + } + + protected AbstractHierarchicalListFragment() { + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java new file mode 100644 index 0000000..e55b8ea --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java @@ -0,0 +1,163 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +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.annotation.WorkerThread; +import androidx.fragment.app.Fragment; + +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.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 com.bingce.controlnetwork.R; + +/* + * 项目限差详情,包含'LimitDetailFragment'+选择模板 + * */ +public abstract class AbstractProjectToleranceFragment extends BaseFragment { + private String currentToleranceDetailRecordId; + + protected String projectType; + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(BundleConstants.KEY_PROJECT_TYPE); + } + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_project_limit_detail_layout, container, false); + //设置限差模板选择事件 + registerSelectTemplateCallback(view, () -> ThreadPoolUtil.execute(this::onSelectToleranceTemplateClick)); + //设置详情 + onCreateView(view); + return view; + } + + /** + * 获取新建项目时的默认限差 + * + * @param projectType + */ + protected IToleranceDetail getNewDefaultTolerance(String projectType) { + return ToleranceLoadUtil.getToleranceLoad(projectType).getNewDefaultTolerance(projectType); + } + + protected abstract void onCreateView(View view); + + protected void setCurrentToleranceName(View view, IToleranceDetail toleranceRecord) { + View tv = view.findViewById(R.id.setting_index); + 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); + } + }); + }); + } + + protected void registerSelectTemplateCallback(View view, Runnable runnable) { + ViewUtil.setOnClick(view.findViewById(R.id.setting_index), v -> runnable.run()); + } + + /** + * 限差模板的点击后逻辑 + */ + @WorkerThread + protected void onSelectToleranceTemplateClick() { + IToleranceOperate operate = ToleranceOperateUtil.getOperate(currentToleranceDetailRecordId); + if (operate == null) return; + IToleranceDetail toleranceDetailRecordTj = operate.getIToleranceDetail(currentToleranceDetailRecordId); + if (toleranceDetailRecordTj == null) { + return; + } + + ThreadPoolUtil.executeInMain(() -> + SelectToleranceBottomSheetFragment.select( + getChildFragmentManager(), + getViewLifecycleOwner(), + projectType, + toleranceDetailRecordTj.getGroupId(), + toleranceDetailRecordTj.getLevelId(), + toleranceDetailRecordTj.getId(), + toleranceId -> ThreadPoolUtil.execute(() -> { + //根据toleranceId查找缓存数据 + IToleranceDetail instance = operate.getIToleranceDetail(toleranceId); + //更新页面数据 + updateToleranceDetail(getView(), instance); + //新增 + //这里增加存入数据库 已备杀死app后能获取到限差数据 + operate.saveToleranceDetail(instance); + }) + )); + } + + protected void onCurrentToleranceChanged(String toleranceId) { + currentToleranceDetailRecordId = toleranceId; + } + + protected void newToleranceDetailFragment(Bundle args, IOnSingleGetCallback callback) { + if (callback != null) { + callback.onGet(ToleranceDetailFragment.newInstance(args, false)); + } + } + + @WorkerThread + protected void updateToleranceDetail(View view, IToleranceDetail tolerance) { + if (tolerance == null) { + return; + } + onCurrentToleranceChanged(tolerance.getId()); + runOnUI(() -> { + //设置限差名称 + setCurrentToleranceName(view, tolerance); + //设置限差详情 + Fragment detailFragment = + getParentFragmentManager().findFragmentByTag(AbstractProjectToleranceFragment.class.getName()); + if (detailFragment == null) { + Bundle args = new Bundle(); + if (getArguments() != null) { + args.putString(BundleConstants.KEY_TOLERANCE_ID, tolerance.getId()); + } + newToleranceDetailFragment(args, detailFragmentInstance -> getParentFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, detailFragmentInstance, AbstractProjectToleranceFragment.class.getName()) + .commit()); + } else { + if (detailFragment instanceof ToleranceDetailFragment) { + ((ToleranceDetailFragment) detailFragment).switchTolerance(tolerance.getId()); + } + } + }); + } + + protected String currentTolerance() { + return currentToleranceDetailRecordId; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractRecyclerViewFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractRecyclerViewFragment.java new file mode 100644 index 0000000..b749465 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractRecyclerViewFragment.java @@ -0,0 +1,33 @@ +package com.bingce.controlnetwork.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 androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public abstract class AbstractRecyclerViewFragment extends Fragment { + protected abstract void refreshRecyclerView(RecyclerView recyclerView); + + @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); + } + + setHasOptionsMenu(true); + + return view; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/BaseBottomSheetDialogFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/BaseBottomSheetDialogFragment.java new file mode 100644 index 0000000..8dc5454 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/BaseBottomSheetDialogFragment.java @@ -0,0 +1,12 @@ +package com.bingce.controlnetwork.fragment; + +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +public class BaseBottomSheetDialogFragment extends BottomSheetDialogFragment { + final protected void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSelectListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSelectListFragment.java new file mode 100644 index 0000000..4eed9fa --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSelectListFragment.java @@ -0,0 +1,141 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; + +/** + * 弹框,用于选择限差模板 + */ +public class BottomSheetSelectListFragment extends BottomSheetDialogFragment { + public static final String TAG = BottomSheetSelectListFragment.class.getName(); + + private BottomSheetSelectListFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_bottom_popup_list_select_layout, + container, false); + // Set the adapter + Context context = view.getContext(); + RecyclerView recyclerView = view.findViewById(R.id.list); + recyclerView.setLayoutManager(new LinearLayoutManager(context)); + + String targetId = null; + List items = new ArrayList<>(); + List indexes = null; + if (getArguments() != null) { + List strings = getArguments().getStringArrayList(KEY_ITEMS); + indexes = getArguments().getStringArrayList(KEY_ENABLE_INDEX); + int defaultIndex = getArguments().getInt(KEY_DEFAULT_ID, -1); + if (strings != null) { + for (int index = 0; index < strings.size(); index++) { + String string = strings.get(index); + Item item = new Item(); + item.setId(String.valueOf(index)); + item.setName(string); + items.add(item); + } + if (defaultIndex < 0 || defaultIndex >= strings.size()) { + if (!items.isEmpty()) { + targetId = items.get(0).getId(); + } + } else { + targetId = items.get(defaultIndex).getId(); + } + } + } + + SelectableIndexWithTextAdapter adapter = + new SelectableIndexWithTextAdapter<>( + targetId, + items, + indexes, + item -> { + Bundle args = new Bundle(); + String id = item.getId(); + int index = Integer.parseInt(id); + args.putInt(KEY_INDEX, index); + args.putString(KEY_STRING, item.getName()); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + }); + recyclerView.setAdapter(adapter); + return view; + } + + private static final String KEY_ITEMS = "__ITEMS__"; + private static final String KEY_INDEX = "__INDEX__"; + private static final String KEY_ENABLE_INDEX = "__ENABLE_INDEX__"; + private static final String KEY_DEFAULT_ID = "__defaultId__"; + private static final String KEY_STRING = "__STRING__"; + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + + public static void showSelect(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + int defaultIndex, + ArrayList items, + ArrayList enableIndexes, + IOnSelectCallback callback) { + if (callback == null) { + return; + } + Bundle args = new Bundle(); + args.putStringArrayList(KEY_ITEMS, items); + if (enableIndexes != null && !enableIndexes.isEmpty()) { + args.putStringArrayList(KEY_ENABLE_INDEX, enableIndexes); + } + args.putInt(KEY_DEFAULT_ID, defaultIndex); + BottomSheetSelectListFragment fragment = new BottomSheetSelectListFragment(); + fragment.setArguments(args); + fragmentManager + .setFragmentResultListener(KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSelected(result.getInt(KEY_INDEX), result.getString(KEY_STRING)); + } + }); + fragment.show(fragmentManager, TAG); + } + +// public static void showSelect(FragmentManager fragmentManager, +// @NonNull LifecycleOwner lifecycleOwner, +// int defaultIndex, +// ArrayList items, +// IOnSelectCallback callback) { +// showSelect(fragmentManager, lifecycleOwner, defaultIndex, items, null, callback); +// } + + public interface IOnSelectCallback { + void onSelected(int index, String string); + } + + private static class Item extends UniversalListItem { + @Override + public ViewItemType getType() { + return null; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSurveyorPeriodFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSurveyorPeriodFragment.java new file mode 100644 index 0000000..97d3a2a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSurveyorPeriodFragment.java @@ -0,0 +1,320 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +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.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigOperate; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.ISurveyorPeriodDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.SurveyorPeriodAdapter; +import com.bingce.controlnetwork.ui.ViewUtil; +import com.bingce.controlnetwork.util.DefaultNameUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + + +/** + * 弹框,用于选择测期 + */ +public class BottomSheetSurveyorPeriodFragment extends BottomSheetDialogFragment implements IUIRunner { + private static final String KEY_TIME_ID = "__TIME_ID"; + public static final String KEY_REQUEST_TIME = "KEY_REQUEST_TIME_ID"; + public static final String KEY_RESULT_NAME = "KEY_RESULT_NAME"; + public static final String KEY_RESULT_ID = "___result__id"; + private SurveyorPeriodAdapter adapter = null; + + private BottomSheetSurveyorPeriodFragment() { + } + + public static void pick(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String projectId, String currentCycleId, ICallback callback) { + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_TIME, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_TIME.equals(requestKey)) { + callback.onSelect(result.getString(KEY_RESULT_ID), result.getString(KEY_RESULT_NAME)); + } + }); + BottomSheetDialogFragment fragment = new BottomSheetSurveyorPeriodFragment(); + Bundle args = new Bundle(); + args.putString(KEY_TIME_ID, currentCycleId); + args.putString(BundleConstants.KEY_PROJECT_ID, projectId); + fragment.setArguments(args); + fragment.show(fragmentManager, "time_index"); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_surveryor_station_number_list, container, false); + RecyclerView recyclerView = view.findViewById(R.id.list); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + String projectId = ""; + String currentCycleId = ""; + if (getArguments() != null) { + projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + currentCycleId = getArguments().getString(KEY_TIME_ID); + } + + adapter = new SurveyorPeriodAdapter(currentCycleId, this); + recyclerView.setAdapter(adapter); + + Helper helper = new Helper(adapter, recyclerView, + view.findViewById(R.id.loading), view.findViewById(R.id.empty_tips), getViewLifecycleOwner()); + + helper.refresh(projectId); + + String finalProjectId = projectId; + ViewUtil.setOnClick( + view.findViewById(R.id.new_item), + v -> createNewCycle(getContext(), getParentFragmentManager(), getChildFragmentManager(), getViewLifecycleOwner(), + adapter, this, finalProjectId)); + return view; + } + + private static void createNewCycle(@Nullable Context context, FragmentManager parentManager, FragmentManager manager, LifecycleOwner lifecycleOwner, + SurveyorPeriodAdapter adapter, IUIRunner runner, String finalProjectId) { + if (context == null) { + return; + } + StringInputFragment.input(manager, + context.getString(R.string.tips_input_new_cycle_name), + DefaultNameUtil.getDefaultPeriodName(), + lifecycleOwner, + string -> { + if (string == null || string.isEmpty()) { + ToastUtils.showShort(R.string.tips_cycle_name_cannt_empty); + } else { + SurveyorPeriodRecord record = + new SurveyorPeriodRecord(finalProjectId, string); + SurveyorDatabaseFactory.instance + .getSurveyorPeriod() + .saveRecord(record); + if (adapter != null) { + adapter.changeCurrentSelect(record.id); + } + //自动切换到新测回 + Bundle args = new Bundle(); + args.putString(BottomSheetSurveyorPeriodFragment.KEY_RESULT_ID, record.getId()); + args.putString(BottomSheetSurveyorPeriodFragment.KEY_RESULT_NAME, record.getName()); + parentManager.setFragmentResult(BottomSheetSurveyorPeriodFragment.KEY_REQUEST_TIME, args); + //询问是否从其他已有测期复制测站列表 + tryCopyStationFromOther(context, manager, lifecycleOwner, record, runner, finalProjectId); + //更新默认测回和测期 + ConfigOperate.changeDefaultProjectAndCycle(finalProjectId, record.id); + + } + }); + } + + private static void tryCopyStationFromOther( + @Nullable Context context, FragmentManager manager, LifecycleOwner lifecycleOwner, + SurveyorPeriodRecord record, IUIRunner runner, String finalProjectId) { + //检测其他测期是否有测站 + ThreadPoolUtil.execute(() -> { + ISurveyorPeriodDataSource surveyorCycleDataSource = + SurveyorDatabaseFactory.instance + .getSurveyorPeriod(); + List cycleRecords = surveyorCycleDataSource.getDataListSyncByProjectId(finalProjectId); + if (cycleRecords == null || cycleRecords.isEmpty()) { + return; + } + List cycleRecordWithStation = new ArrayList<>(); + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + for (SurveyorPeriodRecord cycleRecord : cycleRecords) { + if (cycleRecord == null) { + continue; + } + + List stationRecordList = stationDataSource.getDataList(finalProjectId, cycleRecord.getId()); + if (stationRecordList == null || stationRecordList.isEmpty()) { + continue; + } + + cycleRecordWithStation.add(cycleRecord); + } + + if (cycleRecordWithStation.isEmpty()) { + return; + } + + ArrayList cycleNameList = new ArrayList<>(); + List cycleIdList = new ArrayList<>(); + for (SurveyorPeriodRecord cycleRecord : cycleRecordWithStation) { + if (cycleRecord == null) { + continue; + } + cycleNameList.add(cycleRecord.getName()); + cycleIdList.add(cycleRecord.getId()); + } + //当前其他测期已有测站,则提示是否拷贝 + runner.runOnUI(() -> { + if (context == null) { + return; + } + TipsWith2OptionFragment.tips(manager, + lifecycleOwner, + context.getString(R.string.confirm_button_copy_station_list), + context.getString(R.string.cancel_button_create_empty_cycle), + context.getString(R.string.tips_should_copy_station_list_from_other_cycle), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + copyStationListFromOther(context, manager, lifecycleOwner, cycleNameList, cycleIdList, record); + } + }); + }); + }); + } + + private static void copyStationListFromOther( + Context context, FragmentManager manager, LifecycleOwner lifecycleOwner, + ArrayList cycleNameList, List surveyorPeriodIdList, + SurveyorPeriodRecord surveyorPeriodRecord) { + if (surveyorPeriodRecord == null) { + return; + } + ListDialogFragment.showList( + manager, context.getString(R.string.tips_select_cycle_to_copy), + cycleNameList, lifecycleOwner, (index, value) -> { + String surveyorPeriodId = surveyorPeriodIdList.get(index); + String surveyorPeriodRecordId = surveyorPeriodRecord.getId(); + String projectId = surveyorPeriodRecord.getProjectId(); + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + ILineRecordDataSource lineRecordDataSource = + SurveyorDatabaseFactory.instance.getLineRecordDatabase(); + ThreadPoolUtil.execute(() -> { + List stationRecordList = + stationDataSource.getDataList(projectId, surveyorPeriodId); + if (stationRecordList == null || stationRecordList.isEmpty()) { + return; + } + String lastLineId = "";//当前遍历到的要拷贝的导线id + String newLineId = "";//新建的导线id + List newStations = new ArrayList<>(); + List newLines = new ArrayList<>(); + long date = (new Date()).getTime(); + for (SurveyorStationRecord surveyorStationRecord : stationRecordList) { + if (surveyorStationRecord == null) { + continue; + } + if (surveyorStationRecord.isMulAngleStation()) { + lastLineId = LineRecord.TYPE_MUL_ANGLE; + newLineId = LineRecord.TYPE_MUL_ANGLE; + } else if (SurveyorStationRecord.isLineStation(surveyorStationRecord.getLineId())) { + //拷贝导线 + if (!lastLineId.equals(surveyorStationRecord.getLineId())) { + lastLineId = surveyorStationRecord.getLineId(); + //执行创建导线以及相应测站的逻辑 + LineRecord lineRecord = lineRecordDataSource.findById(lastLineId); + if (lineRecord == null) { + continue; + } + LineRecord newLine = LineRecord.copy(lineRecord, surveyorPeriodRecordId, date++); + newLines.add(newLine); + newLineId = newLine.id; + } + } + //拷贝测站 + newStations.add( + SurveyorStationRecord.copy( + surveyorStationRecord, surveyorPeriodRecordId, newLineId, date++)); + } + //存储测站 + stationDataSource.save(newStations); + //存储导线 + lineRecordDataSource.save(newLines); + }); + }); + } + + public void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } + + public interface ICallback { + void onSelect(String id, String name); + } + + public static class Helper { + private final SurveyorPeriodAdapter adapter; + private final View loadingView; + private final View emptyView; + private final RecyclerView recyclerView; + private final LifecycleOwner lifecycleOwner; + + Helper(SurveyorPeriodAdapter adapter, + RecyclerView recyclerView, + View loadingView, + View emptyView, + LifecycleOwner lifecycleOwner) { + this.loadingView = loadingView; + this.emptyView = emptyView; + this.adapter = adapter; + this.recyclerView = recyclerView; + this.lifecycleOwner = lifecycleOwner; + } + + private void update(List projectRecords) { + adapter.updateData(projectRecords); + } + + public void refresh(String projectId) { + ISurveyorPeriodDataSource surveyorCycleDataSource = + SurveyorDatabaseFactory.instance.getSurveyorPeriod(); + surveyorCycleDataSource.getLiveDataListByProjectId(projectId) + .observe(lifecycleOwner, + records -> { + //隐藏loading + if (loadingView != null) { + loadingView.setVisibility(View.GONE); + } + if (records == null || records.isEmpty()) { + if (emptyView != null) { + emptyView.setVisibility(View.VISIBLE); + } + recyclerView.setVisibility(View.GONE); + } else { + //刷新adapter + if (emptyView != null) { + emptyView.setVisibility(View.GONE); + } + recyclerView.setVisibility(View.VISIBLE); + update(records); + } + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java new file mode 100644 index 0000000..9c897d9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java @@ -0,0 +1,377 @@ +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; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +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.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.surveyor.data.CachedData; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.SurveyorData; +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.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; + +/** + * 测站某个测期的测量数据列表 + */ +public class ComponentStationSurveyorDataListFragment extends BaseFragment + implements IDistanceTypeChangeListener, ISurveyState { + private SurveyorStationRecordsAdapter adapter = null; + private StateManager stateManager; + private RecyclerView recyclerView; + private IDistanceTypeChangeListener cachedDataListener = null; + private IDistanceTypeChangeListener surveyedDataListener = null; + private ISurveyState surveyState; + + private String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(KEY_STATION_ID); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate( + R.layout.fragment_project_surveyor_station_point_list_layout, + container, + false); + String stationId = stationId(); + recyclerView = view.findViewById(R.id.recycler_view); + if (stationId != null) { + //收集信息 + collectData(stationId, + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + index -> { + if (index >= 0 && adapter != null && index < adapter.getItemCount()) { + recyclerView.scrollToPosition(index); + } + }, + new ICollectCacheCallback() { + @Override + public void onFailure() { + } + + @Override + public void onSuccess( + boolean showSlopDistance, + ICachedData cachedData, + SurveyorData surveyorData, + StateManager stateManager) { + onCollectStationData(showSlopDistance, cachedData, surveyorData, stateManager); + surveyState = stateManager; + } + }); + } + + return view; + } + + @WorkerThread + private void onCollectStationData( + boolean showSlopDistance, + ICachedData cachedData, + SurveyorData surveyorData, + StateManager stateManager) { + this.stateManager = stateManager; + cachedDataListener = cachedData; + surveyedDataListener = surveyorData; + + //测量数据收集完毕后,就可以更新UI了 + runOnUI(() -> { + //刷新UI + if (adapter == null) { + adapter = new SurveyorStationRecordsAdapter(stationId(), cachedData, surveyorData, surveyorData); + adapter.onShowSlopDistance(showSlopDistance); + if (recyclerView != null) { + recyclerView.setAdapter(adapter); + //滚动到当前目标点 + int currentItemIndex = surveyorData.currentIndex(); + if (currentItemIndex >= 0 && currentItemIndex < adapter.getItemCount()) { + recyclerView.scrollToPosition(currentItemIndex); + } + } + } + +// //监听测站数据 +// //监听「平距」「斜距」切换,更新UI显示 +// SurveyorDatabaseFactory +// .instance +// .getSurveyorStation() +// .getLiveDataRecord(stationId()) +// .observe(getViewLifecycleOwner(), +// surveyorStationRecord -> onShowSlopDistance(surveyorStationRecord.isShowSlopDistance())); + }); + } + + /** + * 收集测站信息 + */ + private static void collectData( + String stationId, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner runner, + IScrollDelegate scrollDelegate, + ICollectCacheCallback callback) { + if (callback == null) { + return; + } + boolean isSupportAutoMode = TotalStation.getInstance().isSupportMotor(); + ThreadPoolUtil.execute(() -> { + //读取当前测站的当前测回--很重要 + SurveyorScheduleRecord scheduleRecord = + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(SurveyorScheduleConstants.getCurrentCycleKey(stationId, null)); + int defaultCycle = scheduleRecord == null ? 0 : + DigitalUtil.valueOfIntString(scheduleRecord.getStatue(), 0); + //加载测站信息 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + //加载对应项目 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + callback.onFailure(); + return; + } + //加载对应限差 + ToleranceDetailRecord toleranceRecord = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + if (toleranceRecord == null) { + callback.onFailure(); + return; + } + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(surveyorStationRecord.isAutoClose(), + surveyorStationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + callback.onFailure(); + return; + } + //是否显示斜距? + cachedData.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + if (cachedData.pointCount() <= 0) { + callback.onFailure(); + return; + } + //创建stateManager实例 + SurveyorData surveyorDataSource = new SurveyorData(toleranceRecord.getSurveyorCount()); + surveyorDataSource.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + RequestSurveyorParamAuto requestSurveyorParamAuto = new RequestSurveyorParamAuto(stationId, cachedData); + + StateManager stateManager = StateManager.newInstance( + isSupportAutoMode, + requestSurveyorParamAuto, + surveyorStationRecord, + context, + fragmentManager, + lifecycleOwner, + toleranceRecord, + surveyorDataSource, + surveyorDataSource, + cachedData, + scrollDelegate, + runner); + //fragment创建后立即计算当前cycle的测量状态 + runner.runOnUI(() -> stateManager.calScheduleWhenEnterSurveyFragment(defaultCycle)); + callback.onSuccess(surveyorStationRecord.isShowSlopDistance(), cachedData, surveyorDataSource, stateManager); + }); + } + + @Override + public void onResume() { + super.onResume(); + if (stateManager != null) { + stateManager.resume(); + } + } + + @Override + public void onPause() { + super.onPause(); + if (stateManager != null) { + stateManager.quite(); + } + } + + private interface ICollectCacheCallback { + void onFailure(); + + void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManager stateManager); + } + + public void doSurveyor() { + if (stateManager == null) { + return; + } + stateManager.doSurveyor(); + } + + public void autoSurvey() { + if (stateManager == null) { + return; + } + stateManager.doAutoSurveyor(); + } + + public void switchCycle(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.switch2Cycle(cycleIndex); + } + + public void deleteCurrentStationSurveyorData() { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(); + } + + public void deleteByStationAndPeriod(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(cycleIndex); + } + + /** + * 测站检测 + */ + public void stationCheck() { + if (stateManager == null) { + return; + } + stateManager.stationCheck(); + } + + /** + * 测站平差 + */ + public void stationAdjust() { + if (stateManager == null) { + return; + } + 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; + } + stateManager.moveBack(); + } + + @Override + public void onShowSlopDistance(boolean value) { + if (cachedDataListener != null) { + cachedDataListener.onShowSlopDistance(value); + } + if (surveyedDataListener != null) { + surveyedDataListener.onShowSlopDistance(value); + } + if (adapter != null) { + adapter.onShowSlopDistance(value); + adapter.notifyItemRangeChanged(0, adapter.getItemCount()); + } + } + + @Override + public boolean isSurveying() { + if (surveyState != null) { + return surveyState.isSurveying(); + } + return false; + } + + @Override + public boolean isAutoSurveying() { + if (surveyState != null) { + return surveyState.isAutoSurveying(); + } + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + public static final String TAG = ComponentStationSurveyorDataListFragment.class.getName(); + + public static ComponentStationSurveyorDataListFragment newInstance(String stationId) { + ComponentStationSurveyorDataListFragment fragment = new ComponentStationSurveyorDataListFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java new file mode 100644 index 0000000..39726ae --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java @@ -0,0 +1,144 @@ +package com.bingce.controlnetwork.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 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; +import com.bingce.controlapphelper.util.StationUtil; +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; + +import java.util.List; + +/** + * 测站列表(项目和测量共用) + */ +public class ComponentSurveyorStationListFragment extends BaseFragment { + public static final String TAG = "cn.liuyanbing.surveyor.fragment.dummy__SurveyorStationListFragment___"; + private SurveyorStationListAdapter adapter; + private RecyclerView recyclerView; + + private LiveData> stationLiveData; + + /** + * 去测量或者详情页面 + */ + private void goStationMeasureOrDetail(SurveyorStationRecord item, boolean detailOrSurveyorFinal) { + String stationId = item.getId(); + ThreadPoolUtil.execute(() -> { + SurveyorStationRecord stationRecord = SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + if (stationRecord == null || stationRecord.getItems() == null || stationRecord.getItems().isEmpty()) { + return; + } + + String lineTypeFromStation = StationUtil.getLineTypeFromStation(stationRecord); + + //站的名称 导线+点名 + String stationName = StationUtil.getStationName(stationRecord); + + if (detailOrSurveyorFinal) { + SingleStationDetailAndEditFragment.start(getContext(), stationId, stationName, item.getProjectId(), null); + } else { + //StationSurveyorFragment原始测量页 + if (ProjectType.isConnection(item.projectType)) { + MeasureFragment.start(getContext(), stationId, stationName); + } else { + StationSurveyorFragment.start(getContext(), stationId, stationName); + } + } + }); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_list_layout, container, false); + if (view instanceof RecyclerView) { + recyclerView = (RecyclerView) view; + if (getArguments() != null) { + update(getArguments().getString(BundleConstants.KEY_PROJECT_ID), + getArguments().getString(KEY_TIME_INDEX)); + } + } + return view; + } + + /** + * 根据项目id和测期id获取测站记录 + * + * @param projectId + * @param periodId + */ + public void update(String projectId, String periodId) { + if (stationLiveData != null) { + stationLiveData.removeObservers(this); + } + + stationLiveData = SurveyorDatabaseFactory + .instance + .getSurveyorStation().getLiveDataList(projectId, periodId); + + stationLiveData.observe(getViewLifecycleOwner(), this::updateUi); + } + + private void updateUi(List dataList) { + runOnUI(() -> { + if (adapter == null) { + boolean detailOrSurveyor = false; + if (getArguments() != null) { + detailOrSurveyor = getArguments().getBoolean(KEY_DETAIL_OR_SURVEYOR, false); + } + boolean detailOrSurveyorFinal = detailOrSurveyor; + adapter = new SurveyorStationListAdapter(dataList, + getChildFragmentManager(), + getViewLifecycleOwner(), + runnable -> { + if (getActivity() != null) { + getActivity().runOnUiThread(runnable); + } + }, + getContext(), + item -> goStationMeasureOrDetail(item, detailOrSurveyorFinal), + detailOrSurveyor); + recyclerView.setAdapter(adapter); + } else { + adapter.updateData(dataList); + } + }); + } + + private static final String KEY_TIME_INDEX = "___time_index__"; + private static final String KEY_DETAIL_OR_SURVEYOR = "___editable___";//标识点击item进入测量界面还是测站详情 + + public static ComponentSurveyorStationListFragment newInstance(String projectId, String surveyorPeriodId, boolean isDetail) { + ComponentSurveyorStationListFragment fragment = new ComponentSurveyorStationListFragment(); + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(KEY_TIME_INDEX, surveyorPeriodId); + bundle.putBoolean(KEY_DETAIL_OR_SURVEYOR, isDetail); + fragment.setArguments(bundle); + return fragment; + } + + public static ComponentSurveyorStationListFragment newInstance(String projectId, String surveyorPeriodId) { + return newInstance(projectId, surveyorPeriodId, true); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java new file mode 100644 index 0000000..258a09b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java @@ -0,0 +1,148 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.widget.TextView; + +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; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 选择项目和测期的组件 + */ +public class ComponentSwitchStationListFragment extends AbstractHierarchicalListFragment { + private static final int INDEX_PROJECT_LIST = 0; + private static final int INDEX_CYCLE_LIST = 1; + private String projectId = ""; + private String projectName = ""; + private SelectableIndexWithTextAdapter> projectAdapter; + private SelectableIndexWithTextAdapter> periodAdapter; + + @Override + protected void onItemClicked(int currentListIndex, IUniversalListItem item) { + if (INDEX_PROJECT_LIST == currentListIndex) { + projectId = item.getId(); + projectName = item.getName(); + forward2(INDEX_CYCLE_LIST); + } else { + SelectProjectAndSurveyorCycleFragment.SelectedResult result = + new SelectProjectAndSurveyorCycleFragment.SelectedResult(projectId, projectName, item.getId(), item.getName()); + EventBus.getDefault().post(result); + } + } + + @Override + protected void onBackClicked(int currentListIndex) { + if (INDEX_CYCLE_LIST == currentListIndex) { + back2(INDEX_PROJECT_LIST); + } else { + //结束 + ToastUtils.showShort(R.string.cannot_go_back); + } + } + + @Override + protected void setupList(int listIndex, TextView title, RecyclerView recyclerView, + IndexWithTextAdapter.IOnItemClick> callback) { + if (INDEX_PROJECT_LIST == listIndex) { + //加载 + if (title != null) { + title.setText(Tools.getString(R.string.please_select_an_project)); + } + ThreadPoolUtil.execute(() -> { + List projectRecords = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getDataList(); + String selectedProject = ""; + if (getArguments() != null) { + selectedProject = getArguments().getString(KEY_PROJECT_ID); + } + List> items = new ArrayList<>(); + int targetIndex = 0; + for (int index = 0; index < projectRecords.size(); index++) { + ProjectRecord projectRecord = projectRecords.get(index); + Item item = new Item(projectRecord.getName(), projectRecord.getId()); + items.add(item); + if (selectedProject.equals(item.getId())) { + targetIndex = index; + } + } + int finalTargetIndex = targetIndex; + String finalSelectedProject = selectedProject; + ThreadPoolUtil.executeInMain(() -> { + if (projectAdapter == null) { + projectAdapter = new SelectableIndexWithTextAdapter<>(finalSelectedProject, items, callback); + recyclerView.setAdapter(projectAdapter); + } else { + projectAdapter.updateData(items); + } + recyclerView.scrollToPosition(finalTargetIndex); + }); + }); + } else if (INDEX_CYCLE_LIST == listIndex) { + //加载 + if (title != null) { + title.setText(Tools.getString(R.string.please_select_an_period)); + } + ThreadPoolUtil.execute(() -> { + List periodRecords = SurveyorDatabaseFactory.instance + .getSurveyorPeriod().getDataListSyncByProjectId(projectId); + List> items = new ArrayList<>(); + String selectedPeriodId = ""; + if (getArguments() != null) { + selectedPeriodId = getArguments().getString(KEY_CYCLE_ID); + } + int targetIndex = 0; + for (int index = 0; index < periodRecords.size(); index++) { + SurveyorPeriodRecord surveyorPeriodRecord = periodRecords.get(index); + Item item = new Item(surveyorPeriodRecord.getName(), surveyorPeriodRecord.getId()); + items.add(item); + if (selectedPeriodId.equals(item.getId())) { + targetIndex = index; + } + } + int finalTargetIndex = targetIndex; + if (periodAdapter == null) { + periodAdapter = new SelectableIndexWithTextAdapter<>(selectedPeriodId, items, callback); + ThreadPoolUtil.executeInMain(() -> { + recyclerView.setAdapter(periodAdapter); + recyclerView.scrollToPosition(finalTargetIndex); + }); + } else { + ThreadPoolUtil.executeInMain(() -> { + periodAdapter.updateData(items); + recyclerView.scrollToPosition(finalTargetIndex); + }); + } + }); + } + } + + private static final String KEY_PROJECT_ID = "___project_id"; + private static final String KEY_CYCLE_ID = "__cycle_id"; + + public static ComponentSwitchStationListFragment newInstance(String projectId, String cycleId) { + ComponentSwitchStationListFragment fragment = new ComponentSwitchStationListFragment(); + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_CYCLE_ID, cycleId); + fragment.setArguments(args); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java new file mode 100644 index 0000000..e833c46 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java @@ -0,0 +1,251 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +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.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; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + + +/** + * 选择限差模板的内容 + */ +public class ComponentSwitchToleranceFragment extends AbstractHierarchicalListFragment { + private static final int INDEX_GROUP = 0; + private static final int INDEX_LEVEL = 1; + private static final int INDEX_TOLERANCE = 2; + private String projectType = ""; + private String groupId = ""; + private String levelId = ""; + private String toleranceId = ""; + private SelectableIndexWithTextAdapter> adapterGroup = null; + private SelectableIndexWithTextAdapter> adapterLevel = null; + private SelectableIndexWithTextAdapter> adapterDetail = null; + + @Override + protected void onItemClicked(int currentListIndex, IUniversalListItem item) { + if (INDEX_GROUP == currentListIndex) { + groupId = item.getId(); + //检测目标group是否有level,如果没有直接进入detail + List levelRecordList = ToleranceLoadUtil.getToleranceLoad(projectType).levelListOf(projectType, groupId); + if (levelRecordList.isEmpty()) { + levelId = ""; + forward2(INDEX_TOLERANCE); + } else { + forward2(INDEX_LEVEL); + } + } else if (INDEX_LEVEL == currentListIndex) { + levelId = item.getId(); + forward2(INDEX_TOLERANCE); + } else { + 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) { + if (levelId == null || levelId.isEmpty()) { + return INDEX_GROUP; + } else { + return INDEX_LEVEL; + } + } + return super.preIndexOf(index); + } + + @Override + protected void onBackClicked(int currentListIndex) { + if (INDEX_TOLERANCE == currentListIndex) { + if (levelId == null || levelId.isEmpty()) { + back2(INDEX_GROUP); + } else { + back2(INDEX_LEVEL); + } + } else if (INDEX_LEVEL == currentListIndex) { + back2(INDEX_GROUP); + } else { + ToastUtils.showShort(R.string.cannot_go_back); + } + } + + @Override + protected void setupList(int listIndex, TextView title, RecyclerView recyclerView, + final IndexWithTextAdapter.IOnItemClick> callback) { + if (INDEX_GROUP == listIndex) { + if (title != null) { + title.setText(R.string.tips_please_select_tolerance_group); + } + List toleranceGroupRecords = ToleranceLoadUtil.getToleranceLoad(projectType).getGroupFromType(projectType); + List> items = new ArrayList<>(); + int targetIndex = 0; + IUniversalListItem customGroup = null; + int index = -1; + for (ToleranceGroupRecord toleranceGroupRecord : toleranceGroupRecords) { + if (toleranceGroupRecord.isDeleted()) { + continue; + } + if (ToleranceGroupConstants.VALUE_CUSTOM_GROUP.equals(toleranceGroupRecord.getId())) { + customGroup = toleranceGroupRecord; + continue; + } + index++; + items.add(toleranceGroupRecord); + if (groupId.equals(toleranceGroupRecord.getId())) { + targetIndex = index; + } + } + //添加自定义分组 + if (customGroup != null) { + items.add(customGroup); + if (groupId.equals(customGroup.getId())) { + targetIndex = items.size() - 1; + } + } + if (adapterGroup == null) { + adapterGroup = new SelectableIndexWithTextAdapter<>(groupId, items, callback); + } else { + adapterGroup.updateData(items); + } + recyclerView.setAdapter(adapterGroup); + recyclerView.scrollToPosition(targetIndex); + } else if (INDEX_LEVEL == listIndex) { + if (title != null) { + title.setText(R.string.tips_please_select_tolerance_level); + } + 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); + items.add(toleranceLevelRecord); + if (levelId != null && levelId.equals(toleranceLevelRecord.getId())) { + targetIndex = index; + } + } + if (adapterLevel == null) { + adapterLevel = new SelectableIndexWithTextAdapter<>(levelId, items, callback); + } else { + adapterLevel.updateData(items); + } + recyclerView.setAdapter(adapterLevel); + recyclerView.scrollToPosition(targetIndex); + } else if (INDEX_TOLERANCE == listIndex) { + ThreadPoolUtil.execute(() -> { + IToleranceDetailDataSource toleranceDetailDataSource = + SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + List toleranceDetailList; + int titleRes = R.string.tips_please_select_instrument_precision; + if (levelId == null || levelId.isEmpty()) {//自定义模板 + toleranceDetailList = ToleranceLoadUtil.getToleranceLoad(projectType).getDetailListByGroup(groupId); + //选择模板 + titleRes = R.string.tips_please_select_custom_tolerance; + } else { + 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<>(); + int targetIndex = 0; + for (int index = 0; index < toleranceDetailList.size(); index++) { + IToleranceDetail toleranceDetailRecordTj = toleranceDetailList.get(index); + items.add((IUniversalListItem) toleranceDetailRecordTj); + if (toleranceId.equals(toleranceDetailRecordTj.getId())) { + targetIndex = index; + } + } + int finalTargetIndex = targetIndex; + runOnUI(() -> { + if (adapterDetail == null) { + adapterDetail = new SelectableIndexWithTextAdapter<>(toleranceId, items, callback); + } else { + adapterDetail.updateData(items); + } + recyclerView.setAdapter(adapterDetail); + recyclerView.scrollToPosition(finalTargetIndex); + }); + }); + } + } + + private void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(KEY_PROJECT_TYPE); + groupId = getArguments().getString(KEY_GROUP); + levelId = getArguments().getString(KEY_LEVEL); + toleranceId = getArguments().getString(KEY_TOLERANCE); + } + } + + private static final String KEY_PROJECT_TYPE = "___PROJECT_TYPE___"; + private static final String KEY_GROUP = "___GROUP___"; + private static final String KEY_LEVEL = "___LEVEL___"; + private static final String KEY_TOLERANCE = "___PRECISION__"; + + public static ComponentSwitchToleranceFragment newInstance(String projectType, + String groupId, String levelId, String toleranceId) { + ComponentSwitchToleranceFragment fragment = new ComponentSwitchToleranceFragment(); + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_TYPE, projectType); + args.putString(KEY_GROUP, groupId); + args.putString(KEY_LEVEL, levelId); + args.putString(KEY_TOLERANCE, toleranceId); + fragment.setArguments(args); + return fragment; + } + + public static class SelectedToleranceEvent { + public final String toleranceId; + + public SelectedToleranceEvent(String toleranceId) { + this.toleranceId = toleranceId; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ConfigFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ConfigFragment.java new file mode 100644 index 0000000..4466902 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ConfigFragment.java @@ -0,0 +1,93 @@ +package com.bingce.controlnetwork.fragment; + +import android.graphics.Color; +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.fragment.app.Fragment; + +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.wedcel.dragexpandgrid.model.DargChildInfo; +import com.wedcel.dragexpandgrid.model.DragIconInfo; +import com.wedcel.dragexpandgrid.view.CustomAboveView; +import com.wedcel.dragexpandgrid.view.CustomGroup; + +import java.util.ArrayList; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.NoScrollView; +import com.bingce.controlnetwork.util.config.ConfigsSetConfigs; + +/** + * 主页面-管理 + */ +public class ConfigFragment extends Fragment { + private CustomGroup mCustomGroup; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_config, container, false); + mCustomGroup = rootView.findViewById(R.id.fragment_config_custom_group); + NoScrollView mScrollView = rootView.findViewById(R.id.fragment_config_custom_group_scrollview); + + if (SettingValueUtil.isThemeDark()) { + mScrollView.setBackgroundColor(Color.DKGRAY); + mCustomGroup.setNameTextColor(Color.WHITE); + } + return rootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mCustomGroup.setHasMoreIcon(false); + + ArrayList iconInfoList = new ArrayList<>(); + ConfigsSetConfigs.getInstance().foreach(item -> iconInfoList.add( + new DragIconInfo( + item.getId(), + getString(item.getTitle()), + item.getIcon(), + item.getCategory(), + false, + new ArrayList<>()))); + mCustomGroup.initIconInfo(iconInfoList); + + mCustomGroup.setCustomViewClickListener(new CustomAboveView.CustomAboveViewClickListener() { + @Override + public void onSingleClicked(DragIconInfo iconInfo) { + if (iconInfo == null) { + return; + } + ConfigsSetConfigs.getInstance().onItemClick(iconInfo.getId(), ConfigFragment.this); + } + + @Override + public void onChildClicked(DargChildInfo childInfo) { + } + }); +// mCustomGroup.setEditModelListener(new CustomGroup.InfoEditModelListener() { +// @Override +// public void onModelChanged(boolean isEditModel) { +// if (getActivity() instanceof MainActivity) { +//// ((MainActivity) getActivity()).getViewPager().setNoScroll(isEditModel); +// } +// mScrollView.setNoScroll(isEditModel); +// } +// }); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + } + + public CustomGroup getCustomGroup() { + return mCustomGroup; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/EmptyFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/EmptyFragment.java new file mode 100644 index 0000000..9ee70d0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/EmptyFragment.java @@ -0,0 +1,10 @@ +package com.bingce.controlnetwork.fragment; + +import com.bingce.controlnetwork.fragment.base.BaseFragment; + +/** + * Empty + */ +public class EmptyFragment extends BaseFragment { + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/FullLoadingFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/FullLoadingFragment.java new file mode 100644 index 0000000..6d6b02a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/FullLoadingFragment.java @@ -0,0 +1,83 @@ +package com.bingce.controlnetwork.fragment; + +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.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; + +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.R; + +public final class FullLoadingFragment extends AppCompatDialogFragment { + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_full_loading_layout, container, false); + if (getArguments() != null) { + String msg = getArguments().getString(KEY_MSG); + if (msg != null && !msg.isEmpty()) { + TextView tips = rootView.findViewById(R.id.tips); + if (tips != null) { + tips.setText(msg); + } + } + } + return rootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() != null) { + final Window window = getDialog().getWindow(); + + window.setWindowAnimations(R.style.animate_full_dialog); + window.setBackgroundDrawable(null); + + WindowManager.LayoutParams params = window.getAttributes(); + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.MATCH_PARENT; + window.setAttributes(params); + } + } + + @Override + public void onResume() { + super.onResume(); + if (getDialog() == null) { + return; + } + getDialog().setOnKeyListener((dialog, keyCode, event) -> { + // pass on to be processed as normal + return keyCode == android.view.KeyEvent.KEYCODE_BACK; // pretend we've processed it + }); + } + + private static final String KEY_MSG = "__KEY_MSG__"; + + public static DialogFragment showLoading(FragmentManager fragmentManager) { + return showLoading(fragmentManager, null); + } + + public static DialogFragment showLoading(FragmentManager fragmentManager, String msg) { + DialogFragment fragment = new FullLoadingFragment(); + if (msg != null && !msg.isEmpty()) { + Bundle args = new Bundle(); + args.putString(KEY_MSG, msg); + fragment.setArguments(args); + } + fragment.show(fragmentManager, FullLoadingFragment.class.getName()); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ListDialogFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ListDialogFragment.java new file mode 100644 index 0000000..cab9e36 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ListDialogFragment.java @@ -0,0 +1,173 @@ +package com.bingce.controlnetwork.fragment; + +import android.graphics.drawable.ColorDrawable; +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.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; + +public class ListDialogFragment extends DialogFragment { + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + Window window = getDialog().getWindow(); + window.setBackgroundDrawable(new ColorDrawable(0x00000000)); + window.setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_station_select_point_datasource_layout, container, false); + RecyclerView recyclerView = rootView.findViewById(R.id.list); + if (recyclerView != null && getArguments() != null) { + List list = getArguments().getStringArrayList(KEY_LIST); + _Adapter adapter = new _Adapter(list, (index, value) -> { + Bundle args = new Bundle(); + args.putInt(KEY_INDEX, index); + args.putString(KEY_RESULT, value); + getParentFragmentManager().setFragmentResult(TAG, args); + dismiss(); + }); + recyclerView.setAdapter(adapter); + } + TextView title = rootView.findViewById(R.id.title); + if (title != null && getArguments() != null) { + String string = getArguments().getString(KEY_TITLE); + if (string != null && string.isEmpty()) { + title.setText(string); + } + } + return rootView; + } + + private static class _VH extends RecyclerView.ViewHolder { + final TextView textView; + + public _VH(@NonNull @NotNull View itemView) { + super(itemView); + if (itemView instanceof TextView) { + textView = (TextView) itemView; + } else { + textView = null; + } + } + } + + private static class _Adapter extends RecyclerView.Adapter<_VH> { + private final List list; + private final IResultCallback resultCallback; + + _Adapter(List list, IResultCallback resultCallback) { + this.list = list; + this.resultCallback = resultCallback; + } + + @NonNull + @NotNull + @Override + public _VH onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + View rootView = LayoutInflater.from(parent.getContext()) + .inflate(android.R.layout.simple_list_item_1, parent, false); + return new _VH(rootView); + } + + @Override + public void onBindViewHolder(@NonNull @NotNull ListDialogFragment._VH holder, int position) { + String value = list.get(position); + if (holder.textView != null) { + holder.textView.setText(value); + holder.textView.setOnClickListener(v -> { + if (resultCallback != null) { + resultCallback.onResult(position, value); + } + }); + } + } + + @Override + public int getItemCount() { + return list == null ? 0 : list.size(); + } + } + + public interface IResultCallback { + void onResult(int index, String value); + } + + private static final String TAG = ListDialogFragment.class.getName(); + private static final String KEY_INDEX = "key_index"; + private static final String KEY_RESULT = "key value"; + private static final String KEY_LIST = "key list"; + private static final String KEY_TITLE = "KEY TITLE"; + + public static void showList(FragmentManager fragmentManager, + ArrayList list, + @NonNull LifecycleOwner lifecycleOwner, + IResultCallback callback) { +// DialogFragment fragment = new ListDialogFragment(); +// +// Bundle args = new Bundle(); +// args.putStringArrayList(KEY_LIST, list); +// fragment.setArguments(args); +// +// fragmentManager +// .setFragmentResultListener( +// TAG, +// lifecycleOwner, +// (requestKey, result) -> { +// if (TAG.equals(requestKey)) { +// callback.onResult(result.getInt(KEY_INDEX, -1), result.getString(KEY_RESULT)); +// } +// }); +// fragment.show(fragmentManager, TAG); + showList(fragmentManager, null, list, lifecycleOwner, callback); + } + + public static void showList(FragmentManager fragmentManager, + String title, + ArrayList list, + @NonNull LifecycleOwner lifecycleOwner, + IResultCallback callback) { + DialogFragment fragment = new ListDialogFragment(); + + Bundle args = new Bundle(); + args.putStringArrayList(KEY_LIST, list); + args.putString(KEY_TITLE, title); + fragment.setArguments(args); + + fragmentManager + .setFragmentResultListener( + TAG, + lifecycleOwner, + (requestKey, result) -> { + if (TAG.equals(requestKey)) { + callback.onResult(result.getInt(KEY_INDEX, -1), result.getString(KEY_RESULT)); + } + }); + fragment.show(fragmentManager, TAG); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt new file mode 100644 index 0000000..883bbf1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt @@ -0,0 +1,373 @@ +package com.bingce.controlnetwork.fragment + +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +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 +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentProjectSurveyorStationListLayoutBinding +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 com.bingce.controlnetwork.newui.stationlist.StationListFragment +import com.bingce.controlnetwork.newui.stationlist.StationListVm +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 测量首页 + */ +class MainSurveyFragment : BaseFragment() { + + private val mBinding get() = _binding!! + + private var _binding: FragmentProjectSurveyorStationListLayoutBinding? = null + + private val scope = MainScope() + + //筛选项目的项目类型 + private var selectProjectType: String? = null + + private val stationListVm by viewModels() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = + FragmentProjectSurveyorStationListLayoutBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + scope.cancel() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + SurveyorDatabaseFactory.instance + .configDataSource + .getLiveDataByKey(ConfigConstants.KEY_DEFAULT_PROJECT_ID) + .observe(viewLifecycleOwner) { configRecord -> + refreshUi(configRecord?.configValue) + } + + initListener() + } + + private fun initListener() { + mBinding.title.setOnClickListener { + BottomPageFragment.showBottom( + childFragmentManager, viewLifecycleOwner, + selectData, + object : BottomPageFragment.CallBack { + override fun back(selectData: List) { + scope.launch { + val title = getFilterTitle( + selectData[0].name, + selectData[1].name + ) + if (ProjectType.isHeightTraverse(selectProjectType)) { + switchContent( + title, + SurveyorRouteStationFragment.newInstance( + selectData[0].id, + selectData[1].id + ) + ) + } else if (ProjectType.isLevel(selectProjectType)) { + switchContent( + title, + LevelSurveyorHomeFragment.newInstance( + selectData[0].id, + selectData[1].id, + false + ) + ) + } else { + stationListVm.setArgument(selectData[0].id, selectData[1].id) + switchContent( + title, + StationListFragment() + ) + } + } + } + }) + } + } + + private val selectData = object : IData { + override suspend fun getData(bottomBean: BottomBean?): List { + val dataList: MutableList = ArrayList() + + if (bottomBean == null) { + //一级数据 + val projectRecords = SurveyorDatabaseFactory.instance + .projectDataSource + .dataList + for (projectRecord in projectRecords) { + dataList.add( + BottomBean( + projectRecord.getId(), projectRecord.getProjectName(), + 0 + ) + ) + } + } else { + if (bottomBean.pageIndex == 0) { + //二级数据 + val projectRecord = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(bottomBean.id) + 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 = 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 + ) + ) + } + } else { + val periodRecords = SurveyorDatabaseFactory.instance + .surveyorPeriod.getDataListSyncByProjectId(bottomBean.id) + for (periodItem in periodRecords) { + dataList.add( + BottomBean( + periodItem.getId(), periodItem.getName(), + 1, tag = selectProjectType + ) + ) + } + } + } + } + + return dataList + } + + override fun getTitle(pageIndex: Int): String { + return if (pageIndex == 0) { + Tools.getString(R.string.please_select_an_project) + } 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) + } + } else { + "" + } + } + } + + /** + * 刷新页面 + */ + private fun refreshUi(projectId: String?) { + scope.launch { + val projectRecord = getProjectRecord(projectId) + if (projectRecord == null) { + switchContent(null, null) + return@launch + } + val projectType = projectRecord.getProjectType() + if (ProjectType.isHeightTraverse(projectType)) { + loadHeightTraverseData(projectRecord) + } else if (ProjectType.isLevel(projectType)) { + loadLevelData(projectRecord) + } else { + loadNotHeightTraverseData(projectRecord) + } + } + } + + /** + * 加载三角导线和联系测量数据 + */ + private suspend fun loadNotHeightTraverseData(projectRecord: ProjectRecord) { + val cycleRecord = getPeriodRecord(projectRecord.getId()) + + val fragment = + if (cycleRecord == null) + EmptyFragment() + else { + stationListVm.setArgument(projectRecord.getId(), cycleRecord.getId()) + StationListFragment() + +// ComponentSurveyorStationListFragment.newInstance( +// projectRecord.getId(), +// cycleRecord.getId(), +// false +// ) + } + switchContent( + getFilterTitle(projectRecord.getProjectName(), cycleRecord?.getName()), + fragment + ) + } + + + /** + * 加载高程导线数据 + */ + private suspend fun loadHeightTraverseData(projectRecord: ProjectRecord) { + val routeRecord = getRouteRecord(projectRecord.getId()) + + val fragment = + if (routeRecord == null) + EmptyFragment() + else SurveyorRouteStationFragment.newInstance( + projectRecord.getId(), + routeRecord.getId() + ) + + switchContent( + getFilterTitle(projectRecord.getProjectName(), routeRecord?.routeName), + fragment + ) + } + + 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 + } + + private suspend fun switchContent(title: String?, fragment: Fragment?) { + withContext(Dispatchers.Main) { + setFilterTitle(title) + val targetFragment = fragment ?: EmptyFragment() + childFragmentManager + .beginTransaction() + .replace(R.id.fragment_container, targetFragment, null) + .commit() + } + } + + private fun setFilterTitle(title: String?) { + if (TextUtils.isEmpty(title)) { + mBinding.title.visibility = View.INVISIBLE + } else { + mBinding.title.visibility = View.VISIBLE + mBinding.titleView.text = title + } + } + + private suspend fun getProjectRecord(projectId: String?): ProjectRecord? { + return withContext(Dispatchers.IO) { + val projectRecord = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + if (projectRecord != null) { + return@withContext projectRecord + } + SurveyorDatabaseFactory.instance.projectDataSource.defaultRecordSync + } + } + + private suspend fun getPeriodRecord( + projectId: String, + ): SurveyorPeriodRecord? { + return withContext(Dispatchers.IO) { + val defaultPeriodId = SurveyorDatabaseFactory.instance + .configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_PERIOD_ID)?.configValue + val periodRecord = + SurveyorDatabaseFactory.instance.surveyorPeriod.getByIdAndProjectId( + defaultPeriodId, + projectId + ) + if (periodRecord != null) { + return@withContext periodRecord + } + SurveyorDatabaseFactory.instance.surveyorPeriod.getDefaultSync(projectId) + } + } + + private suspend fun getRouteRecord( + projectId: String, + ): RouteRecord? { + return withContext(Dispatchers.IO) { + val defaultRouteId = SurveyorDatabaseFactory.instance + .configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_ROUTE_ID)?.configValue + val routeRecord = + SurveyorDatabaseFactory.instance.getRouteDataSource() + .getByIdAndProjectId(defaultRouteId, projectId) + if (routeRecord != null) { + return@withContext routeRecord + } + SurveyorDatabaseFactory.instance.getRouteDataSource() + .getDefault(projectId) + } + } + + 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 new file mode 100644 index 0000000..6fb2bd0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PickPointFragment.java @@ -0,0 +1,239 @@ +package com.bingce.controlnetwork.fragment; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +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.ExpandableListView; + +import androidx.activity.result.ActivityResultLauncher; +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; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.KnownAndUnknownPoints; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.adapter.AbstractPointSelectAdapter; +import com.bingce.controlnetwork.adapter.PointSelectAdapter; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.utils.ThreadPoolUtil; + +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; + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + //读取数据类型 + int maxCount = -1; + if (getArguments() != null) { + maxCount = getArguments().getInt(KEY_MAX_COUNT, -1); + } + View view = inflater.inflate(R.layout.fragment_pick_point_bottom_sheet_layout, container, false); + if (view instanceof ExpandableListView) { + ExpandableListView expandableListView = (ExpandableListView) view; + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + List filterId = getArguments().getStringArrayList(KEY_FILTER); + PickPointResult pickPointResult = getArguments().getParcelable(BundleConstants.KEY_RESULT); + + int finalMaxCount1 = maxCount; + ThreadPoolUtil.execute(() -> { + IPointDataSource pointDataSource = + SurveyorDatabaseFactory.instance.getPointDataSource(); + //去掉全局控制点 +// List globalControlPoints = pointDataSource +// .getListByProjectId(PointRecordTj.GLOBAL_CONTROL_POINT_PROJECT_ID, PointRecordTj.TYPE_GLOBAL_POINT); + + KnownAndUnknownPoints knownAndUnknownPoints = + KnownAndUnknownPoints.loadData(false, filterId, projectId); + + List filterName = new ArrayList<>(); + if (filterId != null) { + for (String id : filterId) { + PointRecord record = pointDataSource.findByIdSync(id); + if (record == null) { + continue; + } + filterName.add(record.getName()); + } + } + + //过滤全局控制点 + List others = new ArrayList<>(); + //去掉全局控制点 +// 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()); + runOnUI(() -> { + expandableListView.setAdapter(adapter); + int groupCount = adapter.getGroupCount(); + for (int index = 0; index < groupCount; index++) { + expandableListView.expandGroup(index); + } + }); + }); +// 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; + } + + @Override + public void onCreateOptionsMenu(@NonNull @NotNull Menu menu, @NonNull @NotNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (item.getItemId() == R.id.menu_confirm) { + Intent intent = new Intent(); + PickPointResult pickPointResult = new PickPointResult(); + pickPointResult.setSelectedIds(adapter.getSelectedId()); + pickPointResult.setSelectedNames(adapter.getSelectedName()); + intent.putExtra(BundleConstants.KEY_RESULT, pickPointResult); + if (getArguments() != null) { + intent.putExtra(KEY_TYPE, getArguments().getString(KEY_TYPE)); + } + Activity activity = getActivity(); + if (activity != null) { + activity.setResult(Activity.RESULT_OK, intent); + activity.finish(); + } + } + return super.onOptionsItemSelected(item); + } + + public static final String KEY_TYPE = "__TYPE"; + private static final String KEY_FILTER = "__filter__id"; + private static final String KEY_MAX_COUNT = "__key__max_count"; + private static final String KEY_POINT_TYPE = "__point_type"; + + public static PickPointFragment newInstance(Bundle args) { + PickPointFragment pickPointFragment = new PickPointFragment(); + pickPointFragment.setArguments(args); + return pickPointFragment; + } + + public static ActivityResultLauncher createActivityLauncher(Fragment fragment, IOnSelectCallback selectCallback) { + return fragment.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result != null && Activity.RESULT_OK == result.getResultCode()) { + Intent intent = result.getData(); + if (intent != null) { + PickPointResult pickPointResult = intent.getParcelableExtra(BundleConstants.KEY_RESULT); + String type = intent.getStringExtra(KEY_TYPE); + selectCallback.onSelect(type, pickPointResult); + } + } + }); + } + + 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) { +// 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 { + void onSelect(String type, PickPointResult result); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PointFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PointFragment.java new file mode 100644 index 0000000..2b3fa73 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PointFragment.java @@ -0,0 +1,362 @@ +package com.bingce.controlnetwork.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 androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.FragmentPointLayoutBinding; +import com.bingce.utils.SoftKeyUtils; +import com.bingce.utils.ThreadPoolUtil; +import com.rengwuxian.materialedittext.MaterialEditText; + +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +import blankj.utilcode.util.ToastUtils; + +/** + * 新建或编辑点 + */ +public class PointFragment extends DialogFragment { + + private FragmentPointLayoutBinding mBinding; + + private PointFragment() { + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(STYLE_NORMAL, R.style.Dialog_FullScreen); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = FragmentPointLayoutBinding.inflate(inflater, container, false); + return mBinding.getRoot(); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initListener(); + initData(); + } + + private void initListener() { + + mBinding.getRoot().setOnClickListener(v -> dismissPointFragment()); + + mBinding.cancel.setOnClickListener(v -> dismissPointFragment()); + + mBinding.next.setOnClickListener(v -> checkSave(isCanSave -> { + if (!isCanSave) return; + saveCurrnetPoint(); + startNextPointPre(); + })); + + mBinding.confirm.setOnClickListener(v -> checkSave(isCanSave -> { + if (!isCanSave) return; + saveCurrnetPoint(); + dismissPointFragment(); + })); + + } + + private void startNextPointPre() { + runOnUI(() -> { + //编号+1 + String indexString = string(mBinding.number); + int index = 1; + try { + index = Integer.parseInt(indexString) + 1; + } catch (Exception ignored) { + ignored.printStackTrace(); + } + mBinding.number.setText(String.format(Locale.getDefault(), "%03d", index)); + clearXYZ(mBinding.pointX, mBinding.pointY, mBinding.pointZ); + }); + } + + @WorkerThread + private void saveCurrnetPoint() { + String pointName = pointName(mBinding.prefix, mBinding.number, mBinding.suffix); + + double x = doubleValue(mBinding.pointX); + double y = doubleValue(mBinding.pointY); + double z = doubleValue(mBinding.pointZ); + + if (isEdit()) { + String pointId = getPointId(); + PointRecord pointRecord = SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(pointId); + pointRecord.name = pointName; + pointRecord.x = x; + pointRecord.y = y; + pointRecord.z = z; + pointRecord.code = ""; + pointRecord.remarks = ""; + SurveyorDatabaseFactory.instance.getPointDataSource().update(pointRecord); + } else { + PointRecord pointRecord = PointRecord.point( + getProjectId(), getPointType(), pointName, "", x, y, z, "", -1); + SurveyorDatabaseFactory + .instance + .getPointDataSource() + .saveSync(pointRecord); + } + } + + /** + * 初始化编辑数据 + */ + private void initData() { + boolean isEdit = isEdit(); + + mBinding.title.setText(isEdit ? R.string.edit_point : R.string.new_point); + + if (isEdit) { + mBinding.number.setVisibility(View.GONE); + mBinding.suffix.setVisibility(View.GONE); + mBinding.next.setVisibility(View.GONE); + + setString(mBinding.prefix, getArguments(), KEY_POINT_NAME); + String label = getString(R.string.point_name); + mBinding.prefix.setFloatingLabelText(label); + mBinding.prefix.setHint(label); + + setDouble(mBinding.pointX, getArguments(), KEY_POINT_X); + setDouble(mBinding.pointY, getArguments(), KEY_POINT_Y); + setDouble(mBinding.pointZ, getArguments(), KEY_POINT_Z); + } + } + + private void runOnUI(Runnable runnable) { + if (getActivity() != null) { + getActivity().runOnUiThread(runnable); + } + } + + private void clearXYZ(MaterialEditText x, MaterialEditText y, MaterialEditText z) { + if (x != null) { + x.setText(null); + } + if (y != null) { + y.setText(null); + } + if (z != null) { + z.setText(null); + } + } + + private String string(MaterialEditText editText) { + if (editText == null || editText.getText() == null) { + return ""; + } + return editText.getText().toString(); + } + + private double doubleValue(MaterialEditText editText) { + String string = string(editText); + if (string.isEmpty()) { + return 0; + } + return Double.parseDouble(string); + } + + private void setString(MaterialEditText editText, Bundle args, String key) { + if (editText == null || args == null) { + return; + } + editText.setText(args.getString(key)); + } + + private void setDouble(MaterialEditText editText, Bundle args, String key) { + if (editText == null || args == null) { + return; + } + editText.setText(String.valueOf(args.getDouble(key))); + } + + private String pointName(final MaterialEditText prefix, + final MaterialEditText numberCome, + final MaterialEditText suffix) { + String number = string(numberCome); + if (number.isEmpty()) { + return string(prefix) + string(suffix); + } + long value = 0; + try { + value = Long.parseLong(number); + } catch (NumberFormatException ignored) { + + } + String result = String.format(Locale.getDefault(), "%s%03d%s", string(prefix), value, string(suffix)); + return result.replace(",", ""); + } + + private boolean checkXYValidate(MaterialEditText x, MaterialEditText y) { + return x != null && y != null && + x.getText() != null && y.getText() != null && + !x.getText().toString().isEmpty() && !y.getText().toString().isEmpty(); + } + + private static final String KEY_PROJECT_ID = "___project__id"; + private static final String KEY_POINT_TYPE = "___point_type__"; + private static final String KEY_POINT_NAME = "___point_name__"; + private static final String KEY_POINT_ID = "___point_id"; + private static final String KEY_POINT_X = "___point_x"; + private static final String KEY_POINT_Y = "___point_y"; + private static final String KEY_POINT_Z = "__point_z"; + + private static final String KEY_TYPE = "_TYPE_"; + private static final String VALUE_NEW = "___new___"; + private static final String VALUE_EDIT = "___edit___"; + + + public static void start(FragmentManager fragmentManager, + String projectId, + String pointType) { + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_POINT_TYPE, pointType); + show(fragmentManager, args); + } + + + public static void edit(FragmentManager fragmentManager, + String projectId, + String pointName, + String pointId, + String pointType, + double x, + double y, + double z) { + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_POINT_NAME, pointName); + args.putString(KEY_POINT_ID, pointId); + args.putString(KEY_POINT_TYPE, pointType); + + args.putDouble(KEY_POINT_X, x); + args.putDouble(KEY_POINT_Y, y); + args.putDouble(KEY_POINT_Z, z); + args.putString(KEY_TYPE, VALUE_EDIT); + + show(fragmentManager, args); + } + + + private static void show(FragmentManager fragmentManager, + Bundle args) { + PointFragment fragment = new PointFragment(); + if (args != null) { + fragment.setArguments(args); + } + fragment.show(fragmentManager, PointFragment.class.getName()); + } + + public interface ICallback { + void onGet(String pointName, double x, double y, double z); + } + + private void showPointSameNameDialogHint() { + ThreadPoolUtil.executeInMain(() -> { + //点名重复,提示 + TipsFragment.tipsOnly( + getChildFragmentManager(), + getViewLifecycleOwner(), + requireContext(), + Tools.getString(R.string.same_project_ponit_point_cannot_repeate)); + }); + } + + private boolean isEdit() { + if (getArguments() != null) { + return VALUE_EDIT.equals(getArguments().getString(KEY_TYPE, VALUE_NEW)); + } + return false; + } + + private String getProjectId() { + if (getArguments() != null) { + return getArguments().getString(KEY_PROJECT_ID); + } + return null; + } + + private String getPointId() { + if (getArguments() != null) { + return getArguments().getString(KEY_POINT_ID); + } + return null; + } + + private String getPointType() { + if (getArguments() != null) { + return getArguments().getString(KEY_POINT_TYPE); + } + return null; + } + + private boolean isKnownPoint(String pointType) { + return PointRecord.TYPE_KNOWN_POINT.equals(pointType) || PointRecord.TYPE_GLOBAL_POINT.equals(pointType); + } + + private void checkSave(ICallBackSave callBackSave) { + String pointName = pointName(mBinding.prefix, mBinding.number, mBinding.suffix);//string(prefix) + string(number) + string(suffix); + if (pointName.isEmpty()) { + ToastUtils.showShort(R.string.point_name_cannot_be_empty); + callBackSave.result(false); + return; + } + + if (isKnownPoint(getPointType()) && !checkXYValidate(mBinding.pointX, mBinding.pointY)) { + ToastUtils.showShort(R.string.error_tips_known_point_x_y_cannt_be_empty); + callBackSave.result(false); + return; + } + + ThreadPoolUtil.execute(() -> { + boolean sameName = PointUtil.isSameName(getProjectId(), pointName, getPointId()); + if (sameName) { + showPointSameNameDialogHint(); + callBackSave.result(false); + return; + } + callBackSave.result(true); + }); + } + + private void dismissPointFragment() { + runOnUI(() -> { + SoftKeyUtils.hideSoftKey(); + dismiss(); + }); + } + + private interface ICallBackSave { + void result(boolean isCanSave); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PointListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PointListFragment.java new file mode 100644 index 0000000..4d3b31a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PointListFragment.java @@ -0,0 +1,279 @@ +package com.bingce.controlnetwork.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.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +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.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.databinding.NewFragmentPointListBinding; +import com.bingce.controlnetwork.newui.adapter.PointListAdapter; +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding; +import com.bingce.controlnetwork.newui.createeditpoint.CreateEditPointActvity; +import com.bingce.controlnetwork.newui.widget.swipemenu.SwipeMenuEditDelete; +import com.bingce.controlnetwork.util.DialogUtil; +import com.bingce.controlnetwork.util.ImportPointsUtilPla; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.Collections; +import java.util.List; + + +/** + * 点列表 + */ +public class PointListFragment extends BaseFragmentBinding { + public static final String TAG = PointListFragment.class.getName(); + private final static String KEY_TYPE = "___KEY___"; + + // private PointRecordAdapter adapter; + private PointListAdapter adapter; + @NonNull + private final ImportPointsUtilPla importPointsUtil; + + /** + * 去未知点列表 + * + * @param projectId + * @param context + */ + public static void go2UnknownPointList(String projectId, String projectType, Context context) { + Bundle bundle = new Bundle(); + bundle.putString(KEY_TYPE, PointRecord.TYPE_UNKNOWN_POINT); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, R.string.project_unknown_points, bundle); + } + + /** + * 去已知点列表 + * + * @param projectId + * @param context + */ + public static void go2KnownPointList(String projectId, String projectType, Context context) { + Bundle bundle = new Bundle(); + bundle.putString(KEY_TYPE, PointRecord.TYPE_KNOWN_POINT); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, R.string.project_known_points, bundle); + } + + /** + * 去全局控制点 + * + * @param context + */ + public static void go2GlobalPointList(Context context) { + Bundle bundle = new Bundle(); + bundle.putString(KEY_TYPE, PointRecord.TYPE_GLOBAL_POINT); + bundle.putString(BundleConstants.KEY_PROJECT_ID, PointRecord.GLOBAL_CONTROL_POINT_PROJECT_ID); + FragmentContainerActivity.start(context, TAG, R.string.global_control_point, bundle); + } + + public static PointListFragment newInstance(Bundle bundle) { + PointListFragment fragment = new PointListFragment(); + fragment.setArguments(bundle); + return fragment; + } + + public PointListFragment() { + importPointsUtil = new ImportPointsUtilPla(this); + } + + /** + * 更新点列表 + * + * @param pointRecords + */ + private void updateData(List pointRecords) { + //排序 + Collections.sort(pointRecords, (o1, o2) -> { + if (o1.getCreateDate().before(o2.getCreateDate())) { + return -1; + } else if (o1.getCreateDate().after(o2.getCreateDate())) { + return 1; + } + if (o1.getOrderIndex() < o2.getOrderIndex()) { + return -1; + } else if (o1.getOrderIndex() > o2.getOrderIndex()) { + return 1; + } + return 0; + }); + + adapter.refreshData(pointRecords); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_import_and_clear, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int id = item.getItemId(); + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } + String pointType = getPonitType(); + String projectId = getProjectId(); + if (id == R.id.menu_item_import) { + //导入点 + importPoints(pointType, projectId); + } else if (id == R.id.menu_item_clear) { + //清空点 + clearPoints(pointType, projectId); + } + return super.onOptionsItemSelected(item); + } + + private String getPonitType() { + return requireArguments().getString(KEY_TYPE, PointRecord.TYPE_GLOBAL_POINT); + } + + private String getProjectId() { + return requireArguments().getString(BundleConstants.KEY_PROJECT_ID); + } + + private String getProjectType() { + return requireArguments().getString(BundleConstants.KEY_PROJECT_TYPE); + } + + /** + * 创建点 + */ + private void createPoints(String pointType, String projectId, String projectType) { + goCreateEditPointActvity(projectId, projectType, pointType, null); + } + + private void goCreateEditPointActvity(String projectId, String projectType, String pointType, PointRecord bean) { + CreateEditPointActvity.launch(requireContext(), projectId, projectType, + pointType, bean); + } + + /** + * 清空点 + */ + private void clearPoints(String pointType, String projectId) { + String hint = ""; + if (PointRecord.TYPE_KNOWN_POINT.equals(pointType)) { + hint = getString(R.string.tips_ready_2_clear_all_known_point); + } else if (PointRecord.TYPE_UNKNOWN_POINT.equals(pointType)) { + hint = getString(R.string.tips_ready_2_clear_all_unknown_point); + } + DialogUtil.showConfirmCountDownDialog(getChildFragmentManager(), getViewLifecycleOwner(), + hint, + Tools.getString(R.string.confirm), () -> SurveyorDatabaseFactory + .instance + .getPointDataSource() + .clearByProjectId(projectId, pointType)); + } + + /** + * 导入点 + */ + private void importPoints(String pointType, String projectId) { + importPointsUtil.showImportDialog(projectId, pointType); + } + + @Override + protected NewFragmentPointListBinding getViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) { + return NewFragmentPointListBinding.inflate(inflater, container, false); + } + + @Override + protected void initView() { + setHasOptionsMenu(true); + initAapter(); + initListener(); + } + + private void initListener() { + mBinding.tvNewPoint.setOnClickListener((v) -> { + //新建点 + if (getArguments() == null) { + return; + } + createPoints(getPonitType(), getProjectId(), getProjectType()); + }); + } + + private void initAapter() { + mBinding.ilSwipeList.swipeRecyclerView.addItemDecoration(new DefaultItemDecoration(Tools.getColor(R.color.transparent), 1, 1)); + mBinding.ilSwipeList.swipeRecyclerView.setSwipeMenuCreator(new SwipeMenuEditDelete(requireContext())); + mBinding.ilSwipeList.swipeRecyclerView.setOnItemMenuClickListener((menuBridge, adapterPosition) -> { + menuBridge.closeMenu(); + dealMenuClick(menuBridge.getPosition(), adapter.getBean(adapterPosition)); + }); + adapter = new PointListAdapter(requireContext()); + adapter.setProjectType(getProjectType()); + mBinding.ilSwipeList.swipeRecyclerView.setAdapter(adapter); + } + + /** + * @param menuPostion 编辑或删除的position + * @param bean 数据模型 + */ + private void dealMenuClick(int menuPostion, PointRecord bean) { + if (SwipeMenuEditDelete.isEditMenu(menuPostion)) { + startEdit(bean); + } else if (SwipeMenuEditDelete.isDeleteMenu(menuPostion)) { + startDelete(bean); + } + } + + private void startDelete(PointRecord bean) { + SurveyorDatabaseFactory + .instance + .getPointDataSource() + .delete(bean); + } + + private void startEdit(PointRecord bean) { + goCreateEditPointActvity(getProjectId(), getProjectType(), getPonitType(), bean); + } + + + @Override + protected void initData() { + if (getArguments() == null) { + return; + } + String pointType = getArguments().getString(KEY_TYPE, PointRecord.TYPE_GLOBAL_POINT); + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + + String projectType = getProjectType(); + ThreadPoolUtil.execute(() -> { + //是否是平面坐标 + boolean isPlatCoordinate = true; + if (ProjectType.isHeightTraverse(projectType)) { + isPlatCoordinate = false; + } + adapter.setIsPlatCoordinate(isPlatCoordinate); + getData(projectId, pointType); + }); + } + + private void getData(String projectId, String pointType) { + ThreadPoolUtil.executeInMain(() -> SurveyorDatabaseFactory + .instance + .getPointDataSource() + .getLiveDataListByProject(projectId, pointType) + .observe(getViewLifecycleOwner(), this::updateData)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManageFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManageFragment.java new file mode 100644 index 0000000..d398962 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManageFragment.java @@ -0,0 +1,159 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +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.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.prism.IPrismManagerDataSource; +import com.bingce.controlapphelper.datasource.database.prism.PrismConstants; +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord; +import com.bingce.controlnetwork.adapter.PrismMagegeAdapter; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.adapter.PrismMagegeAdapter; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit; +import com.bingce.controlnetwork.fragment.base.BaseFragment; + +/** + * 棱镜管理 + */ +public class PrismManageFragment extends BaseFragment { + + public static final String TAG = PrismManageFragment.class.getName(); + private PrismMagegeAdapter adapter = null; + private RecyclerView recyclerView; + + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_prism_manager, container, false); + recyclerView = rootView.findViewById(R.id.list); + View createButton = rootView.findViewById(R.id.create_new); + if (createButton != null) { + createButton.setOnClickListener(this::createCustom); + } + return rootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + } + + private void initData() { + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + prismManagerDataSource.getAllRecordLiveData().observe(getViewLifecycleOwner(), prismRecords -> { + if (prismRecords == null) return; + if (adapter == null) { + adapter = new _Adapter( + prismRecords, + item -> { + + }); + recyclerView.setAdapter(adapter); + } else { + adapter.updateData(prismRecords); + } + + + }); + + + } + + /** + * 创建自定义 + * + * @param view + */ + private void createCustom(View view) { + PrismManagerCreateCustomFragment.create(getChildFragmentManager(), getViewLifecycleOwner(), (nameBefore, name, typeLarge, constant) -> { + //选择完的结果 + ThreadPoolUtil.execute(() -> { + PrismRecord record = PrismRecord.createRecord(name, PrismConstants.TYPE_USER, constant, PrismRecord.MODIFY_ALLOW, typeLarge); + SurveyorDatabaseFactory.instance.getPrismManagerDataSource().saveRecord(record); + }); + }); + } + + private void editCustom(PrismRecord item) { + PrismManagerCreateCustomFragment.edit(getChildFragmentManager(), + getViewLifecycleOwner(), + item.prismTypeName, item.prismTypeLarge, item.prismTypeConstant, + (nameBefore, name, typeLarge, constant) -> ThreadPoolUtil.execute(() -> { + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + PrismRecord record = prismManagerDataSource.getPrismTypeNameSync(nameBefore); + if (record != null) { + record.prismTypeName = name; + record.prismType = PrismConstants.TYPE_USER; + record.prismTypeConstant = constant; + record.prismTypeLarge = typeLarge; + prismManagerDataSource.update(record); + } + })); + } + + private class _Adapter extends PrismMagegeAdapter { + public _Adapter( + List records, + IOnItemClick callback) { + super(records == null ? new ArrayList<>() : records, + callback, + new ContextMenuDeleteEdit() { + @Override + protected void delete(PrismRecord item) { + ThreadPoolUtil.execute(() -> { + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + prismManagerDataSource.delete(item); + }); + } + + @Override + protected void edit(PrismRecord item) { + editCustom(item); + } + }); + } + + + } + + /** + * 启动方法 + * + * @param context + */ + public static void start(Context context) { + Bundle bundle = new Bundle(); + FragmentContainerActivity.start(context, TAG, R.string.prism_manager, bundle); + } + + public static PrismManageFragment newInstance(Bundle bundle) { + PrismManageFragment fragment = new PrismManageFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManagerCreateCustomFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManagerCreateCustomFragment.java new file mode 100644 index 0000000..52db430 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManagerCreateCustomFragment.java @@ -0,0 +1,277 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.prism.IPrismManagerDataSource; +import com.bingce.controlapphelper.datasource.database.prism.PrismConstants; +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.SoftKeyUtils; +import com.bingce.utils.ThreadPoolUtil; +import com.rengwuxian.materialedittext.MaterialEditText; + +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 新建自定义棱镜类型 + */ +public class PrismManagerCreateCustomFragment extends DialogFragment { + + private final String[] spinnerData = {PrismConstants.TYPE_PRISM_LARGE, PrismConstants.TYPE_TAPE_LARGE}; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(STYLE_NORMAL, R.style.Dialog_FullScreen); + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_prism_manager_create_custom, container, false); + if (contentView != null) { + contentView.setOnClickListener(v -> { + SoftKeyUtils.hideSoftKey(); + dismiss(); + }); + String type = VALUE_NEW; + String prismTypeName = ""; + String prismTypeType = ""; + String prismTypeConstant = ""; + if (getArguments() != null) { + type = getArguments().getString(KEY_TYPE, VALUE_NEW); + prismTypeName = getArguments().getString(KEY_PRISM_TYPE_NAME); + prismTypeType = getArguments().getString(KEY_PRISM_TYPE_LARGE); + prismTypeConstant = getArguments().getString(KEY_PRISM_TYPE_CONSTANT); + } + //设置标题 + TextView title = contentView.findViewById(R.id.title); + if (title != null) { + if (VALUE_NEW.equals(type)) { + title.setText(Tools.getString(R.string.text_create_new_surveyor_station)); + } else if (VALUE_EDIT.equals(type)) { + title.setText(Tools.getString(R.string.menu_edit)); + } + } + + MaterialEditText etName = contentView.findViewById(R.id.etName); + Spinner spinner = contentView.findViewById(R.id.spinner); + MaterialEditText etContant = contentView.findViewById(R.id.etContant); + + List spinnerDataList = Arrays.asList(spinnerData); + spinner.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, spinnerDataList)); + + //编辑的时候重新赋值 + if (VALUE_EDIT.equals(type)) { + //设置值 + etName.setText(prismTypeName); + if (!TextUtils.isEmpty(prismTypeName)) { + etName.setSelection(prismTypeName.length()); + } + etContant.setText(prismTypeConstant); + spinner.setSelection(spinnerDataList.indexOf(prismTypeType)); + } + + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + + Button confirm = contentView.findViewById(R.id.confirm); + if (confirm != null) { + String finalPrismTypeNameBefore = prismTypeName; + String finalType = type; + confirm.setOnClickListener(v -> { + String name = string(etName); + if (name.isEmpty()) { + ToastUtils.showShort(R.string.name_is_required); + return; + } + String constant = string(etContant); + if (constant.isEmpty()) { + ToastUtils.showShort(R.string.absolute_constants_cannot_be_empty); + return; + } + double constantD = Double.parseDouble(constant); + if (constantD > 0) { + ToastUtils.showShort(R.string.absolute_constants_must_be_negative); + return; + } + + String selectedItem = (String) spinner.getSelectedItem(); + + //检测名称是否重复 + ThreadPoolUtil.execute(() -> { + PrismRecord prismRecord = prismManagerDataSource.getPrismTypeNameSync(name); + + if (VALUE_NEW.equals(finalType)) { + if (prismRecord != null) { + //点名重复,提示 + TipsFragment.tipsOnly( + getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + Tools.getString(R.string.custom_name_cannot_be_repeated)); + return; + } + } + + //1.新建没有重名 + //2.编辑 + runOnUI(() -> { + onCallback(finalPrismTypeNameBefore, name, selectedItem, constant, getParentFragmentManager()); + SoftKeyUtils.hideSoftKey(); + dismiss(); + }); + + + }); + }); + } + Button cancel = contentView.findViewById(R.id.cancel); + if (cancel != null) { + cancel.setOnClickListener(v -> { + SoftKeyUtils.hideSoftKey(); + dismiss(); + }); + } + + } + return contentView; + } + + private void runOnUI(Runnable runnable) { + if (getActivity() != null) { + getActivity().runOnUiThread(runnable); + } + } + + private PrismManagerCreateCustomFragment() { + } + + private static void onCallback( + final String nameBefore, + final String name, + final String type, + final String constant, + final FragmentManager fragmentManager) { + Bundle args = new Bundle(); + + args.putString(KEY_PRISM_TYPE_NAME_BEFORE, nameBefore); + args.putString(KEY_PRISM_TYPE_NAME, name); + args.putString(KEY_PRISM_TYPE_LARGE, type); + args.putString(KEY_PRISM_TYPE_CONSTANT, constant); + + fragmentManager.setFragmentResult(KEY_REQUEST_INPUT, args); + } + + private static String string(MaterialEditText editText) { + if (editText == null || editText.getText() == null) { + return ""; + } + return editText.getText().toString().trim(); + } + + private static double doubleValue(MaterialEditText editText) { + String string = string(editText); + if (string.isEmpty()) { + return 0; + } + return Double.parseDouble(string); + } + + private static void setString(MaterialEditText editText, Bundle args, String key) { + if (editText == null || args == null) { + return; + } + editText.setText(args.getString(key)); + } + + + private static final String KEY_PRISM_TYPE_NAME = "KEY_PRISM_TYPE_NAME"; + private static final String KEY_PRISM_TYPE_NAME_BEFORE = "KEY_PRISM_TYPE_NAME_BEFORE"; + private static final String KEY_PRISM_TYPE_LARGE = "KEY_PRISM_TYPE_LARGE"; + private static final String KEY_PRISM_TYPE_CONSTANT = "KEY_PRISM_TYPE_CONSTANT"; + + private static final String KEY_TYPE = "KEY_TYPE"; + private static final String VALUE_NEW = "___new___"; + private static final String VALUE_EDIT = "___edit___"; + + private static final String KEY_REQUEST_INPUT = "___request__code___"; + + public static void create(FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + @Nullable ICallback callback) { + Bundle args = new Bundle(); + show(fragmentManager, lifecycleOwner, args, callback); + } + + + public static void edit(FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + String prismTypeName, + String prismTypeLarge, + String prismTypeConstant, + @Nullable ICallback callback) { + Bundle args = new Bundle(); + args.putString(KEY_PRISM_TYPE_NAME, prismTypeName); + args.putString(KEY_PRISM_TYPE_LARGE, prismTypeLarge); + args.putString(KEY_PRISM_TYPE_CONSTANT, prismTypeConstant); + args.putString(KEY_TYPE, VALUE_EDIT); + + show(fragmentManager, lifecycleOwner, args, callback); + } + + + private static void show(FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + @Nullable Bundle args, + @Nullable ICallback callback) { + PrismManagerCreateCustomFragment fragment = new PrismManagerCreateCustomFragment(); + if (args != null) { + fragment.setArguments(args); + } + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_INPUT, + lifecycleOwner, + (key, result) -> { + if (KEY_REQUEST_INPUT.equals(key)) { + if (callback == null) { + return; + } + callback.onGet( + result.getString(KEY_PRISM_TYPE_NAME_BEFORE, ""), + result.getString(KEY_PRISM_TYPE_NAME, ""), + result.getString(KEY_PRISM_TYPE_LARGE, ""), + result.getString(KEY_PRISM_TYPE_CONSTANT, "") + ); + } + }); + fragment.show(fragmentManager, PrismManagerCreateCustomFragment.class.getName()); + } + + public interface ICallback { + void onGet(String nameBefore, String name, String typeLarge, String constant); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java new file mode 100644 index 0000000..a4a992a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java @@ -0,0 +1,274 @@ +package com.bingce.controlnetwork.fragment; + +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 androidx.annotation.NonNull; +import androidx.annotation.Nullable; +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.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.HorDividerDecoration; +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.jetbrains.annotations.NotNull; + +import java.util.List; + +import jp.wasabeef.recyclerview.animators.FadeInLeftAnimator; + +/** + * 主页面-项目 + */ +public class ProjectListFragment extends BaseFragment { + private ProjectListAdapter projectListAdapter; + private RecyclerView recyclerView; + private View createNewProject; + + @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; + } + + @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()); + recyclerView.addItemDecoration(new HorDividerDecoration(requireContext())); + + projectListAdapter = new ProjectListAdapter(requireContext()); + projectListAdapter.setAdapterContextMenu(new ContextMenuDeleteEdit() { + @Override + protected void delete(ProjectRecord item) { + startDeleteProject(item); + } + + @Override + protected void edit(ProjectRecord item) { + startEditProject(item); + } + }); + projectListAdapter.setOnItemClickListener(this::goProjectDetail); + recyclerView.setAdapter(projectListAdapter); + } + + private void initListener() { + //新建项目 + createNewProject.setOnClickListener(v -> { + //选择项目类型 + BaseSelectItemFragment.select(new SelectProjectTypeFragment(), + getChildFragmentManager(), + getViewLifecycleOwner(), + value -> goCreateOrEditProject(value, null)); + }); + } + + /** + * 去新建项目或编辑项目 + */ + 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()); + } + } + } + + private void initObserver() { + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getLiveDataList() + .observe(getViewLifecycleOwner(), this::addToleranceNameToProject); + } + + + private void addToleranceNameToProject(List projectRecords) { + ThreadPoolUtil.execute(() -> { + 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; + } + refreshAdapter(projectRecords); + }); + } + + private void refreshAdapter(List projectRecords) { + ThreadPoolUtil.executeInMain(() -> { + if (projectListAdapter != null) { + projectListAdapter.refreshData(projectRecords); + } + }); + } + + private void initView() { + initAdapter(); + } + + /** + * 进入项目详情 + */ + private void goProjectDetail(ProjectRecord item) { + 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 + public void onCreateOptionsMenu(@NotNull Menu menu, @NotNull MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.menu_activity_project_list, menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.menu_activity_project_list_help) { + 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/ProjectToleranceSettingFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectToleranceSettingFragment.java new file mode 100644 index 0000000..9083bd4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectToleranceSettingFragment.java @@ -0,0 +1,101 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.View; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +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.model.BundleConstants; +import com.bingce.controlapphelper.util.SurveyorRecordUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; +import com.bingce.utils.ThreadPoolUtil; + +import blankj.utilcode.util.ToastUtils; + +/* + * 项目限差详情,包含'LimitDetailFragment'+选择模板 + * */ +public class ProjectToleranceSettingFragment extends AbstractProjectToleranceFragment { + public static final int title = R.string.project_limite_detail; + public static final String TAG = ProjectToleranceSettingFragment.class.getName(); + + @Override + protected void onCurrentToleranceChanged(String toleranceId) { + super.onCurrentToleranceChanged(toleranceId); + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + ThreadPoolUtil.execute(() -> { + IProjectDataSource projectDataSource = + SurveyorDatabaseFactory.instance.getProjectDataSource(); + ProjectRecord projectRecord = projectDataSource.getRecord(projectId); + projectRecord.setToleranceId(toleranceId); + projectDataSource.saveRecordSync(projectRecord); + }); + } + + @Override + protected void onCreateView(View view) { + //读取当前项目配置的限差方案,并设置限差界面 + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + ThreadPoolUtil.execute(() -> { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory + .instance + .getProjectDataSource(); + ProjectRecord projectRecord = projectDataSource.getRecord(projectId); + if (projectRecord == null) { + return; + } + IToleranceOperate operate = ToleranceOperateUtil.getOperate(projectRecord.getToleranceId()); + + if (operate == null) { + IToleranceDetail defaultRecord = ToleranceLoadUtil.getToleranceLoad(projectType).getNewDefaultTolerance(projectType); + updateToleranceDetail(view, defaultRecord); + } else { + IToleranceDetail lastToleranceDetail = operate.getIToleranceDetail(projectRecord.getToleranceId()); + updateToleranceDetail(view, lastToleranceDetail); + } + }); + } + + @Override + protected void onSelectToleranceTemplateClick() { + //读取当前项目配置的限差方案,并设置限差界面 + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + //判断当前project是否存在已经测量的station + ThreadPoolUtil.execute(() -> { + if (SurveyorRecordUtil.isProjectSurveyor(projectId)) { + ToastUtils.showShort(R.string.tips_tolerance_cannt_modify); + } else { + ProjectToleranceSettingFragment.super.onSelectToleranceTemplateClick(); + } + }); + } + + public static void start(Context context, String projectId, String projectType) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, title, bundle); + } + + public static ProjectToleranceSettingFragment newInstance(Bundle bundle) { + ProjectToleranceSettingFragment fragment = new ProjectToleranceSettingFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportHeightTraverseFragment.kt new file mode 100644 index 0000000..5cc7222 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportHeightTraverseFragment.kt @@ -0,0 +1,270 @@ +package com.bingce.controlnetwork.fragment + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.MainThread +import androidx.fragment.app.DialogFragment +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.util.CheckStorageUtil +import com.bingce.controlapphelper.util.StationUtil.getStationName +import com.bingce.controlapphelper.util.StationUtil.getStationPointName +import com.bingce.controlapphelper.util.StationUtil.isStationCanExportForHeightTraverse +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.BuildConfig +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlnetwork.databinding.FragmentSelectExportSurveyorLayoutBinding +import com.bingce.controlnetwork.fragment.base.BaseFragment +import com.bingce.controlnetwork.surveyor.method.ExportUtilsPla +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode +import com.bingce.controlnetwork.ui.widget.treeview.TreeView +import com.bingce.controlnetwork.ui.widget.treeview.custom.MyNodeViewFactory +import com.bingce.file.FileOperator +import com.bingce.utils.ThreadPoolUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.io.File + + +class SelectExportHeightTraverseFragment : BaseFragment() { + + private var _binding: FragmentSelectExportSurveyorLayoutBinding? = null + val mBinding get() = _binding!! + + private val mainScope = MainScope() + + val root: TreeNode = TreeNode.root() + + private val treeView: TreeView by lazy { + TreeView(root, requireContext(), MyNodeViewFactory()) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentSelectExportSurveyorLayoutBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mBinding.export.isEnabled = true + + mBinding.export.setOnClickListener { + if (ExportUtilsPla.isCanExport()) { + requestStoragePermission() + } + } + + initData() + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + mainScope.cancel() + } + + private fun initData() { + mainScope.launch { + withContext(Dispatchers.IO) { + buildNodeTree() + } + treeView.setup(mBinding.list) + mBinding.list.visibility = View.VISIBLE + mBinding.loading.visibility = View.GONE + } + } + + private suspend fun buildNodeTree() { + val projectDataSource = SurveyorDatabaseFactory.instance.projectDataSource + val projectRecordList = projectDataSource.dataList + + for (projectRecord in projectRecordList) { + //遍历项目 + //一级数据 + val projectNode = + TreeNode(TreeNode.Value(projectRecord.projectName, projectRecord.id), 0) + + val routeList = SurveyorDatabaseFactory.instance.getRouteDataSource() + .getByProjectId(projectRecord.getId()) + + var projectHasData = false + + for (routeRecord in routeList) { + //遍历路线 + //二级数据 + val periodNode = + TreeNode(TreeNode.Value(routeRecord.name, routeRecord.id), 1) + + val stationList = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRoute( + projectRecord.getId(), + routeRecord.getId() + ) + + var routeHasData = false + + for (stationRecord in stationList) { + //遍历测站 + if (stationRecord == null) { + continue + } + + val exportItem = ExportUtilsPla.ExportItem( + projectRecord.getProjectName(), projectRecord.getId(), + projectRecord.projectType, + routeRecord.getId(), routeRecord.name, + stationRecord.getId(), + getStationName(stationRecord), + getStationPointName(stationRecord) + ) + + //三级数据 + val stationNode = TreeNode( + TreeNode.Value(exportItem, stationRecord.getId()), + 2 + ) + //添加三级数据 + periodNode.addChild(stationNode) + + val stationCanExport = isStationCanExportForHeightTraverse(stationRecord) + stationNode.isEnable = stationCanExport + if (stationCanExport) { + projectHasData = true + routeHasData = true + } + } + + //添加二级数据 + periodNode.isEnable = routeHasData + projectNode.addChild(periodNode) + + } + + projectNode.isEnable = projectHasData + //添加一级数据 + root.addChild(projectNode) + } + + } + + companion object { + @JvmField + val TAG: String = SelectExportHeightTraverseFragment::class.java.name + + @JvmStatic + fun newInstance(args: Bundle?): SelectExportHeightTraverseFragment { + val fragment = SelectExportHeightTraverseFragment() + fragment.arguments = args + return fragment + } + + @JvmStatic + fun start(context: Context) { + FragmentContainerActivity.start( + context, + TAG, + R.string.export_height_traverse, + null + ) + } + + } + + + private fun requestStoragePermission() { + CheckStorageUtil.check(context) { exportHasPermission() } + } + + private fun exportHasPermission() { + val dialogFragment: DialogFragment = FullLoadingFragment.showLoading(childFragmentManager) + doExport(root, requireContext(), object : ICallback { + override fun onFailureInMainThread(msg: String?) { + dialogFragment.dismiss() + ToastUtils.showShort(R.string.tips_please_select_exported_data) + } + + override fun onSuccessInMainThread(zip: File) { + if (dialogFragment.isVisible) { + dialogFragment.dismiss() + } + TipsWith2OptionFragment.tipsCannotCancel( + childFragmentManager, viewLifecycleOwner, + getString(R.string.share), + getString(R.string.cancel), + getString(R.string.export_successful), + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + FileOperator.shareFile(context, zip, BuildConfig.APPLICATION_ID) + } + }) + } + }) + } + + private interface ICallback { + fun onFailureInMainThread(msg: String?) + fun onSuccessInMainThread(zip: File) + } + + @MainThread + private fun doExport( + root: TreeNode, + context: Context, + callback: ICallback + ) { + ThreadPoolUtil.execute { + + //层遍历node树,找到所有被选中的station + val exportItem: MutableList = + ArrayList() + val nodeList: MutableList = + ArrayList() + nodeList.add(root) + while (!nodeList.isEmpty()) { + val first = nodeList.removeAt(0) + if (first.isEnable && first.isSelected && first.value + .value is ExportUtilsPla.ExportItem + ) { + exportItem.add(first.value.value as ExportUtilsPla.ExportItem) + } + nodeList.addAll(first.children) + } + if (exportItem.isEmpty()) { + if (callback != null) { + ThreadPoolUtil.executeInMain { + callback.onFailureInMainThread( + context.getString( + R.string.error_tips_please_select_exported_station + ) + ) + } + } + return@execute + } + + //执行导出 + val zip = ExportUtilsPla.doExportHeightTraverse(context, exportItem) + //提示导出成功 + ThreadPoolUtil.executeInMain { + if (zip == null) { + callback.onFailureInMainThread(Tools.getString(R.string.export_failure)) + } else { + callback.onSuccessInMainThread(zip) + } + } + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordFragment.java new file mode 100644 index 0000000..179f50e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordFragment.java @@ -0,0 +1,246 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.ISurveyorPeriodDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.BuildConfig; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.newui.configfragment.SelectExportType; +import com.bingce.controlnetwork.surveyor.method.ExportUtilsPla; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.TreeView; +import com.bingce.controlnetwork.ui.widget.treeview.custom.MyNodeViewFactory; +import com.bingce.file.FileOperator; +import com.bingce.utils.ThreadPoolUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 观测数据导出(基于选择的站的点数据导出) + */ +public class SelectExportSurveyorRecordFragment extends BaseFragment { + public static final String TAG = SelectExportSurveyorRecordFragment.class.getName(); + private TreeNode root; + private TreeView treeView; + private boolean isOpen = false; + + public static final String KEY_DATA = "key_data"; + private ArrayList selectExportTypeList; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + root = TreeNode.root(); + if (getContext() != null) { + treeView = new TreeView(root, getContext(), new MyNodeViewFactory()); + } + View rootView = inflater.inflate(R.layout.fragment_select_export_surveyor_layout, container, false); + View exportBtn = rootView.findViewById(R.id.export); + exportBtn.setEnabled(true); + + exportBtn.setOnClickListener(v -> { + if (ExportUtilsPla.isCanExport()) { + requestStoragePermission(); + } + }); + + ThreadPoolUtil.execute(() -> { + buildNodeTree(root); + ThreadPoolUtil.executeInMain(() -> { + RecyclerView list = rootView.findViewById(R.id.list); + treeView.setup(list); + list.setVisibility(View.VISIBLE); + View loading = rootView.findViewById(R.id.loading); + loading.setVisibility(View.GONE); + }); + }); + return rootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + selectExportTypeList = getSelectExportTypeList(); + } + + @MainThread + private void doExport(TreeNode root, + Context context, + ICallback callback) { + ThreadPoolUtil.execute(() -> { + //层遍历node树,找到所有被选中的station + List exportItem = new ArrayList<>(); + List nodeList = new ArrayList<>(); + nodeList.add(root); + while (!nodeList.isEmpty()) { + TreeNode first = nodeList.remove(0); + if (first.isEnable() && first.isSelected() && first.getValue().getValue() instanceof ExportUtilsPla.ExportItem) { + exportItem.add((ExportUtilsPla.ExportItem) first.getValue().getValue()); + } + nodeList.addAll(first.getChildren()); + } + if (exportItem.isEmpty()) { + if (callback != null) { + ThreadPoolUtil.executeInMain(() -> callback.onFailureInMainThread(context.getString(R.string.error_tips_please_select_exported_station))); + } + return; + } + + //执行导出 + File zip = ExportUtilsPla.doExport(context, exportItem, selectExportTypeList); + //提示导出成功 + if (callback != null) { + ThreadPoolUtil.executeInMain(() -> { + if (zip == null) { + callback.onFailureInMainThread(Tools.getString(R.string.export_failure)); + } else { + callback.onSuccessInMainThread(zip); + } + }); + } + }); + } + + private interface ICallback { + void onFailureInMainThread(String msg); + + void onSuccessInMainThread(File zip); + } + + /** + * 根据 + *

+ * (项目->测期->测站) + *

+ * 三级结构,构建node树 + *

+ * 检测每个测站数据是否正常记录,如果没有则将其设置为不可选中状态 + * + * @param root node树的根节点 + */ + @WorkerThread + private static void buildNodeTree(TreeNode root) { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + List projectRecordList = projectDataSource.getDataList(); + for (ProjectRecord projectRecord : projectRecordList) {//遍历项目 + TreeNode projectNode = + new TreeNode(new TreeNode.Value(projectRecord.projectName, projectRecord.id), 0); + ISurveyorPeriodDataSource surveyorPeriodDataSource = SurveyorDatabaseFactory.instance.getSurveyorPeriod(); + List surveyorPeriodRecordList = surveyorPeriodDataSource.getDataListSyncByProjectId(projectRecord.getId()); + + boolean projectHasData = false; + for (SurveyorPeriodRecord periodRecord : surveyorPeriodRecordList) {//遍历测期 + TreeNode periodNode = new TreeNode(new TreeNode.Value(periodRecord.getName(), periodRecord.id), 1); + ISurveyorStationDataSource surveyorStationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List stationRecordList = surveyorStationDataSource.getDataList(projectRecord.getId(), periodRecord.getId()); + + boolean periodHasData = false; + for (SurveyorStationRecord stationRecord : stationRecordList) {//遍历测站 + if (stationRecord == null) { + continue; + } + ExportUtilsPla.ExportItem exportItem = + new ExportUtilsPla.ExportItem(projectRecord.getProjectName(), projectRecord.getId(), + projectRecord.projectType, + periodRecord.getId(), periodRecord.getName(), + stationRecord.getId(), + StationUtil.getStationName(stationRecord), + StationUtil.getStationPointName(stationRecord)); + TreeNode stationNode = new TreeNode(new TreeNode.Value(exportItem, stationRecord.getId()), + 2); + periodNode.addChild(stationNode); + + boolean stationCanExport = StationUtil.isStationCanExport(stationRecord); + stationNode.setEnable(stationCanExport); + if (stationCanExport) { + projectHasData = true; + periodHasData = true; + } + } + + periodNode.setEnable(periodHasData); + projectNode.addChild(periodNode); + } + + projectNode.setEnable(projectHasData); + root.addChild(projectNode); + } + } + + public static SelectExportSurveyorRecordFragment newInstance(Bundle args) { + SelectExportSurveyorRecordFragment fragment = new SelectExportSurveyorRecordFragment(); + fragment.setArguments(args); + return fragment; + } + + public static void start(Context context, Bundle bundle) { + FragmentContainerActivity.start(context, TAG, R.string.export, bundle); + } + + public void requestStoragePermission() { + CheckStorageUtil.check(getContext(), this::exportHasPermission); + } + + private void exportHasPermission() { + DialogFragment dialogFragment = FullLoadingFragment.showLoading(getChildFragmentManager()); + doExport(root, getContext(), new ICallback() { + @Override + public void onFailureInMainThread(String msg) { + dialogFragment.dismiss(); + ToastUtils.showShort(R.string.tips_please_select_exported_data); + } + + @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 ArrayList getSelectExportTypeList() { + Bundle arguments = getArguments(); + if (arguments != null) { + return arguments.getParcelableArrayList(KEY_DATA); + } + return null; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordWireFileFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordWireFileFragment.java new file mode 100644 index 0000000..a50e0b2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordWireFileFragment.java @@ -0,0 +1,295 @@ +package com.bingce.controlnetwork.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.MainThread; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.ISurveyorScheduleDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.ISurveyorPeriodDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.surveyor.method.ExportUtils; +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.BuildConfig; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.surveyor.method.ExportUtilsPla; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.TreeView; +import com.bingce.controlnetwork.ui.widget.treeview.custom.MyNodeViewFactory; +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.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import blankj.utilcode.util.FileUtils; +import blankj.utilcode.util.ToastUtils; + +/** + * 导线文件导出(基于选择的导线数据导出) + */ +public class SelectExportSurveyorRecordWireFileFragment extends BaseFragment { + public static final String TAG = SelectExportSurveyorRecordWireFileFragment.class.getName(); + private TreeNode root; + private TreeView treeView; + private boolean isOpen = false; + private Date currentDate, expireDate; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + root = TreeNode.root(); + if (getContext() != null) { + treeView = new TreeView(root, getContext(), new MyNodeViewFactory()); + } + View rootView = inflater.inflate(R.layout.fragment_select_export_surveyor_layout, container, false); + View exportBtn = rootView.findViewById(R.id.export); + exportBtn.setEnabled(true); + exportBtn.setOnClickListener(v -> { + if (ExportUtilsPla.isCanExport()) { + requestStoragePermission(); + } + }); + + ThreadPoolUtil.execute(() -> { + buildNodeTree(root); + ThreadPoolUtil.executeInMain(() -> { + RecyclerView list = rootView.findViewById(R.id.list); + treeView.setup(list); + list.setVisibility(View.VISIBLE); + View loading = rootView.findViewById(R.id.loading); + loading.setVisibility(View.GONE); + }); + }); + return rootView; + } + + @MainThread + private static void doExport(TreeNode root, + Context context, + ICallback callback) { + ThreadPoolUtil.execute(() -> { + //层遍历node树,找到所有被选中的station + List exportItem = new ArrayList<>(); + List nodeList = new ArrayList<>(); + nodeList.add(root); + while (!nodeList.isEmpty()) { + TreeNode first = nodeList.remove(0); + if (first.isEnable() && first.isSelected() && first.getValue().getValue() instanceof ExportUtils.ExportItem) { + exportItem.add((ExportUtils.ExportItem) first.getValue().getValue()); + } + nodeList.addAll(first.getChildren()); + } + if (exportItem.isEmpty()) { + if (callback != null) { + ThreadPoolUtil.executeInMain(() -> callback.onFailureInMainThread(context.getString(R.string.error_tips_please_select_exported_station))); + } + return; + } + + //获取测站测期的完整数据列表 +// List exportCompleteLoopList = getExportProjectPeridList(root); + + //执行导出 + String exportFolder = "控制测量电子手薄导出文件" + File.separator + "导线文件导出"; + List files = ExportUtils.doExportWire(context, exportItem, exportFolder); + + //将文件存储到一个zip中 + String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath(); +// File appSharedFolder = PathManager.appDocumentFolder(); + 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(absolutePath, exportFolder + File.separator + dateString + ".zip"); + if (!ZipUtil.zip(zip, files)) { + zip = null; + } + //存储成功,删除zip文件 + for (File file : files) { + if (file == null) { + continue; + } + FileUtils.delete(file); + } + + //提示导出成功 + if (callback != null) { + File finalZip = zip; + ThreadPoolUtil.executeInMain(() -> { + if (finalZip == null) { + callback.onFailureInMainThread(Tools.getString(R.string.export_failure)); + } else { + callback.onSuccessInMainThread(finalZip); + } + }); + } + }); + } + + private interface ICallback { + void onFailureInMainThread(String msg); + + void onSuccessInMainThread(File zip); + } + + /** + * 根据 + *

+ * (项目->测期->测站) + *

+ * 三级结构,构建node树 + *

+ * 检测每个测站数据是否正常记录,如果没有则将其设置为不可选中状态 + * + * @param root node树的根节点 + */ + @WorkerThread + private static void buildNodeTree(TreeNode root) { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + List projectRecordList = projectDataSource.getDataList(); + //遍历项目 + for (ProjectRecord projectRecord : projectRecordList) { + //创建项目节点 + TreeNode projectNode = + new TreeNode(new TreeNode.Value(projectRecord.projectName, projectRecord.id), 0); + ISurveyorPeriodDataSource surveyorPeriodDataSource = SurveyorDatabaseFactory.instance.getSurveyorPeriod(); + List surveyorPeriodRecordList = surveyorPeriodDataSource.getDataListSyncByProjectId(projectRecord.getId()); + boolean projectHasData = false; + //遍历测期 + for (SurveyorPeriodRecord periodRecord : surveyorPeriodRecordList) { + //创建测期节点 + TreeNode periodNode = new TreeNode(new TreeNode.Value(periodRecord.getName(), periodRecord.id), 1); + ISurveyorStationDataSource surveyorStationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List stationRecordList = surveyorStationDataSource.getDataList(projectRecord.getId(), periodRecord.getId()); + ISurveyorScheduleDataSource surveyorScheduleDataSource = SurveyorDatabaseFactory.instance.getScheduleDataSource(); + + boolean periodHasData = false; + //遍历测站 + if (stationRecordList == null || stationRecordList.isEmpty()) { + continue; + } + + //初始化导线数据map + Map lineMap = new HashMap<>(); + for (SurveyorStationRecord stationRecord : stationRecordList) { + if (stationRecord == null) { + continue; + } + String lineId = stationRecord.getLineId(); + LineRecord lineRecord = SurveyorDatabaseFactory.instance.getLineRecordDatabase().findById(lineId); + if (lineRecord == null) { + continue; + } + if (LineRecord.TYPE_MUL_ANGLE.equals(StationUtil.getLineTypeFromStation(stationRecord))) { + //排除多测回测角 + continue; + } + if (lineMap.containsKey(lineId)) { + LineRecord lineRecordAlready = lineMap.get(lineId); + if (lineRecordAlready != null && lineRecordAlready.isCanSelected) { + lineRecordAlready.isCanSelected = StationUtil.isStationCanExport(stationRecord); + } + } else { + lineRecord.isCanSelected = StationUtil.isStationCanExport(stationRecord); + lineMap.put(lineId, lineRecord); + } + } + + //添加第三节点 导线 + for (LineRecord lineRecord : lineMap.values()) { + ExportUtils.ExportItem exportItem = + new ExportUtils.ExportItem(projectRecord.getProjectName(), projectRecord.getId(), + projectRecord.projectType, + periodRecord.getId(), periodRecord.getName(), + lineRecord.id, + lineRecord.name, + ""); + TreeNode lineNode = new TreeNode(new TreeNode.Value(exportItem, lineRecord.id), + 2); + + lineNode.setEnable(lineRecord.isCanSelected); + periodNode.addChild(lineNode); + + if (lineRecord.isCanSelected) { + projectHasData = true; + periodHasData = true; + } + } + + periodNode.setEnable(periodHasData); + projectNode.addChild(periodNode); + } + + projectNode.setEnable(projectHasData); + root.addChild(projectNode); + } + } + + public static SelectExportSurveyorRecordWireFileFragment newInstance(Bundle args) { + SelectExportSurveyorRecordWireFileFragment fragment = new SelectExportSurveyorRecordWireFileFragment(); + fragment.setArguments(args); + return fragment; + } + + public static void start(Context context) { + FragmentContainerActivity.start(context, TAG, R.string.export_wire_file, null); + } + + public void requestStoragePermission() { + CheckStorageUtil.check(getContext(), this::exportHasPermission); + } + + private void exportHasPermission() { + DialogFragment dialogFragment = FullLoadingFragment.showLoading(getChildFragmentManager()); + doExport(root, getContext(), new SelectExportSurveyorRecordWireFileFragment.ICallback() { + @Override + public void onFailureInMainThread(String msg) { + dialogFragment.dismiss(); + ToastUtils.showShort(R.string.tips_please_select_exported_data); + } + + @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); + } + }); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectProjectAndSurveyorCycleFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectProjectAndSurveyorCycleFragment.java new file mode 100644 index 0000000..f2ace7d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectProjectAndSurveyorCycleFragment.java @@ -0,0 +1,163 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.R; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; + +/** + * 弹框,先选项目,再选测期 + */ +public class SelectProjectAndSurveyorCycleFragment extends DialogFragment { + public static final String TAG = SelectProjectAndSurveyorCycleFragment.class.getName(); + private ComponentSwitchStationListFragment componentSwitchStationListFragment; + + private SelectProjectAndSurveyorCycleFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate(R.layout.fragment_single_framelayout_layout, + container, + false); + String currentProjectId = ""; + String cycleId = ""; + if (getArguments() != null) { + currentProjectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + cycleId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + } + + componentSwitchStationListFragment = + ComponentSwitchStationListFragment.newInstance(currentProjectId, cycleId); + + getChildFragmentManager() + .beginTransaction() + .replace(R.id.container, componentSwitchStationListFragment) + .commit(); + + view.setOnClickListener(v -> dismiss()); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + if (getDialog() != null) { + final Window window = getDialog().getWindow(); + + window.setWindowAnimations(R.style.animate_dialog); + window.setBackgroundDrawable(null); + + WindowManager.LayoutParams params = window.getAttributes(); + params.gravity = Gravity.BOTTOM; + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + window.setAttributes(params); + } + } + + @Override + public void onStart() { + super.onStart(); + EventBus.getDefault().register(this); + getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() { + @Override + public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { + if ((keyCode == android.view.KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)) { + if (!componentSwitchStationListFragment.doBack()) { + dismiss(); + } + return true; + } + return false; + } + }); + } + + @Override + public void onStop() { + super.onStop(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(SelectedResult event) { + Bundle args = new Bundle(); + args.putString(BundleConstants.KEY_PROJECT_ID, event.projectId); + args.putString(BundleConstants.KEY_PROJECT_NAME, event.projectName); + args.putString(BundleConstants.KEY_PERIOD_ID, event.cycleId); + args.putString(BundleConstants.KEY_PERIOD_NAME, event.cycleName); + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + } + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String defaultProjectId, + String defaultToleranceId, + IOnSelectCallback callback) { + Bundle args = new Bundle(); + args.putString(BundleConstants.KEY_PROJECT_ID, defaultProjectId); + args.putString(BundleConstants.KEY_PERIOD_ID, defaultToleranceId); + SelectProjectAndSurveyorCycleFragment fragment = new SelectProjectAndSurveyorCycleFragment(); + fragment.setArguments(args); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected( + result.getString(BundleConstants.KEY_PROJECT_ID), + result.getString(BundleConstants.KEY_PROJECT_NAME), + result.getString(BundleConstants.KEY_PERIOD_ID), + result.getString(BundleConstants.KEY_PERIOD_NAME)); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IOnSelectCallback { + void onSurveyorCycleSelected(String projectId, String projectName, String cycleId, String cycleName); + } + + public static class SelectedResult { + public final String projectId; + public final String projectName; + public final String cycleId; + public final String cycleName; + + public SelectedResult(String projectId, String projectName, + String cycleId, String cycleName) { + this.projectId = projectId; + this.projectName = projectName; + this.cycleId = cycleId; + this.cycleName = cycleName; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorCycleFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorCycleFragment.java new file mode 100644 index 0000000..34653b5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorCycleFragment.java @@ -0,0 +1,139 @@ +package com.bingce.controlnetwork.fragment; + +import android.app.Dialog; +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.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.ReSurveyorCycleAdapter; +import com.bingce.controlnetwork.databinding.FragmentResurveryorLayoutCycleBinding; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.adapter.ReSurveyorCycleAdapter; + +/** + * 高程导线 + * 选择要重测的测回 + */ +public class SelectReSurveyorCycleFragment extends BaseBottomSheetDialogFragment { + private FragmentResurveryorLayoutCycleBinding mBinding; + + private int resultCycleIndex = -1; + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + mBinding = FragmentResurveryorLayoutCycleBinding.inflate(inflater, container, false); + + List> items = new ArrayList<>(); + + if (getArguments() != null) { + int cycleCount = getArguments().getInt(KEY_CYCLE_COUNT, 0); + for (int i = 0; i < cycleCount; i++) { + UniversalListItem item = new UniversalListItem() { + @Override + public ViewItemType getType() { + return ViewItemType.indexWithName; + } + }; + item.setName(Tools.getString(R.string.test_n_cycle, (i + 1))); + items.add(item); + } + } + + ReSurveyorCycleAdapter adapter = new ReSurveyorCycleAdapter(items, cycleIndex -> { + resultCycleIndex = cycleIndex; + }); + mBinding.list.setAdapter(adapter); + + mBinding.confirm.setOnClickListener(v -> { + if (resultCycleIndex == -1) { + ToastUtils.showShort(R.string.please_select_retest_cycle); + return; + } + Bundle args = new Bundle(); + args.putInt(KEY_RESULT_CYCLE, resultCycleIndex); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_TIME, args); + dismiss(); + }); + + return mBinding.getRoot(); + } + + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + public static final String KEY_REQUEST_TIME = "KEY_REQUEST_TIME_ID"; + + + private static final String KEY_CYCLE_COUNT = "__cycle_count__ "; + private static final String KEY_RESULT_CYCLE = "__result_cycle__ "; + + private SelectReSurveyorCycleFragment() { + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Dialog dialog = getDialog(); + if (dialog == null) { + return; + } + dialog.setOnDismissListener(dialogInterface -> { + Bundle args = new Bundle(); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_TIME, args); + dismiss(); + }); + } + + public static void start(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + int cycleCount, + ISelectedCallback callback) { + if (callback == null) { + return; + } + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_TIME, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_TIME.equals(requestKey)) { + int targetCycleIndex = result.getInt(KEY_RESULT_CYCLE, -1); + callback.onSelected(targetCycleIndex); + } + }); + BottomSheetDialogFragment fragment = new SelectReSurveyorCycleFragment(); + Bundle args = new Bundle(); + args.putInt(KEY_CYCLE_COUNT, cycleCount); + fragment.setArguments(args); + fragment.show(fragmentManager, SelectReSurveyorCycleFragment.class.getName()); + } + + public interface ISelectedCallback { + void onSelected(int cycleIndex); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorPointFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorPointFragment.java new file mode 100644 index 0000000..ccc6f80 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorPointFragment.java @@ -0,0 +1,176 @@ +package com.bingce.controlnetwork.fragment; + +import android.app.Dialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlnetwork.adapter.ResurveyorPointsAdapter; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.ResurveyorPointsAdapter; + +/** + * 选择要补测的方向 + */ +public class SelectReSurveyorPointFragment extends BaseBottomSheetDialogFragment { + private int cycleIndex = -1; + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_resurveryor_layout, container, false); + + RecyclerView recyclerView = rootView.findViewById(R.id.list); + if (recyclerView != null && getArguments() != null) { + int cycleCount = getArguments().getInt(KEY_CYCLE_COUNT); + boolean showLeftOrRight = getArguments().getBoolean(KEY_SHOW_LEFT_RIGHT, false); + if (cycleCount > 0) { + cycleIndex = 0; + View layoutCycle = rootView.findViewById(R.id.layout_cycle); + if (layoutCycle != null) { + layoutCycle.setVisibility(View.VISIBLE); + TextView cycleText = rootView.findViewById(R.id.cycle_text); + layoutCycle.setOnClickListener(v -> { + ArrayList cycleList = SurveyorCycleUtil.cycleStrings(cycleCount, showLeftOrRight); + runOnUI(() -> BottomSheetSelectListFragment.showSelect( + getChildFragmentManager(), + getViewLifecycleOwner(), + cycleIndex, + cycleList, + null,//不再限制测期 + (index, string) -> { + cycleIndex = index; + if (cycleText != null) { + cycleText.setText(string); + } + })); + }); + } + } + + //默认添加0方向 + List allPointIds = getArguments().getStringArrayList(KEY_ALL_POINT_IDS); + List allPointNames = getArguments().getStringArrayList(KEY_ALL_POINT_NAMES); + + List items = new ArrayList<>(); + for (int index = 0; index < allPointIds.size(); index++) { + ResurveyorPointsAdapter.Item item = + new ResurveyorPointsAdapter.Item(allPointNames.get(index), allPointIds.get(index)); + items.add(item); + } + ResurveyorPointsAdapter adapter = new ResurveyorPointsAdapter( + Collections.singletonList(allPointIds.get(0)), + items, + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner()); + recyclerView.setAdapter(adapter); + + Button confirm = rootView.findViewById(R.id.confirm); + if (confirm != null) { + confirm.setOnClickListener(v -> { + Bundle args = new Bundle(); + List ids = adapter.selectedIds(); + ArrayList results = new ArrayList<>(ids); + args.putStringArrayList(KEY_SELECTED_POINT_IDS, results); + args.putInt(KEY_CYCLE_INDEX, cycleIndex); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_TIME, args); + dismiss(); + }); + } + } + + return rootView; + } + + public static final String KEY_REQUEST_TIME = "KEY_REQUEST_TIME_ID"; + private static final String KEY_ALL_POINT_IDS = "__all_point_ids "; + private static final String KEY_ALL_POINT_NAMES = "__all_point_names "; + private static final String KEY_SELECTED_POINT_IDS = "__selected_point_ids "; + + private static final String KEY_CYCLE_COUNT = "__cycle_count__ "; + private static final String KEY_SHOW_LEFT_RIGHT = "__show_left_or_right__"; + private static final String KEY_CYCLE_INDEX = "__cycle_INDEX__ "; + + private SelectReSurveyorPointFragment() { + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Dialog dialog = getDialog(); + if (dialog == null) { + return; + } + dialog.setOnDismissListener(dialogInterface -> { + Bundle args = new Bundle(); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_TIME, args); + dismiss(); + }); + } + + public static void pick(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + boolean showLeftOrRight, + ArrayList allPointIds, + ArrayList allPointNames, + ISelectedCallback callback) { + pick(fragmentManager, lifecycleOwner, -1, showLeftOrRight, + allPointIds, allPointNames, callback); + } + + public static void pick(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + int cycleCount, + boolean showLeftOrRight, + ArrayList allPointIds, + ArrayList allPointNames, + ISelectedCallback callback) { + if (callback == null) { + return; + } + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_TIME, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_TIME.equals(requestKey)) { + List selectedIds = result.getStringArrayList(KEY_SELECTED_POINT_IDS); + int targetCycleIndex = result.getInt(KEY_CYCLE_INDEX, -1); + callback.onSelected(targetCycleIndex, selectedIds); + } + }); + BottomSheetDialogFragment fragment = new SelectReSurveyorPointFragment(); + Bundle args = new Bundle(); + args.putStringArrayList(KEY_ALL_POINT_IDS, allPointIds); + args.putStringArrayList(KEY_ALL_POINT_NAMES, allPointNames); + args.putBoolean(KEY_SHOW_LEFT_RIGHT, showLeftOrRight); + args.putInt(KEY_CYCLE_COUNT, cycleCount); + fragment.setArguments(args); + fragment.show(fragmentManager, SelectReSurveyorPointFragment.class.getName()); + } + + public interface ISelectedCallback { + void onSelected(int cycleIndex, List pointIds); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeFragment.java new file mode 100644 index 0000000..0fa0925 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeFragment.java @@ -0,0 +1,176 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +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.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import com.bingce.controlnetwork.R; + +/** + * 选择站的类型(闭合导线,直导线等) + */ +public class SelectSurveyorStationTypeFragment extends BottomSheetDialogFragment { + public static final String TAG = SelectProjectAndSurveyorCycleFragment.class.getName(); + //上个页面传过来的 + private String projectType; + + private final int[] needHideIdsTriangle = { + R.id.wire_well_double, R.id.wire_well + }; + private final int[] needHideIdsConnection = { + R.id.default_type, R.id.wire_zhi, R.id.wire_fuhe, R.id.wire_close, + R.id.wire_random + }; + private final int[] needHideIdsHeightTraverse = { + R.id.default_type, R.id.wire_zhi, R.id.wire_fuhe, R.id.wire_close, + R.id.wire_random, R.id.wire_well_double, R.id.wire_well + }; + + private SelectSurveyorStationTypeFragment() { + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(KEY_PROJECT_TYPE); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate( + R.layout.fragment_bottom_popup_surveyor_station_type_select_layout, + container, + false); + initListener(view); + initShowOrHideView(view); + return view; + } + + private void initShowOrHideView(View view) { + ProjectType.getTarget(projectType, (projectTypeBack) -> { + if (projectTypeBack == ProjectType.TRIANGLE) { + hideViews(view, needHideIdsTriangle); + } else if (projectTypeBack == ProjectType.CONNECTION) { + hideViews(view, needHideIdsConnection); + } else if (projectTypeBack == ProjectType.HEIGHT_TRAVERSE) { + hideViews(view, needHideIdsHeightTraverse); + } + return null; + }); + } + + private void hideViews(View view, int[] ids) { + for (int i = 0; i < ids.length; i++) { + View currentView = view.findViewById(ids[i]); + currentView.setVisibility(View.GONE); + } + } + + private void initListener(View view) { + View.OnClickListener onClickListener = v -> { + if (v == null) { + dismiss(); + return; + } + int id = v.getId(); + String type = TYPE_DEFAULT; + if (id == R.id.wire_zhi) { + type = TYPE_LINE_SINGLE; + } else if (id == R.id.wire_fuhe) { + type = TYPE_LINE_ATTACH; + } else if (id == R.id.wire_close) { + type = TYPE_LINE_CLOSE; + } else if (id == R.id.wire_random) { + type = TYPE_LINE_RANDOM; + } else if (id == R.id.wire_well) { + type = TYPE_WELL_WIRE; + } else if (id == R.id.wire_well_double) { + type = TYPE_WELL_WIRE_DOUBLE; + } + Bundle args = new Bundle(); + args.putString(KEY_RESULT_TYPE, type); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + }; + + setOnClickListener(view, R.id.default_type, onClickListener); + setOnClickListener(view, R.id.wire_zhi, onClickListener); + setOnClickListener(view, R.id.wire_fuhe, onClickListener); + setOnClickListener(view, R.id.wire_close, onClickListener); + setOnClickListener(view, R.id.wire_random, onClickListener); + setOnClickListener(view, R.id.wire_well, onClickListener); + setOnClickListener(view, R.id.wire_well_double, onClickListener); + setOnClickListener(view, R.id.cancel, v -> dismiss()); + } + + @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 static void setOnClickListener(View root, int id, View.OnClickListener onClickListener) { + View view = root.findViewById(id); + if (view != null) { + view.setOnClickListener(onClickListener); + } + } + + private static final String KEY_PROJECT_TYPE = "__KEY_PROJECT_TYPE__"; + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_RESULT_TYPE = "__KEY_RESULT_TYPE__"; + + public static final String TYPE_DEFAULT = "__default__";//多测回测角 + public static final String TYPE_LINE_SINGLE = "__line_single";//支导线 + public static final String TYPE_LINE_ATTACH = "__line_attach";//附合导线 + public static final String TYPE_LINE_CLOSE = "__line_close";//闭合导线 + public static final String TYPE_LINE_RANDOM = "__line_random";//无定向导线 + public static final String TYPE_WELL_WIRE = "__well_wire";//井定向 + public static final String TYPE_WELL_WIRE_DOUBLE = "__well_wire_double";//二井定向 + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String projectType, + IOnSelectCallback callback) { + SelectSurveyorStationTypeFragment fragment = new SelectSurveyorStationTypeFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_PROJECT_TYPE, projectType); + fragment.setArguments(bundle); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected(result.getString(KEY_RESULT_TYPE)); + } + }); + fragment.show(fragmentManager, TAG); + } + + + public interface IOnSelectCallback { + void onSurveyorCycleSelected(String type); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeWellSubFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeWellSubFragment.java new file mode 100644 index 0000000..f9524bc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeWellSubFragment.java @@ -0,0 +1,103 @@ +package com.bingce.controlnetwork.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.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import com.bingce.controlnetwork.R; + +/** + * 选择二井定向-地上还是地下 + */ +public class SelectSurveyorStationTypeWellSubFragment extends BottomSheetDialogFragment { + public static final String TAG = SelectProjectAndSurveyorCycleFragment.class.getName(); + + private SelectSurveyorStationTypeWellSubFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate( + R.layout.fragment_bottom_popup_surveyor_station_type_select_layout_well_sub, + container, + false); + View.OnClickListener onClickListener = v -> { + if (v == null) { + dismiss(); + return; + } + int id = v.getId(); + String type = TYPE_GROUND; + if (id == R.id.wire_ground) { + type = TYPE_GROUND; + } else if (id == R.id.wire_underground) { + type = TYPE_UNDERGROUND; + } + Bundle args = new Bundle(); + args.putString(KEY_TYPE, type); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + }; + + setOnClickListener(view, R.id.wire_ground, onClickListener); + setOnClickListener(view, R.id.wire_underground, onClickListener); + setOnClickListener(view, R.id.cancel, v -> dismiss()); + + return view; + } + + private static void setOnClickListener(View root, int id, View.OnClickListener onClickListener) { + View view = root.findViewById(id); + if (view != null) { + view.setOnClickListener(onClickListener); + } + } + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_TYPE = "__SELECT_TYPE__"; + + public static final String TYPE_GROUND = "type_ground";//二井定向地上 + public static final String TYPE_UNDERGROUND = "type_underground";//二井定向地下 + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + IOnSelectCallback callback) { + SelectSurveyorStationTypeWellSubFragment fragment = new SelectSurveyorStationTypeWellSubFragment(); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected(result.getString(KEY_TYPE)); + } + }); + fragment.show(fragmentManager, TAG); + } + + @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 IOnSelectCallback { + void onSurveyorCycleSelected(String type); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceBottomSheetFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceBottomSheetFragment.java new file mode 100644 index 0000000..5af4a8b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceBottomSheetFragment.java @@ -0,0 +1,156 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +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; + +/** + * 限差选择框(限差设置-限差模板点击后的操作) + */ +public class SelectToleranceBottomSheetFragment extends DialogFragment { + public static final String TAG = SelectToleranceBottomSheetFragment.class.getName(); + private ComponentSwitchToleranceFragment componentSwitchToleranceFragment; + + private SelectToleranceBottomSheetFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate(R.layout.fragment_tolerance_select_framelayout_layout, + container, + false); + String projectType = ""; + String groupId = ""; + String levelId = ""; + String toleranceId = ""; + if (getArguments() != null) { + projectType = getArguments().getString(KEY_PROJECT_TYPE); + groupId = getArguments().getString(KEY_GROUP_ID); + levelId = getArguments().getString(KEY_LEVEL_ID); + toleranceId = getArguments().getString(KEY_TOLERANCE_ID); + } + + componentSwitchToleranceFragment = + ComponentSwitchToleranceFragment.newInstance(projectType, groupId, levelId, toleranceId); + + getChildFragmentManager() + .beginTransaction() + .replace(R.id.container, componentSwitchToleranceFragment) + .commit(); + + View toleranceManager = view.findViewById(R.id.btn_tolerance_manager); + if (toleranceManager != null) { + String finalProjectType = projectType; + toleranceManager.setOnClickListener(v -> ToleranceManageFragment.start(getContext(), finalProjectType)); + } + + view.setOnClickListener(v -> dismiss()); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + if (getDialog() != null) { + final Window window = getDialog().getWindow(); + + window.setWindowAnimations(R.style.animate_dialog); + window.setBackgroundDrawable(null); + + WindowManager.LayoutParams params = window.getAttributes(); + params.gravity = Gravity.BOTTOM; + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + window.setAttributes(params); + } + } + + @Override + public void onStart() { + super.onStart(); + EventBus.getDefault().register(this); + getDialog().setOnKeyListener((dialog, keyCode, event) -> { + if ((keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)) { + if (!componentSwitchToleranceFragment.doBack()) { + dismiss(); + } + return true; + } + return false; + }); + } + + @Override + public void onStop() { + super.onStop(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(ComponentSwitchToleranceFragment.SelectedToleranceEvent event) { + Bundle args = new Bundle(); + args.putString(KEY_TOLERANCE_ID, event.toleranceId); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + } + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_PROJECT_TYPE = "___project__type"; + private static final String KEY_GROUP_ID = "___group__id"; + private static final String KEY_LEVEL_ID = "____level__id"; + private static final String KEY_TOLERANCE_ID = "____tolerance__id"; + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String projectType, + String defaultGroupId, + String defaultLevelId, + String defaultToleranceId, + IOnSelectCallback callback) { + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_TYPE, projectType); + args.putString(KEY_GROUP_ID, defaultGroupId); + args.putString(KEY_LEVEL_ID, defaultLevelId); + args.putString(KEY_TOLERANCE_ID, defaultToleranceId); + + SelectToleranceBottomSheetFragment fragment = new SelectToleranceBottomSheetFragment(); + fragment.setArguments(args); + + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onToleranceSelected( + result.getString(KEY_TOLERANCE_ID)); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IOnSelectCallback { + void onToleranceSelected(String toleranceId); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceTemplateBottomSheetFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceTemplateBottomSheetFragment.java new file mode 100644 index 0000000..ad345da --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceTemplateBottomSheetFragment.java @@ -0,0 +1,144 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +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; + +/** + * 选择限差参考模板(自定义限差管理点击+后的操作) + */ +public class SelectToleranceTemplateBottomSheetFragment extends DialogFragment { + public static final String TAG = SelectToleranceTemplateBottomSheetFragment.class.getName(); + private ComponentSwitchToleranceFragment componentSwitchToleranceFragment; + + private String projectType; + + private SelectToleranceTemplateBottomSheetFragment() { + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(KEY_PROJECT_TYPE, ""); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate(R.layout.fragment_tolerance_template_select_layout, + container, + false); + + componentSwitchToleranceFragment = + ComponentSwitchToleranceFragment.newInstance(projectType, "", "", ""); + + getChildFragmentManager() + .beginTransaction() + .replace(R.id.container, componentSwitchToleranceFragment) + .commit(); + + view.setOnClickListener(v -> dismiss()); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + if (getDialog() != null) { + final Window window = getDialog().getWindow(); + + window.setWindowAnimations(R.style.animate_dialog); + window.setBackgroundDrawable(null); + + WindowManager.LayoutParams params = window.getAttributes(); + params.gravity = Gravity.BOTTOM; + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + window.setAttributes(params); + } + } + + @Override + public void onStart() { + super.onStart(); + EventBus.getDefault().register(this); + getDialog().setOnKeyListener((dialog, keyCode, event) -> { + if ((keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)) { + if (!componentSwitchToleranceFragment.doBack()) { + dismiss(); + } + return true; + } + return false; + }); + } + + @Override + public void onStop() { + super.onStop(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(ComponentSwitchToleranceFragment.SelectedToleranceEvent event) { + Bundle args = new Bundle(); + args.putString(KEY_TOLERANCE_ID, event.toleranceId); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + } + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_TOLERANCE_ID = "___key__tolerance__id"; + private static final String KEY_PROJECT_TYPE = "KEY_PROJECT_TYPE"; + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String projectType, + IOnSelectCallback callback) { + SelectToleranceTemplateBottomSheetFragment fragment = + new SelectToleranceTemplateBottomSheetFragment(); + + Bundle bundle = new Bundle(); + bundle.putString(KEY_PROJECT_TYPE, projectType); + fragment.setArguments(bundle); + + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onToleranceSelected( + result.getString(KEY_TOLERANCE_ID)); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IOnSelectCallback { + void onToleranceSelected(String toleranceId); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ServiceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ServiceFragment.java new file mode 100644 index 0000000..1ce6514 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ServiceFragment.java @@ -0,0 +1,108 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.View; +import android.webkit.JavascriptInterface; + +import androidx.annotation.Nullable; + +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.surveyor.agentweb.AgentWebFragment; +import com.bingce.surveyor.agentweb.FragmentKeyDown; +import com.bingce.surveyor.agentweb.sonic.SonicImpl; +import com.bingce.surveyor.constant.ServicePageUrl; +import com.bingce.utils.StringUtil; +import com.just.agentweb.MiddlewareWebClientBase; + + +/** + * 主页面-服务 + */ +public class ServiceFragment extends AgentWebFragment implements FragmentKeyDown { + public static final String TAG = "ServiceFragment"; + public final String offlineUrl = "file:///android_asset/service_default.html"; + private SonicImpl mSonicImpl; + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + // 1. 首先创建SonicImpl + mSonicImpl = new SonicImpl(offlineUrl, this.getContext()); + // 2. 调用 onCreateSession + mSonicImpl.onCreateSession(); + //3. 创建AgentWeb ,注意创建AgentWeb的时候应该使用加入SonicWebViewClient中间件 + super.onViewCreated(view, savedInstanceState); // 创建 AgentWeb 注意的 go("") 传入的 mUrl 应该null 或者"" + //4. 注入 JavaScriptInterface + if (mAgentWeb != null) { + //注入对象 + mAgentWeb.getJsInterfaceHolder().addJavaObject("android", this); + } + //5. 最后绑定AgentWeb + mSonicImpl.bindAgentWeb(mAgentWeb); + + refresh(); + } + + //在步骤3的时候应该传入给AgentWeb + @Override + public MiddlewareWebClientBase getMiddlewareWebClient() { + return mSonicImpl.createSonicClientMiddleWare(); + } + + //getUrl 应该为null + @Override + public String getUrl() { + return null; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + //销毁SonicSession + if (mSonicImpl != null) { + mSonicImpl.destrory(); + } + } + + @JavascriptInterface + public void refresh() { + String queryUrl = "android_url_service_for_control"; + LeanCloudConfigLoader.findInBackground(queryUrl, instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", queryUrl) +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { +// ((App) Utils.getApp()).servicePageUrl = /*avObjects.get(0).getString("value")*/instance.value; + ServicePageUrl.url = instance.value; + mAgentWeb.getUrlLoader().loadUrl(ServicePageUrl.url); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + } + + @Override + public void onResume() { + super.onResume(); +// Activity activity = getActivity(); +// if (activity instanceof MainActivity) { +// ((MainActivity) activity).setCurrentTab(2); +// } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/StationDataAdjustDialogFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/StationDataAdjustDialogFragment.java new file mode 100644 index 0000000..24fced5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/StationDataAdjustDialogFragment.java @@ -0,0 +1,183 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +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.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.surveyor.method.RadianMethod; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.adapter.BaseAdapter; +import com.bingce.utils.Util; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.vh.StationAdjustItemViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +public class StationDataAdjustDialogFragment extends DialogFragment { + public static final String KEY_SHOW_TYPE = "__key_show_type"; + private static final String KEY_LIST = "__key_list"; + private static final String KEY_IS_SHOW_SLOP_DISTANCE = "__key_show_slop"; + + //key_type对应的常量 + public static final String TYPE_ANGLE_DISTANCE = "TYPE_ANGLE_DISTANCE";//水平角,垂直角,距离 + public static final String TYPE_ANGLE_VER_AND_DISTANCE = "TYPE_ANGLE_VER_AND_DISTANCE";//垂直角,距离 + public static final String TYPE_ALONE_DISTANCE = "TYPE_ALONE_DISTANCE";//距离 + + + private String showType; + + private StationDataAdjustDialogFragment() { + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + Bundle arguments = getArguments(); + if (arguments != null) { + showType = arguments.getString(KEY_SHOW_TYPE); + } + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + Window window = getDialog().getWindow(); + window.setBackgroundDrawable(new ColorDrawable(0x00000000)); + window.setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_station_data_adjust_dialog_layout, container, false); + if (getArguments() != null) { + ArrayList items = getArguments().getParcelableArrayList(KEY_LIST); + boolean isShowSlop = getArguments().getBoolean(KEY_IS_SHOW_SLOP_DISTANCE, true); + RecyclerView recyclerView = rootView.findViewById(R.id.list); + TextView distanceTitle = rootView.findViewById(R.id.distance_angle_title); + if (recyclerView != null) { + _Adapter adapter = new _Adapter(items); + recyclerView.setAdapter(adapter); + if (distanceTitle != null) { + distanceTitle.setText(isShowSlop ? R.string.distance_slope : R.string.distance_horizontal); + } + } + + initShowView(rootView.findViewById(R.id.hor_angle_title), + rootView.findViewById(R.id.ver_angle_title), + rootView.findViewById(R.id.distance_angle_title)); + + } + return rootView; + } + + + private void initShowView(View horView, View verView, View disView) { + if (showType == null) return; + switch (showType) { + case TYPE_ALONE_DISTANCE: + horView.setVisibility(View.GONE); + verView.setVisibility(View.GONE); + disView.setVisibility(View.VISIBLE); + break; + case TYPE_ANGLE_VER_AND_DISTANCE: + horView.setVisibility(View.GONE); + verView.setVisibility(View.VISIBLE); + disView.setVisibility(View.VISIBLE); + break; + case TYPE_ANGLE_DISTANCE: + default: + horView.setVisibility(View.VISIBLE); + verView.setVisibility(View.VISIBLE); + disView.setVisibility(View.VISIBLE); + break; + } + } + + + private class _Adapter extends BaseAdapter { + + public _Adapter(List items) { + super(items); + } + + @Override + protected StationAdjustItemViewHolder createVH(@NotNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder viewHolder = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.stationAdjust); + if (viewHolder instanceof StationAdjustItemViewHolder) { + return (StationAdjustItemViewHolder) viewHolder; + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull StationAdjustItemViewHolder holder, int position) { + SurveyorAdjustMethod.Item item = getItem(position); + + initShowView(holder.horAngle, holder.verAngle, holder.distance); + + setText(holder.pointName, item.getPointName()); + setText(holder.horAngle, formatAngle(item.getHorAngle())); + setText(holder.verAngle, formatAngle(item.getVerAngle())); + setText(holder.distance, formatDistance(item.getDistance())); + } + + + private void setText(TextView textView, String string) { + if (textView != null) { + textView.setText(string); + } + } + + private String formatAngle(double angle) { + if (angle < 0) { + return ""; + } + return RadianMethod.dmsStringOf(angle); + } + + private String formatDistance(double distance) { + if (distance < 0) { + return ""; + } + return Util.formatDouble2String(distance, SettingValueUtil.getLengthDecimalPoint()); + } + } + + public static void showDialog(String type, ArrayList finalItemList, + Boolean isShowSlopDistance, + FragmentManager fragmentManager) { + StationDataAdjustDialogFragment dialogFragment = new StationDataAdjustDialogFragment(); + Bundle args = new Bundle(); + args.putString(KEY_SHOW_TYPE, type); + args.putParcelableArrayList(KEY_LIST, finalItemList); + args.putBoolean(KEY_IS_SHOW_SLOP_DISTANCE, isShowSlopDistance); + dialogFragment.setArguments(args); + dialogFragment.show(fragmentManager, StationDataAdjustDialogFragment.class.getName()); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/StringInputFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/StringInputFragment.java new file mode 100644 index 0000000..620fa02 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/StringInputFragment.java @@ -0,0 +1,88 @@ +package com.bingce.controlnetwork.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 androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.rengwuxian.materialedittext.MaterialEditText; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; + +public class StringInputFragment extends AbstractFullScreenDialogFragment { + @Override + protected View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.content_string_input_layout, container, false); + MaterialEditText 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) { + MaterialEditText editText = getView().findViewById(R.id.editor); + if (editText.getText() != null) { + String string = editText.getText().toString(); + if (string.isEmpty()) { + ToastUtils.showShort(R.string.string_no_empty); + return; + } + args.putString(KEY_STRING_RESULT, string); + } + } + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST_INPUT, args); + super.onConfirm(); + } + + private static final String TAG = StringInputFragment.class.getName(); + private static final String KEY_REQUEST_INPUT = StringInputFragment.class.getName() + "_REQUEST"; + private static final String KEY_STRING_RESULT = StringInputFragment.class.getName() + "_result"; + private static final String KEY_DEFAULT_STRING = StringInputFragment.class.getName() + "__DEFAULT_STRING"; + + public static void input(FragmentManager fragmentManager, + String title, + @NonNull LifecycleOwner lifecycleOwner, + IInputCallback callback) { + input(fragmentManager, title, null, lifecycleOwner, callback); + } + + public static void input(FragmentManager fragmentManager, + String title, + String defaultString, + @NonNull LifecycleOwner lifecycleOwner, + IInputCallback callback) { + Bundle args = new Bundle(); + StringInputFragment fragment = new StringInputFragment(); + fragment.setArguments(args); + if (defaultString != null) { + args.putString(KEY_DEFAULT_STRING, defaultString); + } + 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/fragment/SurveyorRouteStationFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorRouteStationFragment.java new file mode 100644 index 0000000..b80faba --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorRouteStationFragment.java @@ -0,0 +1,200 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.LiveData; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.route.RouteRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.util.ScheduleUtil; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.SurveyorStationListAdapter; +import com.bingce.controlnetwork.databinding.FragmentSurveyorRouteStationBinding; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.station.heighttraverse.CreateStationForHeightTraverseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse.MeasureHeightTraverseFragment; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 高程导线 测量页-项目路线下的测站列表和新增测站 + */ +public class SurveyorRouteStationFragment extends BaseFragment { + public static final String TAG = SurveyorRouteStationFragment.class.getName(); + private SurveyorStationListAdapter adapter; + private FragmentSurveyorRouteStationBinding mBinding; + + private static final String KEY_DETAIL_OR_SURVEYOR = "___editable___";//标识点击item进入测量界面还是测站详情 + + public static SurveyorRouteStationFragment newInstance(String projectId, String routeId) { + return newInstance(projectId, routeId, true); + } + + public static SurveyorRouteStationFragment newInstance(String projectId, String routeId, boolean detailOrSurveyor) { + SurveyorRouteStationFragment fragment = new SurveyorRouteStationFragment(); + 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 goStationMeasureOrDetail(SurveyorStationRecord item) { + String stationId = item.getId(); + ThreadPoolUtil.execute(() -> { + SurveyorStationRecord stationRecord = SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + if (stationRecord == null || stationRecord.getItems() == null || stationRecord.getItems().isEmpty()) { + return; + } + + //站的名称 导线+点名 + String stationName = StationUtil.getStationName(stationRecord); + + MeasureHeightTraverseFragment.start(requireContext(), stationId, stationName); + }); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = FragmentSurveyorRouteStationBinding.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(); + initListener(); + initData(); + } + + private void initView() { + mBinding.btnCreateStation.setVisibility(getRouteId() == null ? View.GONE : View.VISIBLE); + } + + private void initListener() { + mBinding.btnCreateStation.setOnClickListener(v -> checkCreateStation(checkSuccess -> { + if (!checkSuccess) return; + CreateStationForHeightTraverseFragment.start(requireContext(), getProjectId(), getRouteId()); + })); + } + + private void checkCreateStation(ICallBackCheckStation callBackCheckStation) { + ThreadPoolUtil.execute(() -> { + String projectId = getProjectId(); + String routeId = getRouteId(); + if (projectId == null || routeId == null) { + ToastUtils.showShort(R.string.parameter_exception); + callBackCheckStation.result(false); + return; + } + RouteRecord routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getByIdSync(routeId); + if (routeRecord == null) { + ToastUtils.showShort(R.string.route_record_exception); + callBackCheckStation.result(false); + return; + } + + //判断上一个测站是否通过检测 + SurveyorStationRecord stationLatest = SurveyorDatabaseFactory.instance.getSurveyorStation().getByProjectRouteLatest(projectId, routeId); + if (stationLatest != null && stationLatest.items != null && stationLatest.items.size() > 0) { + String stationNameNotFinish = ScheduleUtil.INSTANCE.getStationNameNotFinishForHeightTraverse(stationLatest); + if (!TextUtils.isEmpty(stationNameNotFinish)) { + ToastUtils.showShort(Tools.getString(R.string.station_failed_test, stationNameNotFinish)); + callBackCheckStation.result(false); + return; + } + } + + SurveyorStationRecord stationRecord = SurveyorDatabaseFactory.instance.getSurveyorStation().getByProjectRouteLatest(projectId, routeId); + if (stationRecord != null && stationRecord.items != null) { + for (SurveyorPoint surveyorPoint : stationRecord.items) { + if (surveyorPoint.getOriginalPointId().equals(routeRecord.getEndPointId())) { + ToastUtils.showShort(R.string.route_begin_end_been_created); + callBackCheckStation.result(false); + return; + } + } + } + + callBackCheckStation.result(true); + }); + } + + private void initData() { + if (getArguments() != null) { + update(getProjectId(), getRouteId()); + } + } + + 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; + } + + /** + * 根据项目id和路线id获取测站记录 + */ + public void update(String projectId, String routeId) { + LiveData> liveData = SurveyorDatabaseFactory.instance.getSurveyorStation().getByProjectRouteLiveData(projectId, routeId); + liveData.observe(getViewLifecycleOwner(), this::updateUi); + } + + private void updateUi(List stationList) { + if (adapter == null) { + adapter = new SurveyorStationListAdapter(stationList, + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + getContext(), + this::goStationMeasureOrDetail, + true); + mBinding.recyclerView.setAdapter(adapter); + } else { + adapter.updateData(stationList); + } + } + + private interface ICallBackCheckStation { + void result(boolean checkSuccess); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorSettingsFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorSettingsFragment.java new file mode 100644 index 0000000..15ddfd9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorSettingsFragment.java @@ -0,0 +1,98 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +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.fragment.app.Fragment; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreferenceCompat; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +public class SurveyorSettingsFragment extends Fragment { + public static final String TAG = SurveyorSettingsFragment.class.getName(); + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_fragment_container_layout, container, false); + _SettingsFragment fragment = new _SettingsFragment(); + fragment.setArguments(getArguments()); + getChildFragmentManager() + .beginTransaction() + .add(R.id.container, fragment) + .commit(); + return rootView; + } + + public static class _SettingsFragment extends PreferenceFragmentCompat { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.surveyor_settings_prefs); + + SwitchPreferenceCompat distanceType = findPreference("surveyor_settings_key_distance_type"); + if (getArguments() != null) { + String stationId = getArguments().getString(BundleConstants.KEY_SURVEYOR_STATION_ID); + ThreadPoolUtil.execute(() -> { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + if (stationRecord == null) { + return; + } + runOnUI(() -> { + if (distanceType != null) { + distanceType.setChecked(stationRecord.isShowSlopDistance()); + distanceType.setOnPreferenceChangeListener((preference, newValue) -> { + if (newValue instanceof Boolean) { +// Log.d("___distance_type", newValue.toString()); + stationRecord.setShowSlopDistance((boolean) newValue); + stationDataSource.save(stationRecord); + } + return true; + }); + } + }); + }); + } + } + + private void runOnUI(Runnable action) { + if (getActivity() != null) { + getActivity().runOnUiThread(action); + } + } + } + +// public static void show(FragmentManager fragmentManager) { +// DialogFragment dialogFragment = new SurveyorSettingDialogFragment(); +// dialogFragment.show(fragmentManager, SurveyorSettingDialogFragment.class.getName()); +// } + + public static void start(Context context, String surveyorStationId, String surveyorStationName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_NAME, surveyorStationName); + FragmentContainerActivity.start(context, TAG, surveyorStationName, bundle); + } + + public static SurveyorSettingsFragment newInstance(Bundle bundle) { + SurveyorSettingsFragment fragment = new SurveyorSettingsFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/TipsFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/TipsFragment.java new file mode 100644 index 0000000..c27b0a3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/TipsFragment.java @@ -0,0 +1,177 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.Button; +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 TipsFragment extends AppCompatDialogFragment { + private final Handler mainHandler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(@NonNull Message msg) { + View contentView = getView(); + if (contentView == null) { + return; + } + Button confirm = contentView.findViewById(R.id.confirm_button); + int countDown = (Integer) msg.obj - 1; + if (countDown <= 0) { + confirm.setEnabled(true); + confirm.setText(R.string.confirm); + } else { + confirm.setEnabled(false); + confirm.setText(String.valueOf(countDown)); + Message message = Message.obtain(); + message.obj = countDown; + mainHandler.sendMessageDelayed(message, 1000); + } + } + }; + + private TipsFragment() { + super(); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_tips_layout, container, false); + Button confirm = contentView.findViewById(R.id.confirm_button); + if (getArguments() != null) { + TextView tvTitle = contentView.findViewById(R.id.title); + if (tvTitle != null) { + tvTitle.setText(getArguments().getString(KEY_TITLE)); + } + TextView tvTips = contentView.findViewById(R.id.content); + if (tvTips != null) { + tvTips.setText(getArguments().getString(KEY_CONTENT)); + } + int countDown = getArguments().getInt(KEY_COUNT_DOWN, -1); + if (countDown > 0) { + confirm.setEnabled(false); + confirm.setText(String.valueOf(countDown)); + Message message = Message.obtain(); + message.obj = countDown; + mainHandler.sendMessageDelayed(message, 1000); + } + } + + if (confirm != null) { + confirm.setOnClickListener(v -> { + //这里主动dismiss不会收到回调 + Bundle args = new Bundle(); + args.putBoolean(KEY_QUIT_CANCEL, false); + getParentFragmentManager().setFragmentResult(getTag(), args); + dismiss(); + }); + } + return contentView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + if (getArguments() != null) { + boolean cancelAble = getArguments().getBoolean(KEY_CANCEL_ABLE, true); + if (!cancelAble) { + getDialog().setCancelable(false); + } + } + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + private static final String KEY_TITLE = "__TITLE"; + private static final String KEY_CONTENT = "___CONTENT"; + private static final String KEY_COUNT_DOWN = "__COUNT_DOWN"; + private static final String KEY_CANCEL_ABLE = "__cancel__able"; + private static final String KEY_QUIT_CANCEL = "__key_quit_cancel__"; + + public static void noCancelAbleTips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Context context, + String content, + int countdown, + IConfirmCallback callback) { + baseTips(fragmentManager, lifecycleOwner, context.getString(R.string.notice), content, countdown, false, false, callback); + } + + public static void cancelAbleTips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Context context, + String content, + int countdown, + IConfirmCallback callback) { + baseTips(fragmentManager, lifecycleOwner, context.getString(R.string.notice), content, countdown, true, true, callback); + } + + public static void tipsOnly(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Context context, + String content) { + baseTips(fragmentManager, lifecycleOwner, context.getString(R.string.notice), content, + -1, true, false, null); + } + + private static void baseTips( + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String title, + String content, + int countdown, + boolean cancelAble, + boolean filterCancel, + IConfirmCallback callback) { + Bundle args = new Bundle(); + TipsFragment fragment = new TipsFragment(); + fragment.setArguments(args); + args.putString(KEY_TITLE, title); + args.putString(KEY_CONTENT, content); + args.putInt(KEY_COUNT_DOWN, countdown); + args.putBoolean(KEY_CANCEL_ABLE, cancelAble); + + String tag = String.valueOf(System.currentTimeMillis()); + + fragmentManager + .setFragmentResultListener( + tag, + lifecycleOwner, + (requestKey, result) -> { + if (callback != null) { + if (tag.equals(requestKey)) { + boolean isCancel = result.getBoolean(KEY_QUIT_CANCEL, true); + if (!isCancel || !filterCancel) { + callback.onConfirm(); + } + } + } + }); + + fragment.show(fragmentManager, tag); + + + } + + public interface IConfirmCallback { + void onConfirm(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/TipsWith2OptionFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/TipsWith2OptionFragment.java new file mode 100644 index 0000000..c0ed8e4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/TipsWith2OptionFragment.java @@ -0,0 +1,452 @@ +package com.bingce.controlnetwork.fragment; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.graphics.Color; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.FragmentTipsWith2OptionLayoutBinding; + +public class TipsWith2OptionFragment extends AppCompatDialogFragment { + + private static TipsWith2OptionFragment currentFragmet;//为了全局消失使用 + + private static final int COUNT_DOWN_TIME = 5;//如果有倒计时,默认是5秒 + + //key 返回的是确实还是取消... + private static final String KEY_CALL_BACK_CODE = "KEY_CALL_BACK_CODE"; + private static final int CALL_BACK_CODE_CONFIRM = 1; + private static final int CALL_BACK_CODE_CANCEL = 2; + private static final int CALL_BACK_CODE_OPTION = 3; + private static final int CALL_BACK_CODE_IGNORE = 4; + + private static final String KEY_TITLE = "__TITLE"; + private static final String KEY_CONTENT = "___CONTENT"; + private static final String KEY_CONFIRM_BUTTON = "_confirm_button"; + private static final String KEY_CANCEL_BUTTON = "_cancel_button"; + private static final String KEY_OPTION_BUTTON = "_option_button"; + private static final String KEY_CANCELABLE = "__cancelable"; + private static final String KEY_AUTO_DISMISS = "__auto_dismiss";//点击按钮后是否可以自动关闭 + private static final String KEY_COUNT_DOWN = "__COUNT_DOWN"; + + private int callBackCode; + + + private final Handler mainHandler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(@NonNull Message msg) { + View contentView = getView(); + if (contentView == null) { + return; + } + Button confirm = contentView.findViewById(R.id.confirm_button); + int countDown = (Integer) msg.obj - 1; + if (countDown <= 0) { + confirm.setEnabled(true); + confirm.setText(R.string.confirm); + confirm.setTextColor(Color.BLACK); + } else { + confirm.setEnabled(false); + confirm.setText(String.valueOf(countDown)); + Message message = Message.obtain(); + message.obj = countDown; + mainHandler.sendMessageDelayed(message, 1000); + } + } + }; + private FragmentTipsWith2OptionLayoutBinding mBinding; + + public static void hardTips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().content(content).cancelable(false).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + + public static void tips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Argument argument, + IOperatorCallback callback) { + Bundle build = argument.build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + public static void dismissNowMe() { + if (currentFragmet != null && currentFragmet.getLifecycle().getCurrentState() == Lifecycle.State.RESUMED) { + currentFragmet.dismissAllowingStateLoss(); + currentFragmet = null; + } + } + + public static void tips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String confirmButton, + String cancelButton, + String optionButton, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().confirmText(confirmButton).cancelText(cancelButton).optionText(optionButton).content(content).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + public static void tips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String confirmButton, + String cancelButton, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().confirmText(confirmButton).cancelText(cancelButton) + .content(content).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + public static void tipsCountDownTime(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String confirmButton, + String cancelButton, + String optionButton, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().confirmText(confirmButton).cancelText(cancelButton).optionText(optionButton) + .content(content).countDownTime(COUNT_DOWN_TIME).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + + public static void tipsCannotCancel(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String confirmButton, + String cancelButton, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().confirmText(confirmButton).cancelText(cancelButton) + .content(content).cancelable(false).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + @Override + public void onStart() { + super.onStart(); + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.setCancelable(isCancelableOwn()); + + Window window = dialog.getWindow(); + if (window != null) { + window.setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + } + } + + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + currentFragmet = this; + + mBinding = FragmentTipsWith2OptionLayoutBinding.inflate(inflater, container, false); + initData(); + initClickListener(); + initCountDownTime(); + + return mBinding.getRoot(); + } + + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + currentFragmet = null; + } + + + private void initData() { + mBinding.title.setText(getTitle()); + mBinding.content.setText(getContent()); + mBinding.cancelButton.setText(getCancelText()); + String optionText = getOptionText(); + if (TextUtils.isEmpty(optionText)) { + mBinding.optionButton.setVisibility(View.GONE); + } else { + mBinding.optionButton.setVisibility(View.VISIBLE); + mBinding.optionButton.setText(optionText); + } + mBinding.confirmButton.setText(getConfirmText()); + } + + private void initCountDownTime() { + int countDownTime = getCountDownTime(); + if (countDownTime > 0) { + mBinding.confirmButton.setEnabled(false); + mBinding.confirmButton.setText(String.valueOf(countDownTime)); + mBinding.confirmButton.setTextColor(Color.RED); + Message message = Message.obtain(); + message.obj = countDownTime; + mainHandler.sendMessageDelayed(message, 1000); + } + } + + private void initClickListener() { + mBinding.confirmButton.setOnClickListener(view -> { + callBackCode = CALL_BACK_CODE_CONFIRM; + setResultForBtnClick(); + }); + mBinding.cancelButton.setOnClickListener(view -> { + callBackCode = CALL_BACK_CODE_CANCEL; + setResultForBtnClick(); + }); + mBinding.optionButton.setOnClickListener(view -> { + callBackCode = CALL_BACK_CODE_OPTION; + setResultForBtnClick(); + }); + } + + @Override + public void onDismiss(@NonNull DialogInterface dialog) { + setResultForIgnore(); + super.onDismiss(dialog); + } + + private void setResultForIgnore() { + if (isCallBackCodeConfirm() || isCallBackCodeCancel() + || isCallBackCodeOption()) { + return; + } + callBackCode = CALL_BACK_CODE_IGNORE; + setResult(); + } + + private void setResultForBtnClick() { + setResult(); + + if (isAutoDismiss() || !isCallBackCodeConfirm()) { + dismissAllowingStateLoss(); + } + } + + private boolean isCallBackCodeCancel() { + return callBackCode == CALL_BACK_CODE_CANCEL; + } + + private boolean isCallBackCodeConfirm() { + return callBackCode == CALL_BACK_CODE_CONFIRM; + } + + private boolean isCallBackCodeOption() { + return callBackCode == CALL_BACK_CODE_OPTION; + } + + private void setResult() { + Bundle bundle = new Bundle(); + bundle.putInt(KEY_CALL_BACK_CODE, callBackCode); + getParentFragmentManager().setFragmentResult(getTag(), bundle); + } + + private static void init(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + IOperatorCallback callback, Bundle bundle) { + TipsWith2OptionFragment fragment = new TipsWith2OptionFragment(); + fragment.setArguments(bundle); + fragment.setCancelable(true); + + String tag = String.valueOf(System.currentTimeMillis()); + + fragmentManager + .setFragmentResultListener( + tag, + lifecycleOwner, + (requestKey, result) -> { + if (callback != null) { + if (fragment.getTag().equals(requestKey)) { + int type = result.getInt(KEY_CALL_BACK_CODE, -1); + if (CALL_BACK_CODE_CONFIRM == type) { + callback.onConfirm(); + } else if (CALL_BACK_CODE_OPTION == type) { + callback.onOption(); + } else if (CALL_BACK_CODE_CANCEL == type) { + callback.onCancel(); + } else if (CALL_BACK_CODE_IGNORE == type) { + callback.onIgnore(); + } + } + } + }); + fragment.show(fragmentManager, tag); + } + + public boolean isAutoDismiss() { + assert getArguments() != null; + return getArguments().getBoolean(KEY_AUTO_DISMISS, true); + } + + public boolean isCancelableOwn() { + assert getArguments() != null; + return getArguments().getBoolean(KEY_CANCELABLE, true); + } + + public String getTitle() { + assert getArguments() != null; + return getArguments().getString(KEY_TITLE, Tools.getString(R.string.notice)); + } + + public String getConfirmText() { + assert getArguments() != null; + return getArguments().getString(KEY_CONFIRM_BUTTON, Tools.getString(R.string.confirm)); + } + + public String getCancelText() { + assert getArguments() != null; + return getArguments().getString(KEY_CANCEL_BUTTON, Tools.getString(R.string.cancel)); + } + + public String getOptionText() { + assert getArguments() != null; + return getArguments().getString(KEY_OPTION_BUTTON, ""); + } + + public String getContent() { + assert getArguments() != null; + return getArguments().getString(KEY_CONTENT, ""); + } + + public int getCountDownTime() { + assert getArguments() != null; + return getArguments().getInt(KEY_COUNT_DOWN, 0); + } + + public static class Argument { + private Boolean cancelable;//是否可以取消 + private Boolean autoDismiss; + private String title; + private String confirmText; + private String cancelText; + private String optionText; + private String content; + private Integer countDownTime; + + public Argument() { + } + + public Argument autoDismiss(boolean autoDismiss) { + this.autoDismiss = autoDismiss; + return this; + } + + public Argument cancelable(boolean cancelable) { + this.cancelable = cancelable; + return this; + } + + public Argument title(String title) { + this.title = title; + return this; + } + + public Argument confirmText(String confirmText) { + this.confirmText = confirmText; + return this; + } + + public Argument cancelText(String cancelText) { + this.cancelText = cancelText; + return this; + } + + public Argument optionText(String optionText) { + this.optionText = optionText; + return this; + } + + public Argument content(String content) { + this.content = content; + return this; + } + + public Argument countDownTime(int countDownTime) { + this.countDownTime = countDownTime; + return this; + } + + public Bundle build() { + Bundle bundle = new Bundle(); + putValue(bundle, KEY_TITLE, title); + putValue(bundle, KEY_CONTENT, content); + putValue(bundle, KEY_CONFIRM_BUTTON, confirmText); + putValue(bundle, KEY_CANCEL_BUTTON, cancelText); + putValue(bundle, KEY_OPTION_BUTTON, optionText); + putValue(bundle, KEY_CANCELABLE, cancelable); + putValue(bundle, KEY_AUTO_DISMISS, autoDismiss); + putValue(bundle, KEY_COUNT_DOWN, countDownTime); + return bundle; + } + + private void putValue(Bundle bundle, String key, Object value) { + if (value != null) { + if (value instanceof Boolean) { + bundle.putBoolean(key, (Boolean) value); + } else if (value instanceof String) { + bundle.putString(key, (String) value); + } else if (value instanceof Integer) { + bundle.putInt(key, (Integer) value); + } + } + } + + } + + public interface IOperatorCallback { + void onConfirm(); + + void onOption(); + + void onCancel(); + + void onIgnore(); + } + + public static class SimpleCallback implements IOperatorCallback { + + @Override + public void onConfirm() { + + } + + @Override + public void onOption() { + + } + + @Override + public void onCancel() { + + } + + @Override + public void onIgnore() { + + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java new file mode 100644 index 0000000..67f10db --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java @@ -0,0 +1,188 @@ +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 androidx.appcompat.widget.SwitchCompat; +import androidx.fragment.app.FragmentManager; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +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 + protected View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.content_tolerance_attribute_editor_layout, container, false); + if (getArguments() != null) { + ThreadPoolUtil.execute(() -> { + String toleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); + ToleranceDetailRecord record = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(toleranceId); + if (record == null) { + return; + } + ProjectTolerance projectTolerance = new ProjectTolerance(record); + 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) { + integerView.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); + } + 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(() -> { + if (getArguments() == null || getView() == null) { + return; + } + String toleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); + ToleranceDetailRecord record = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(toleranceId); + if (record == null) { + return; + } + ProjectTolerance projectTolerance = new ProjectTolerance(record); + int attributeIndex = getArguments().getInt(KEY_ATTRIBUTE_INDEX, -1); + if (attributeIndex < 0) { + return; + } + MaterialEditText editor = getView().findViewById(R.id.editor); + SwitchCompat switchCompat = getView().findViewById(R.id.switch_control); + TextView count = getView().findViewById(R.id.count); + ToleranceAttributesType type = ToleranceAttributesType.values()[attributeIndex]; + if (projectTolerance.isBoolValue(type)) { + projectTolerance.setBoolAttribute(type, switchCompat.isChecked()); + } else if (projectTolerance.isDoubleValue(type)) { + String string = editor.getText().toString(); + if (string.isEmpty()) { + dismiss(); + return; + } + projectTolerance.setDoubleAttribute(type, Double.parseDouble(string)); + } else if (projectTolerance.isIntegerValue(type)) { + String string = count.getText().toString(); + if (string.isEmpty()) { + dismiss(); + return; + } + projectTolerance.setIntegerAttribute(type, Integer.parseInt(string)); + } + //存储数据 + projectTolerance.save2DataSource(() -> { + EventBus.getDefault().post(new RefreshToleranceTotailEvent()); + dismissAllowingStateLoss(); + }); + + }); + } + + private static final String KEY_ATTRIBUTE_INDEX = "__attribute_index___"; + + public static void editAndSave(String toleranceId, + ToleranceAttributesType attributesType, + String groupTitle, + String title, + FragmentManager fragmentManager) { + ToleranceAttributeEditFragment fragment = new ToleranceAttributeEditFragment(); + Bundle args = new Bundle(); + args.putInt(KEY_ATTRIBUTE_INDEX, attributesType.ordinal()); + args.putString(BundleConstants.KEY_TOLERANCE_ID, toleranceId); + setArgs(args, groupTitle, title); + fragment.setArguments(args); + fragment.show(fragmentManager, ToleranceAttributeEditFragment.class.getName()); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java new file mode 100644 index 0000000..d8989e9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java @@ -0,0 +1,179 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ExpandableListView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +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.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 currentToleranceId; + private ToleranceDetailAdapter adapter; + + 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) { + 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); + expandableListView = view.findViewById(R.id.list); + refreshUi(); + return view; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + EventBus.getDefault().unregister(this); + } + + 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)); + } + } + }); + }); + + } + + /** + * 填充数据 + * + * @param expandableListView + * @param projectTolerance + */ + private void updateTolerance(ExpandableListView expandableListView, IProjectTolerance projectTolerance) { + if (!currentToleranceId.equals(projectTolerance.id())) { + return; + } + boolean editable = projectTolerance.isWritable(); + //填充adapter + if (adapter == null) { + adapter = new ToleranceDetailAdapter(projectTolerance); + expandableListView.setAdapter(adapter); + expandAllItemView(expandableListView, projectTolerance); + } else { + adapter.updateData(projectTolerance); + expandAllItemView(expandableListView, projectTolerance); + } + //设置点击事件 + expandableListView.setOnChildClickListener((parent, v, groupPosition, childPosition, viewId) -> { + 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; + }); + } + + /** + * 全部展开 + * + * @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 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) { + ToleranceDetailFragment fragment = new ToleranceDetailFragment(); + fragment.setArguments(args); + return fragment; + } + + 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, "限差设置", 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 new file mode 100644 index 0000000..336c84f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceManageFragment.java @@ -0,0 +1,231 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +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; +import com.bingce.controlnetwork.adapter.BaseIndexTextWithContextMenuAdapter; +import com.bingce.controlnetwork.adapter.IUpdateListAdapter; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 自定义限差管理 + */ +public class ToleranceManageFragment extends BaseFragment { + public static final String TAG = ToleranceManageFragment.class.getName(); + private BaseIndexTextWithContextMenuAdapter adapter = null; + + private String projectType; + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(BundleConstants.KEY_PROJECT_TYPE); + } + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_tolerance_manager_layout, container, false); + + RecyclerView recyclerView = rootView.findViewById(R.id.list); + IToleranceDetailDataSource toleranceDetailDataSource = + SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + toleranceDetailDataSource + .getCustomLiveDataListByGroup() + .observe(getViewLifecycleOwner(), + toleranceDetailRecords -> { + if (adapter == null) { + adapter = new _Adapter( + getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + toleranceDetailRecords, + this::clickToleranceItem); + recyclerView.setAdapter(adapter); + } else { + adapter.updateData(toleranceDetailRecords); + } + }); + + View createButton = rootView.findViewById(R.id.create_new); + if (createButton != null) { + createButton.setOnClickListener(this::showSelectedToleranceDlg); + } + 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( + getChildFragmentManager(), + getViewLifecycleOwner(), + projectType, + toleranceId -> onSelectedTolerance( + getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + toleranceId)); + } + + private static void onSelectedTolerance(FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + Context context, + String toleranceId) { + //查询 限差 名称 + IToleranceDetailDataSource toleranceDetailDataSource = + SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + ThreadPoolUtil.execute(() -> { + //先检测预置模板 + ToleranceDetailRecord toleranceDetailRecord = (ToleranceDetailRecord) ToleranceLoadUtil.getTriangleToleranceLoad().detailOf(toleranceId); + if (toleranceDetailRecord == null) { + toleranceDetailRecord = toleranceDetailDataSource.getRecordSync(toleranceId); + } + if (toleranceDetailRecord == null) { + return; + } + + //查询限差完整名称 + 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; + } + ToleranceDetailRecord finalToleranceDetailRecord = toleranceDetailRecord; + ThreadPoolUtil.executeInMain(() -> StringInputFragment + .input( + fragmentManager, + context.getString(R.string.tips_please_input_new_tolerance_name), + ToleranceUtil.completedToleranceName(toleranceGroupRecord, toleranceLevelRecord, finalToleranceDetailRecord), + lifecycleOwner, + string -> { + if (string == null || string.isEmpty()) { + ToastUtils.showShort(R.string.string_no_empty); + return; + } + gotoEditNewTolerance(context, finalToleranceDetailRecord, string); + } + )); + }); + } + + private static void gotoEditNewTolerance(Context context, ToleranceDetailRecord template, String name) { + ToleranceDetailRecord newInstance = template.convertCustomRecord(template); + newInstance.singleSurveyor = template.singleSurveyor; + newInstance.setName(name); + SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .saveWithCallback(newInstance, () -> ToleranceDetailFragment.start(context, newInstance.getId(), false)); + } + + private static class _Adapter extends BaseIndexTextWithContextMenuAdapter + implements IUpdateListAdapter { + public _Adapter( + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + Context context, + List records, + IOnItemClick callback) { + super(records == null ? new ArrayList<>() : records, callback, new ContextMenuDeleteEdit() { + @Override + protected void delete(ToleranceDetailRecord item) { + //检测是否有project使用了当前限差方案 + ThreadPoolUtil.execute(() -> { + long count = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .recordCountWithTolerance(item.getId()); + if (count <= 0) { + IToleranceDetailDataSource toleranceDetailDataSource = + SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + toleranceDetailDataSource.delete(item); + } else { + ThreadPoolUtil.executeInMain(() -> Toast + .makeText(context, R.string.tips_tolerance_cannt_delete_because_of_used, Toast.LENGTH_SHORT) + .show()); + } + }); + } + + @Override + protected void edit(ToleranceDetailRecord item) { + ToleranceMethodKt.changeToleranceName( + fragmentManager, lifecycleOwner, item); + } + }); + } + } + + public static void start(Context context, String projectType) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, R.string.name_custom_telorance_manager, bundle); + } + + public static ToleranceManageFragment newInstance(Bundle bundle) { + ToleranceManageFragment fragment = new ToleranceManageFragment(); + 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 new file mode 100644 index 0000000..cc78629 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceSelectFragment.java @@ -0,0 +1,109 @@ +package com.bingce.controlnetwork.fragment; + +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; +import android.view.View; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +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(); + + @Override + protected void onCreateView(View view) { + String toleranceId = null; + if (getArguments() != null) { + toleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); + } + 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); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.confirm_button) { + Intent intent = new Intent(); + intent.putExtra(BundleConstants.KEY_TOLERANCE_ID, currentTolerance()); + Activity activity = getActivity(); + if (activity != null) { + activity.setResult(Activity.RESULT_OK, intent); + activity.finish(); + } + } + return super.onOptionsItemSelected(item); + } + + public static void start(Context context, String toleranceId, String projectType, + ActivityResultLauncher launcher) { + if (launcher == null) { + return; + } + Bundle args = new Bundle(); + args.putString(BundleConstants.KEY_TOLERANCE_ID, toleranceId); + args.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + launcher.launch(FragmentContainerActivity.startIntent(context, TAG, R.string.select_tolerance, args)); + } + + public static ActivityResultLauncher createActivityLauncher(Fragment fragment, ISelectCallback selectCallback) { + return fragment.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result != null && Activity.RESULT_OK == result.getResultCode()) { + Intent intent = result.getData(); + if (intent != null) { + String id = intent.getStringExtra(BundleConstants.KEY_TOLERANCE_ID); + selectCallback.onSelectTolerance(id); + return; + } + } +// selectCallback.onSelectTolerance(null); + }); + } + + public static ToleranceSelectFragment newInstance(Bundle bundle) { + ToleranceSelectFragment fragment = new ToleranceSelectFragment(); + fragment.setArguments(bundle); + return fragment; + } + + public interface ISelectCallback { + void onSelectTolerance(String id); + } + +} \ No newline at end of file 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 new file mode 100644 index 0000000..5c94c4f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseFragment.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.fragment.base; + +import android.view.View; + +import androidx.annotation.IdRes; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Lifecycle; + +import com.bingce.controlapphelper.util.IUIRunner; + +public class BaseFragment extends Fragment implements IUIRunner { + public void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } + + final protected T findViewById(@IdRes int id) { + if (getActivity() == null) { + return null; + } + return getActivity().findViewById(id); + } + + final protected void setCreatedData(Runnable runnable) { + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.CREATED)) { + runnable.run(); + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseLazyFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseLazyFragment.java new file mode 100644 index 0000000..ee4d84d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseLazyFragment.java @@ -0,0 +1,87 @@ +package com.bingce.controlnetwork.fragment.base; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.IdRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Lifecycle; + +public abstract class BaseLazyFragment extends Fragment { + + /** + * 是否执行懒加载 + */ + private boolean isLoaded = false; + + /** + * 当前Fragment是否对用户可见 + */ + private boolean isVisibleToUser = false; + + /** + * view是否已经创建 + */ + private boolean onViewCreated = false; + + final protected void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } + + final protected T findViewById(@IdRes int id) { + if (getActivity() == null) { + return null; + } + return getActivity().findViewById(id); + } + + final protected void setCreatedData(Runnable runnable) { + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.CREATED)) { + runnable.run(); + } + } + + + @Override + public void setUserVisibleHint(boolean isVisibleToUser) { + super.setUserVisibleHint(isVisibleToUser); + this.isVisibleToUser = isVisibleToUser; + judgeLoadData(); + } + + @Override + public void onHiddenChanged(boolean hidden) { + super.onHiddenChanged(hidden); + isVisibleToUser = !hidden; + } + + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + onViewCreated = true; + judgeLoadData(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + isLoaded = false; + isVisibleToUser = false; + onViewCreated = false; + } + + private void judgeLoadData() { + if (!isLoaded && isVisibleToUser && onViewCreated) { + loadData(); + isLoaded = true; + } + } + + protected abstract void loadData(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomBean.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomBean.kt new file mode 100644 index 0000000..e2ff1ce --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomBean.kt @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import android.os.Parcelable +import androidx.annotation.Keep +import kotlinx.android.parcel.Parcelize + +@Keep +@Parcelize +data class BottomBean( + val id: String, + val name: String, + val pageIndex: Int, + val isSelect: Boolean = false, + val tag: String? = null +) : Parcelable diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageAdapter.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageAdapter.kt new file mode 100644 index 0000000..badb59d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageAdapter.kt @@ -0,0 +1,42 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.bingce.controlapphelper.util.FastClickUtil +import com.bingce.controlnetwork.adapter.BaseAdapter +import com.bingce.controlnetwork.databinding.ListItemIndexTextSelectableLayoutBinding + +class BottomPageAdapter(val context: Context, private val dataList: List, callBack: CallBack) : + BaseAdapter(dataList) { + + private val callBack: CallBack + + init { + this.callBack = callBack + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val bean = dataList[position] + holder.mBinding.index.text = (position + 1).toString() + holder.mBinding.text.text = bean.name + holder.mBinding.status.visibility = if (bean.isSelect) View.VISIBLE else View.GONE + + holder.mBinding.root.setOnClickListener { + FastClickUtil.click { + callBack.back(bean) + } + } + } + + override fun createVH(parent: ViewGroup, viewType: Int): ViewHolder { + val binding = ListItemIndexTextSelectableLayoutBinding.inflate(LayoutInflater.from(context), parent, false) + return ViewHolder(binding) + } + + interface CallBack { + fun back(bottomBean: BottomBean) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageContentFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageContentFragment.kt new file mode 100644 index 0000000..aa40fea --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageContentFragment.kt @@ -0,0 +1,99 @@ +package com.bingce.controlnetwork.fragment.bottompage + +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 com.bingce.controlnetwork.databinding.FragmentBottomPageContentBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class BottomPageContentFragment(private val dataList: List) : Fragment() { + private var _binding: FragmentBottomPageContentBinding? = null + val mBinding get() = _binding!! + + private val viewModel: BottomSwitchVm by viewModels({ requireParentFragment() }) + + private val mainScope = MainScope() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentBottomPageContentBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + mainScope.cancel() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initView() + } + + override fun onHiddenChanged(hidden: Boolean) { + super.onHiddenChanged(hidden) + if (!hidden) { + refreshTitleVisiable() + } + } + + private fun initView() { + mBinding.back.setOnClickListener { + viewModel.selectList.removeLast() + getBottomPageFragment()?.removeFragment() + } + + val adapter = + BottomPageAdapter(requireContext(), dataList, object : BottomPageAdapter.CallBack { + override fun back(bottomBean: BottomBean) { + itemClick(bottomBean) + } + }) + mBinding.recyclerView.adapter = adapter + + mBinding.title.text = getBottomPageFragment()?.getTitle(this) + refreshTitleVisiable() + } + + private fun itemClick(bottomBean: BottomBean) { + mainScope.launch { + val dataNext = withContext(Dispatchers.IO) { + getBottomPageFragment()?.getDataNext(bottomBean) + } + viewModel.selectList.add(bottomBean) + if (dataNext.isNullOrEmpty()) { + getBottomPageFragment()?.setResultData() + } else { + getBottomPageFragment()?.addFragment(dataNext, true) + } + } + } + + private fun getBottomPageFragment(): BottomPageFragment? { + return parentFragment as? BottomPageFragment + } + + private fun refreshTitleVisiable() { + parentFragmentManager.fragments.let { + if (it.size <= 1) { + mBinding.back.visibility = View.GONE + } else { + mBinding.back.visibility = View.VISIBLE + } + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageFragment.kt new file mode 100644 index 0000000..d102353 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageFragment.kt @@ -0,0 +1,157 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import android.os.Bundle +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentTransaction +import androidx.fragment.app.setFragmentResult +import androidx.fragment.app.viewModels +import androidx.lifecycle.LifecycleOwner +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.GsonUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentSingleFramelayoutLayoutBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class BottomPageFragment(val data: IData) : DialogFragment() { + + private val mainScope = MainScope() + + private var _binding: FragmentSingleFramelayoutLayoutBinding? = null + val mBinding get() = _binding!! + + private val viewModel: BottomSwitchVm by viewModels() + + companion object { + @JvmStatic + fun showBottom( + fragmentManager: FragmentManager, + lifecycleOwner: LifecycleOwner, + data: IData, + callBack: CallBack + ) { + val bottomPageFragment = BottomPageFragment(data) + val tag = System.currentTimeMillis().toString() + + fragmentManager.setFragmentResultListener( + tag, + lifecycleOwner + ) { requestKey: String, bundle: Bundle -> + bottomPageFragment.dismiss() + if (requestKey == tag) { + bundle.getString(BundleConstants.KEY_SELECT_LIST)?.let { it -> + GsonUtil.toAny>(it)?.let juadge@{ + if (it.size < 2) { + ToastUtils.showShort(R.string.no_data) + return@juadge + } + callBack.back(it) + } + } + } + } + bottomPageFragment.show(fragmentManager, tag) + } + } + + + override fun onStart() { + super.onStart() + dialog?.window?.run { + setWindowAnimations(R.style.animate_dialog) + setBackgroundDrawable(null) + val params = attributes + params.gravity = Gravity.BOTTOM + params.width = ViewGroup.LayoutParams.MATCH_PARENT + params.height = ViewGroup.LayoutParams.WRAP_CONTENT + attributes = params + } + + } + + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentSingleFramelayoutLayoutBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + mainScope.cancel() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mainScope.launch { + val firstPageData = withContext(Dispatchers.IO) { + data.getData(null) + } + firstPageData?.let { + addFragment(it, false) + } + } + } + + fun addFragment(dataNext: List, isNeedAnim: Boolean) { + addOrDeleteFragment(isNeedAnim) { + val contentFragment = BottomPageContentFragment(dataNext) + add(R.id.container, contentFragment) + } + } + + fun removeFragment() { + childFragmentManager.fragments.last()?.let { + addOrDeleteFragment { + remove(it) + } + } + } + + fun setResultData() { + val toJson = GsonUtil.toJson(viewModel.selectList) + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_SELECT_LIST, toJson) + setFragmentResult(tag!!, bundle) + } + + suspend fun getDataNext(currentData: BottomBean): List? { + return data.getData(currentData) + } + + fun getTitle(bottomPageContentFragment: BottomPageContentFragment): String { + return data.getTitle(childFragmentManager.fragments.indexOf(bottomPageContentFragment)) + } + + private fun addOrDeleteFragment( + isNeedAnim: Boolean = true, + block: FragmentTransaction.() -> Unit + ) { + val transaction = childFragmentManager + .beginTransaction() + if (isNeedAnim) { + transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_right) + } + block(transaction) + transaction.commit() + } + + interface CallBack { + fun back(selectData: List) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomSwitchVm.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomSwitchVm.kt new file mode 100644 index 0000000..35c7013 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomSwitchVm.kt @@ -0,0 +1,8 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import androidx.lifecycle.ViewModel + +class BottomSwitchVm : ViewModel() { + // val dataList = mutableListOf() + val selectList = mutableListOf() +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/IData.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/IData.kt new file mode 100644 index 0000000..4eeafa1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/IData.kt @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.fragment.bottompage + +interface IData { + suspend fun getData(bottomBean: BottomBean?): List? + + fun getTitle(pageIndex: Int): String +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/ViewHolder.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/ViewHolder.kt new file mode 100644 index 0000000..1e1c155 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/ViewHolder.kt @@ -0,0 +1,6 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import androidx.recyclerview.widget.RecyclerView +import com.bingce.controlnetwork.databinding.ListItemIndexTextSelectableLayoutBinding + +class ViewHolder(val mBinding: ListItemIndexTextSelectableLayoutBinding) : RecyclerView.ViewHolder(mBinding.root) \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/CreateOrEditRouteDialog.java b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/CreateOrEditRouteDialog.java new file mode 100644 index 0000000..41c2bb9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/CreateOrEditRouteDialog.java @@ -0,0 +1,447 @@ +package com.bingce.controlnetwork.fragment.heighttraverse; + +import android.content.Intent; +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 androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.IdRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.route.RouteRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.util.CheckLocationUtil; +import com.bingce.controlapphelper.util.GetLocationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.DialogCreateRouteBinding; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.utils.ThreadPoolUtil; +import com.rengwuxian.materialedittext.MaterialEditText; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +public class CreateOrEditRouteDialog extends DialogFragment { + private PickPointResult pickPointResultStart; + private PickPointResult pickPointResultEnd; + + //选择起点还是终点的标志 + private static final String SELECT_START_TAG = "SELECT_START_TAG"; + private static final String SELECT_END_TAG = "SELECT_END_TAG"; + + private static final String KEY_PROJECT_ID = "KEY_PROJECT_ID"; + private static final String KEY_ROUTE_ID = "KEY_ROUTE_ID"; + + private static final String KEY_ROUTE_NAME = "KEY_ROUTE_NAME"; + private static final String KEY_START_POINT_ID = "KEY_START_POINT_ID"; + private static final String KEY_END_POINT_ID = "KEY_END_POINT_ID"; + + private DialogCreateRouteBinding mBinding; + private GetLocationUtil getLocationUtil; + + public static void start(String projectId, String routeId, FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + CallBack callback) { + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_ROUTE_ID, routeId); + showFragment(args, fragmentManager, lifecycleOwner, callback); + } + + + private static void showFragment(Bundle args, FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, CallBack callback) { + String tag = String.valueOf(System.currentTimeMillis()); + CreateOrEditRouteDialog fragment = new CreateOrEditRouteDialog(); + fragment.setArguments(args); + fragmentManager + .setFragmentResultListener( + tag, + lifecycleOwner, + (requestKey, resultBundle) -> { + if (tag.equals(requestKey)) { + callback.result( + resultBundle.getString(KEY_ROUTE_NAME), + resultBundle.getString(KEY_START_POINT_ID), + resultBundle.getString(KEY_END_POINT_ID) + ); + } + }); + fragment.show(fragmentManager, tag); + } + + private final ActivityResultLauncher defaultStationLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (SELECT_START_TAG.equals(type)) { + pickPointResultStart = pickPointResult; + } else if (SELECT_END_TAG.equals(type)) { + pickPointResultEnd = pickPointResult; + } + if (pickPointResult == null || isListEmpty(pickPointResult.getSelectedIds()) || isListEmpty(pickPointResult.getSelectedNames()) + || pickPointResult.getSelectedNames().size() != pickPointResult.getSelectedIds().size()) { + ToastUtils.showShort(R.string.abnormal_point_selection); + return; + } + setEtData(type); + }); + + private void setEtData(String type) { + if (SELECT_START_TAG.equals(type)) { + setEtDataSingle(mBinding.ilStart.etPoint, mBinding.ilStart.etHeight, + mBinding.ilStart.etB, mBinding.ilStart.etL, pickPointResultStart.getSelectedIds().get(0)); + } else if (SELECT_END_TAG.equals(type)) { + setEtDataSingle(mBinding.ilEnd.etPoint, mBinding.ilEnd.etHeight, + mBinding.ilEnd.etB, mBinding.ilEnd.etL, + pickPointResultEnd.getSelectedIds().get(0)); + } + } + + private void setEtDataSingle(MaterialEditText etPointName, MaterialEditText etPointHeight, + MaterialEditText etB, MaterialEditText etL, + String pointId) { + ThreadPoolUtil.execute(() -> { + PointRecord pointRecord = SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(pointId); + ThreadPoolUtil.executeInMain(() -> { + etPointName.setText(pointRecord.getName()); + etPointHeight.setText(doubleToString(pointRecord.getZ())); + + if (pointRecord.getLatitude() != 0 && pointRecord.getLongitude() != 0) { + etB.setText(doubleToString(pointRecord.getLatitude())); + etL.setText(doubleToString(pointRecord.getLongitude())); + } else { + etB.setText(""); + etL.setText(""); + } + }); + }); + } + + private boolean isListEmpty(List list) { + return list == null || list.isEmpty(); + } + + private MaterialEditText getEtPoint(@IdRes int id) { + View view = getView(); + assert view != null; + return view.findViewById(id); + } + + @Override + public void onStart() { + super.onStart(); +// getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0x33000000)); + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getLocationUtil = new GetLocationUtil(); + getLifecycle().addObserver(getLocationUtil); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = DialogCreateRouteBinding.inflate(inflater, container, false); + initView(); + initListener(); + initData(); + return mBinding.getRoot(); + } + + private void initView() { + mBinding.ilStart.llCoord.setVisibility(View.VISIBLE); + mBinding.ilEnd.llCoord.setVisibility(View.VISIBLE); + } + + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + private void initData() { + String routeId = getRouteId(); + if (routeId != null) { + ThreadPoolUtil.execute(() -> { + RouteRecord routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getByIdSync(routeId); + if (routeRecord != null) { + PointRecord startPointRecord = SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(routeRecord.getStartPointId()); + PointRecord endPointRecord = SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(routeRecord.getEndPointId()); + setPickPointResultForEdit(SELECT_START_TAG, startPointRecord.getId(), startPointRecord.getName()); + setPickPointResultForEdit(SELECT_END_TAG, endPointRecord.getId(), endPointRecord.getName()); + + ThreadPoolUtil.executeInMain(() -> { + setEtData(SELECT_START_TAG); + setEtData(SELECT_END_TAG); + }); + } + }); + } + } + + private void setPickPointResultForEdit(String type, String id, String name) { + if (type.equals(SELECT_START_TAG)) { + pickPointResultStart = getPickPointResultFromIdName(id, name); + } else { + pickPointResultEnd = getPickPointResultFromIdName(id, name); + } + } + + private PickPointResult getPickPointResultFromIdName(String id, String name) { + List ids = new ArrayList<>(); + List names = new ArrayList<>(); + ids.add(id); + names.add(name); + PickPointResult pickPointResult = new PickPointResult(); + pickPointResult.setSelectedIds(ids); + pickPointResult.setSelectedNames(names); + return pickPointResult; + } + + private void initListener() { + mBinding.tvSelectStartPoint.setOnClickListener(v -> selectPoint(SELECT_START_TAG)); + mBinding.tvSelectEndPoint.setOnClickListener(v -> selectPoint(SELECT_END_TAG)); + + mBinding.btnCancel.setOnClickListener((v) -> dismissAllowingStateLoss()); + + mBinding.btnConfirm.setOnClickListener((v) -> { + checkConfirm(); + }); + + mBinding.ivGetLocationStartPoint.setOnClickListener(v -> { + getLocation(result -> { + setLocation(mBinding.ilStart.etB, mBinding.ilStart.etL, result); + }); + }); + mBinding.ivGetLocationEndPoint.setOnClickListener(v -> { + getLocation(result -> { + setLocation(mBinding.ilEnd.etB, mBinding.ilEnd.etL, result); + }); + }); + } + + private void getLocation(GetLocationUtil.IResultListener resultListener) { + CheckLocationUtil.check(requireContext(), () -> { + getLocationUtil.getResult(resultListener); + }); + } + + private void setLocation(MaterialEditText etB, MaterialEditText etL, GetLocationUtil.Result result) { + if (result != null) { + etB.setText(result.getLatitude()); + etL.setText(result.getLongitude()); + } + } + + private void checkConfirm() { + ThreadPoolUtil.execute(() -> { + + String startPointName = mBinding.ilStart.etPoint.getText().toString().trim(); + if (TextUtils.isEmpty(startPointName)) { + ToastUtils.showShort(R.string.please_enter_or_select_a_starting_point); + return; + } + + String endPointName = mBinding.ilEnd.etPoint.getText().toString().trim(); + if (TextUtils.isEmpty(endPointName)) { + ToastUtils.showShort(R.string.please_enter_or_select_a_destination); + return; + } + + //取消起点终点重复的限制 +// if (startPointName.equals(endPointName)) { +// ToastUtils.showShort(R.string.duplicate_start_and_end_names); +// return; +// } + + boolean canEdit = checkCanEdit(); + if (!canEdit) { + ToastUtils.showShort(R.string.route_has_data_not_edit_hint); + return; + } + + String startHeight = mBinding.ilStart.etHeight.getText().toString().trim(); + String startB = mBinding.ilStart.etB.getText().toString().trim(); + String startL = mBinding.ilStart.etL.getText().toString().trim(); + String endHeight = mBinding.ilEnd.etHeight.getText().toString().trim(); + String endB = mBinding.ilEnd.etB.getText().toString().trim(); + String endL = mBinding.ilEnd.etL.getText().toString().trim(); + + PointRecord startPoint; + PointRecord endPoint; + + String projectId = getProjectId(); + startPoint = SurveyorDatabaseFactory.instance.getPointDataSource().findByNameSync(startPointName, projectId); + endPoint = SurveyorDatabaseFactory.instance.getPointDataSource().findByNameSync(endPointName, projectId); + + if (startPoint == null) { + startPoint = createPoint(startPointName, startHeight, startB, startL); + } else { + editPoint(startPoint, startPointName, startHeight, startB, startL); + } + + if (endPoint == null) { + endPoint = createPoint(endPointName, endHeight, endB, endL); + } else { + editPoint(endPoint, endPointName, endHeight, endB, endL); + } + + //存数据库 + SurveyorDatabaseFactory.instance.getPointDataSource().saveSync(startPoint); + SurveyorDatabaseFactory.instance.getPointDataSource().saveSync(endPoint); + + setResultToPage(startPoint.getId(), endPoint.getId(), + startPoint.getName() + "-" + endPoint.getName()); + }); + } + + @WorkerThread + private boolean checkCanEdit() { + //路线有数据时候不能编辑 + String routeId = getRouteId(); + if (routeId == null) { + return true; + } + RouteRecord routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getByIdSync(getRouteId()); + if (routeRecord != null) { + List stationList = SurveyorDatabaseFactory.instance.getSurveyorStation().getByProjectRoute(getProjectId(), getRouteId()); + if (stationList != null && !stationList.isEmpty()) { + for (SurveyorStationRecord stationRecord : stationList) { + long recordCount = SurveyorDatabaseFactory.instance.getSurveyorRecordDataSource().recordCount(stationRecord.getId()); + if (recordCount > 0) { + return false; + } + } + } + } + return true; + } + + @WorkerThread + private PointRecord createPoint(String pointName, String height, String b, String l) { + return createPointRecord(pointName, height, b, l); + } + + @WorkerThread + private void editPoint(PointRecord pointRecord, String pointNameEdit, String height, String b, String l) { + pointRecord.setName(pointNameEdit); + pointRecord.setZ(stringToDouble(height)); + pointRecord.setLatitude(stringToDouble(b)); + pointRecord.setLongitude(stringToDouble(l)); + } + + private void setResultToPage(String startPointId, String endPointId, String routeName) { + if (getActivity() != null) { + getActivity().runOnUiThread(() -> { + Bundle resultBundle = new Bundle(); + resultBundle.putString(KEY_START_POINT_ID, startPointId); + resultBundle.putString(KEY_END_POINT_ID, endPointId); + resultBundle.putString(KEY_ROUTE_NAME, routeName); + getParentFragmentManager() + .setFragmentResult(getTag(), resultBundle); + dismissAllowingStateLoss(); + }); + } + } + + private PointRecord createPointRecord(String pointText, String height, String b, String l) { + String pointType; + if (isKnownPoint(height)) { + pointType = PointRecord.TYPE_KNOWN_POINT; + } else { + pointType = PointRecord.TYPE_UNKNOWN_POINT; + } + double h = stringToDouble(height); + PointRecord point = PointRecord.point(getProjectId(), pointType, pointText, "", 0, 0, h, "", -1); + point.setLatitude(stringToDouble(b)); + point.setLongitude(stringToDouble(l)); + return point; + } + + private boolean isKnownPoint(String height) { + double heightD = stringToDouble(height); + return heightD != 0; + } + + private double stringToDouble(String value) { + if (TextUtils.isEmpty(value)) { + return 0; + } + return Double.parseDouble(value); + } + + private String doubleToString(double value) { + return String.valueOf(value); + } + + private void tipsOnly(String msg) { + if (getActivity() != null) { + getActivity().runOnUiThread(() -> TipsFragment.tipsOnly( + getChildFragmentManager(), + getViewLifecycleOwner(), + requireContext(), + msg)); + } + } + + private void selectPoint(String type) { + String title = null; + PickPointResult pickPointResultSelected = null; + List filderIds = null; + if (SELECT_START_TAG.equals(type)) { + pickPointResultSelected = pickPointResultStart; +// filderIds = pickPointResultEnd != null ? pickPointResultEnd.getSelectedIds() : null; + title = Tools.getString(R.string.choose_starting_point); + } else if (SELECT_END_TAG.equals(type)) { + pickPointResultSelected = pickPointResultEnd; +// filderIds = pickPointResultStart != null ? pickPointResultStart.getSelectedIds() : null; + title = Tools.getString(R.string.select_end_point); + } + PickPointFragment.pickPoint( + getContext(), + type, + 1, + title, + filderIds,//filderIds取消起点和终点的限制 + getProjectId(), pickPointResultSelected, defaultStationLauncher); + } + + public interface CallBack { + void result(String routeName, String startPointId, String endPointId); + } + + private String getProjectId() { + if (getArguments() != null) { + return getArguments().getString(KEY_PROJECT_ID); + } + return null; + } + + private String getRouteId() { + if (getArguments() != null) { + return getArguments().getString(KEY_ROUTE_ID); + } + return null; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/adapter/RouteListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/adapter/RouteListAdapter.java new file mode 100644 index 0000000..9e883ba --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/adapter/RouteListAdapter.java @@ -0,0 +1,18 @@ +package com.bingce.controlnetwork.fragment.heighttraverse.adapter; + +import java.util.List; + +import com.bingce.controlnetwork.adapter.BaseIndexTextWithContextMenuAdapter; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDelete; +import com.bingce.controlapphelper.datasource.database.route.RouteRecord; +import com.bingce.controlnetwork.adapter.BaseIndexTextWithContextMenuAdapter; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDelete; + +public class RouteListAdapter extends BaseIndexTextWithContextMenuAdapter { + + public RouteListAdapter(List dataList, IOnItemClick callback + , ContextMenuDelete contextMenuDeleteEdit) { + super(dataList, callback, contextMenuDeleteEdit); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/viewmodel/HeightCreateOrEditVm.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/viewmodel/HeightCreateOrEditVm.kt new file mode 100644 index 0000000..d0fc265 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/viewmodel/HeightCreateOrEditVm.kt @@ -0,0 +1,62 @@ +package com.bingce.controlnetwork.fragment.heighttraverse.viewmodel + +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlnetwork.fragment.heighttraverse.CreateOrEditRouteDialog +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.route.RouteRecord +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class HeightCreateOrEditVm : ViewModel() { + + fun showCreateOrEditDialog( + projectId: String, + routeId: String?, + childFragmentManager: FragmentManager, + viewLifecycleOwner: LifecycleOwner + ) { + CreateOrEditRouteDialog.start( + projectId, routeId, childFragmentManager, viewLifecycleOwner + ) { routeName, startPointId, endPointId -> + saveOrUpdateRecord(projectId, routeName, routeId, startPointId, endPointId) + } + } + + /** + * 存路线的同时存默认项目 + */ + private fun saveOrUpdateRecord( + projectId: String, + routeName: String, + routeId: String?, + startPointId: String, + endPointId: String + ) { + viewModelScope.launch(Dispatchers.IO) { + if (routeId != null) { + val routeRecord = + SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + routeRecord?.let { + it.routeName = routeName + it.startPointId = startPointId + it.endPointId = endPointId + SurveyorDatabaseFactory.instance.getRouteDataSource().update(it) + } + } else { + val routeRecord = + RouteRecord.createRouteRecord(projectId, routeName, startPointId, endPointId) + SurveyorDatabaseFactory.instance.getRouteDataSource().saveRecord(routeRecord) + //存默认的项目id + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PROJECT_ID, + projectId + ) + } + } + } + +} \ No newline at end of file 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 new file mode 100644 index 0000000..622aeea --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailFragment.kt @@ -0,0 +1,161 @@ +package com.bingce.controlnetwork.fragment.projectdetail + + +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 androidx.annotation.WorkerThread +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.event.SwitchPageEvent +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlnetwork.databinding.FragmentProjectDetailListLayoutBinding +import com.bingce.controlnetwork.fragment.PointListFragment +import com.bingce.controlnetwork.fragment.ProjectToleranceSettingFragment +import com.bingce.controlnetwork.fragment.base.BaseFragment +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import org.greenrobot.eventbus.EventBus + + +abstract class ProjectDetailFragment : BaseFragment() { + + companion object { + @JvmStatic + fun start(context: Context, projectType: String?, projectId: String, projectName: String?) { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType) + val tag = if (projectType == ProjectType.HEIGHT_TRAVERSE.flag) { + ProjectDetailHeightTraverseFragment.TAG + } else { + ProjectDetailTriangleFragment.TAG + } + FragmentContainerActivity.start(context, tag, projectName, bundle) + } + } + + private var _binding: FragmentProjectDetailListLayoutBinding? = null + val mBinding get() = _binding!! + + private val configDataSource = SurveyorDatabaseFactory.instance.configDataSource + + protected val projectId: String by lazy { + requireArguments().getString(BundleConstants.KEY_PROJECT_ID)!! + } + + protected val projectType: String? by lazy { + requireArguments().getString(BundleConstants.KEY_PROJECT_TYPE) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentProjectDetailListLayoutBinding.inflate(inflater, container, false) + initView() + setHasOptionsMenu(true) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + protected abstract fun getContentFragment(): Fragment + + @WorkerThread + protected abstract fun saveDefaultProjectAndSoOn(): String? + + protected abstract fun clickCreateStation() + + private fun initView() { + //设置开始测量 + mBinding.ilBtn.btnOne.text = getString(R.string.new_surveyor_station) + mBinding.ilBtn.btnTwo.text = getString(R.string.start_surveyor) + + childFragmentManager + .beginTransaction() + .replace(R.id.fragment_container, getContentFragment(), "__station_list") + .commit() + //已知点 + initKnownPoint() + //未知点 + initUnKnownPoint() + //去测量页面 + initGoMeasurePage() + //新建测站 + initCreateStation() + } + + private fun initCreateStation() = + mBinding.ilBtn.btnOne.setOnClickListener { v -> clickCreateStation() } + + private fun initGoMeasurePage() { + mBinding.ilBtn.btnTwo.setOnClickListener { view -> + lifecycleScope.launch(Dispatchers.IO) { + val msg = saveDefaultProjectAndSoOn() + if (!msg.isNullOrEmpty()) { + ToastUtils.showShort(msg) + return@launch + } + EventBus.getDefault().post( + SwitchPageEvent( + SwitchPageEvent.TYPE_SWITCH_TO_MEASURE_PAGE_AND_DATA, + null + ) + ) + val activity = activity + activity?.finish() + } + } + } + + private fun initUnKnownPoint() { + mBinding.unknownPointList.setOnClickListener { view -> + PointListFragment.go2UnknownPointList( + projectId, + projectType, + context + ) + } + } + + private fun initKnownPoint() { + mBinding.knownPointList.setOnClickListener { view -> + PointListFragment.go2KnownPointList( + projectId, + projectType, + context + ) + } + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.project_detail_fragment_menu, menu) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.project_parameter_setting) { + //设置参数点击事件 + ProjectToleranceSettingFragment.start(context, projectId, projectType) + return true + } + return super.onOptionsItemSelected(item) + } + + +} \ No newline at end of file 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 new file mode 100644 index 0000000..d427cc1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailHeightTraverseFragment.kt @@ -0,0 +1,71 @@ +package com.bingce.controlnetwork.fragment.projectdetail + +import android.os.Bundle +import android.view.View +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +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() { + + private lateinit var routeFragment: RouteFragment + + private val heightCreateOrEditVm: HeightCreateOrEditVm by viewModels() + + companion object { + @JvmField + val TAG = ProjectDetailHeightTraverseFragment::class.simpleName + + @JvmStatic + fun newInstance(bundle: Bundle): ProjectDetailHeightTraverseFragment { + val fragment = ProjectDetailHeightTraverseFragment() + fragment.arguments = bundle + return fragment + } + } + + override fun getContentFragment(): Fragment { + routeFragment = RouteFragment.newInstance(projectId) + return routeFragment + } + + override fun saveDefaultProjectAndSoOn(): String? { + val routeId = + routeFragment.getSurveyorRouteId() ?: return Tools.getString(R.string.no_route_yet) + SurveyorDataBase.getInstance().runInTransaction { + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PROJECT_ID, + projectId + ) + + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_ROUTE_ID, + routeId + ) + } + return null + } + + override fun clickCreateStation() { + heightCreateOrEditVm.showCreateOrEditDialog( + projectId, + routeId = null, + childFragmentManager, + viewLifecycleOwner + ) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mBinding.tvCycleTitle.text = getString(R.string.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 new file mode 100644 index 0000000..594d640 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailTriangleFragment.kt @@ -0,0 +1,197 @@ +package com.bingce.controlnetwork.fragment.projectdetail + +import android.os.Bundle +import android.view.View +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +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.surveyorcycle.SurveyorPeriodRecord +import com.bingce.controlnetwork.fragment.BottomSheetSurveyorPeriodFragment +import com.bingce.controlnetwork.fragment.SelectSurveyorStationTypeFragment +import com.bingce.controlnetwork.fragment.SelectSurveyorStationTypeWellSubFragment +import com.bingce.controlnetwork.fragment.station.defaultstation.DefaultStationSetupFragment +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 com.bingce.controlnetwork.newui.stationlist.StationListFragment +import com.bingce.controlnetwork.newui.stationlist.StationListVm + +class ProjectDetailTriangleFragment : ProjectDetailFragment() { + + private var currentPeriodId: String = "" + + private var contentFragment: StationListFragment? = null + + private val stationListVm by viewModels() + + companion object { + @JvmField + val TAG = ProjectDetailTriangleFragment::class.simpleName + + @JvmStatic + fun newInstance(bundle: Bundle): ProjectDetailTriangleFragment { + val fragment = ProjectDetailTriangleFragment() + fragment.arguments = bundle + return fragment + } + + } + + override fun getContentFragment(): Fragment { + //测站列表 + contentFragment = StationListFragment() + return contentFragment!! + } + + override fun saveDefaultProjectAndSoOn(): String? { + SurveyorDataBase.getInstance().runInTransaction { + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PROJECT_ID, + projectId + ) + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PERIOD_ID, + currentPeriodId + ) + } + return null + } + + override fun clickCreateStation() { + SelectSurveyorStationTypeFragment + .select( + childFragmentManager, + viewLifecycleOwner, + projectType + ) { type: String -> + if (SelectSurveyorStationTypeFragment.TYPE_DEFAULT == type) { + DefaultStationSetupFragment.start(context, projectId, currentPeriodId) + } else if (SelectSurveyorStationTypeFragment.TYPE_LINE_SINGLE == type) { + //支导线 + LineStationSingleSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_LINE_ATTACH == type) { + //附合导线 + LineStationAttachedSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_LINE_CLOSE == type) { + LineStationCloseSetupFragment.startCreateCloseLine( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_LINE_RANDOM == type) { + LineStationRandomSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_WELL_WIRE == type) { + //一井定向 + LineStationWellSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_WELL_WIRE_DOUBLE == type) { + //二井定向 + selectWellDoubleType() + } + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + stationListVm.isCanEditDelete = true + initListener() + initData() + } + + private fun initListener() { + initSwithCycle() + } + + private fun initSwithCycle() { + mBinding.cycleLayout.setOnClickListener { + //切换测期 + BottomSheetSurveyorPeriodFragment.pick( + childFragmentManager, + viewLifecycleOwner, + projectId, + currentPeriodId + ) { id: String, name: String -> + setCreatedData { + currentPeriodId = id + mBinding.orderText.text = name + updateStationList(projectId, currentPeriodId) + } + } + } + } + + private fun initData() { + //获取默认测期,刷新页面 + SurveyorDatabaseFactory.instance + .surveyorPeriod + .getDefault( + projectId + ) { instance: SurveyorPeriodRecord -> + setCreatedData { + currentPeriodId = instance.value + runOnUI { + //设置测期名称 + mBinding.orderText.text = instance.name + //设置测站列表 + updateStationList(projectId, instance.id) + } + } + } + } + + private fun updateStationList(projectId: String, periodId: String) { + if (contentFragment == null) { + return + } + stationListVm.setArgument(projectId, periodId) + contentFragment!!.refreshUi() + } + + /** + * 选择二井定向地上还是地下的弹框 + */ + private fun selectWellDoubleType() { + SelectSurveyorStationTypeWellSubFragment + .select( + childFragmentManager, + viewLifecycleOwner + ) { type: String -> + if (SelectSurveyorStationTypeWellSubFragment.TYPE_GROUND == type) { + LineStationWellDoubleGroundSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeWellSubFragment.TYPE_UNDERGROUND == type) { + LineStationWellDoubleUnderGroundSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/content/RouteFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/content/RouteFragment.kt new file mode 100644 index 0000000..5fcd3db --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/content/RouteFragment.kt @@ -0,0 +1,185 @@ +package com.bingce.controlnetwork.fragment.projectdetail.content + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import androidx.room.withTransaction +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDelete +import com.bingce.controlnetwork.fragment.TipsFragment +import com.bingce.controlnetwork.fragment.base.BaseFragment +import com.bingce.controlnetwork.fragment.heighttraverse.adapter.RouteListAdapter +import com.bingce.controlnetwork.fragment.heighttraverse.viewmodel.HeightCreateOrEditVm +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.route.RouteRecord +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.PointUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentListLayoutBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class RouteFragment : BaseFragment() { + + private val heightCreateOrEditVm: HeightCreateOrEditVm by viewModels() + + private var _binding: FragmentListLayoutBinding? = null + val mBinding get() = _binding!! + + private val dataList = mutableListOf() + + val adapter: RouteListAdapter by lazy { + RouteListAdapter(dataList, + { + //路线item点击 + doLookAndEditRoute(it) + }, + object : ContextMenuDelete() { + override fun delete(item: RouteRecord) { + doDelete(item) + } + }) + } + + private fun doLookAndEditRoute(item: RouteRecord) { + heightCreateOrEditVm.showCreateOrEditDialog( + getProjectId()!!, + routeId = item.getId(), + childFragmentManager, + viewLifecycleOwner + ) + } + + private fun doDelete(item: RouteRecord) { + 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: RouteRecord) { + lifecycleScope.launch(Dispatchers.IO) { + SurveyorDataBase.getInstance().withTransaction { + val stationList = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRoute( + routeRecord.projectId, + routeRecord.getId() + ) + + //删除路线 + SurveyorDatabaseFactory.instance.getRouteDataSource().delete(routeRecord) + //删除测站 + SurveyorDatabaseFactory.instance.surveyorStation.deleteByRouteId(routeRecord.getId()) + + if (PointUtil.isCanDeleteHeightTraverseAutoCreatePoint(routeRecord.startPointId)) { + SurveyorDatabaseFactory.instance.pointDataSource.deleteById(routeRecord.startPointId) + } + + if (PointUtil.isCanDeleteHeightTraverseAutoCreatePoint(routeRecord.endPointId)) { + SurveyorDatabaseFactory.instance.pointDataSource.deleteById(routeRecord.endPointId) + } + + for (stationItem in stationList) { + if (stationItem.items != null) { + for (surveyorPoint in stationItem.items) { + if (PointUtil.isCanDeleteHeightTraverseAutoCreatePoint(surveyorPoint.originalPointId)) { + //删除点 + SurveyorDatabaseFactory.instance.pointDataSource.deleteById( + surveyorPoint.originalPointId + ) + } + + } + } + } + + } + } + } + + 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) + + mBinding.list.adapter = adapter + + getProjectId()?.let { it -> + SurveyorDatabaseFactory.instance.getRouteDataSource().getListLiveData(it) + .observe(viewLifecycleOwner) { + adapter.updateData(it) + } + } + } + + + fun getProjectId() = arguments?.getString(BundleConstants.KEY_PROJECT_ID) + + + companion object { + fun newInstance(projectId: String): RouteFragment { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + val routeFragment = RouteFragment() + 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/fragment/projectedit/AbstractProjectEditFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/AbstractProjectEditFragment.kt new file mode 100644 index 0000000..12685c4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/AbstractProjectEditFragment.kt @@ -0,0 +1,310 @@ +package com.bingce.controlnetwork.fragment.projectedit + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.text.TextUtils +import android.view.View +import androidx.activity.result.ActivityResultLauncher +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.room.withTransaction +import blankj.utilcode.util.ToastUtils +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.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 +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +abstract class AbstractProjectEditFragment : AbstractFullScreenDialogFragment() { + companion object { + + const val KEY_PROJECT_ID = "___project__id" + const val KEY_PROJECT_TYPE = "___project__type" + const val KEY_PROJECT_NAME = "___project___name___" + const val KEY_TOLERANCE_ID = "___tolerance_id" + + @JvmStatic + fun editProject( + fragmentManager: FragmentManager, + context: Context, + projectId: String, projectType: String?, toleranceId: String?, projectName: String? + ) { + newInstance( + context, projectId, projectType, + toleranceId, projectName + ).show(fragmentManager, "_edit_project_fragment") + } + + @JvmStatic + fun createProject( + fragmentManager: FragmentManager, + context: Context, + projectType: String? + ) { + newInstance(context, null, projectType, null, null) + .show(fragmentManager, "__create_project_fragment__") + } + + private fun newInstance( + context: Context, projectId: String?, projectType: String?, + toleranceId: String?, projectName: String? + ): DialogFragment { + val fragment = + if (projectType == ProjectType.HEIGHT_TRAVERSE.flag) ProjectEditHeightTraverseFragment() + else ProjectEditTriangleFragment() + + val args = Bundle() + if (projectId.isNullOrEmpty()) { + setArgs(args, context.getString(R.string.title_create_new_project), null) + args.putString(KEY_PROJECT_TYPE, projectType) + } else { + setArgs(args, context.getString(R.string.title_edit_project), null) + args.putString(KEY_PROJECT_ID, projectId) + args.putString(KEY_PROJECT_TYPE, projectType) + args.putString(KEY_TOLERANCE_ID, toleranceId) + args.putString(KEY_PROJECT_NAME, projectName) + } + fragment.arguments = args + return fragment + } + + } + + + protected val scope = MainScope() + + private lateinit var selectedToleranceId: String + + private lateinit var selectToleranceLauncher: ActivityResultLauncher + + + protected fun initSelectToleranceLauncher(fragment: Fragment) { + selectToleranceLauncher = ToleranceSelectFragment.createActivityLauncher( + fragment + ) { + updateToleranceData(it) + } + } + + + fun getProjectId() = arguments?.getString(KEY_PROJECT_ID) + fun getProjectType() = arguments?.getString(KEY_PROJECT_TYPE) + fun getProjectName() = arguments?.getString(KEY_PROJECT_NAME) + fun getToleranceId() = arguments?.getString(KEY_TOLERANCE_ID) + + override fun onDestroyView() { + super.onDestroyView() + scope.cancel() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initView() + initData() + } + + protected open fun initView() { + getToleranceBtn().setOnClickListener { + selectTolerance() + } + } + + protected abstract fun getCurrentProjectName(): String + abstract fun getShowSlopSwitch(): Boolean + abstract fun setToleranceName(name: String) + abstract fun setProjectName(name: String) + abstract fun setShowSlopSwitch(isChecked: Boolean) + abstract fun getToleranceBtn(): View + + //存其他的数据,如果是高程导线存自己的配置信息,没有自己的数据就空实现即可 + abstract suspend fun saveOtherRecord(projectId: String) + + + private fun updateToleranceData(toleranceId: String?) { + toleranceId?.let { + scope.launch { + val toleranceDetailRecord = withContext(Dispatchers.IO) { + SurveyorDatabaseFactory.instance + .toleranceDetailDataSource + .getRecordSync(toleranceId) + } + toleranceDetailRecord?.let { + 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}" + + setToleranceName("${groupRecord?.name ?: ""}${lineName}-${it.name}") + + selectedToleranceId = toleranceId + } + } + } + } + + protected open fun initData() { + initToleranceData() + //设置项目名称 + 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()) { + ProjectType.TRIANGLE.flag -> true + ProjectType.CONNECTION.flag -> false + else -> true + } + setShowSlopSwitch(checked) + } else { + scope.launch { + val projectRecord = withContext(Dispatchers.IO) { + SurveyorDatabaseFactory.instance + .projectDataSource + .getRecord(projectId) + } + projectRecord?.let { + setShowSlopSwitch(it.isShowSlopDistance) + } + } + } + } + + private fun selectTolerance() { + //选择限差 + ToleranceSelectFragment.start( + context, + getToleranceId(), + getProjectType(), + selectToleranceLauncher + ) + } + + private fun checkBase(): Boolean { + val projectName = getCurrentProjectName() + if (TextUtils.isEmpty(projectName)) { + ToastUtils.showShort(R.string.tips_need_select_input_project_name) + return false + } + + if (!::selectedToleranceId.isInitialized || TextUtils.isEmpty(selectedToleranceId)) { + ToastUtils.showShort(R.string.tips_need_select_project_tolerance) + return false + } + return true + } + + override fun onConfirm() { + if (!checkBase()) return + saveRecord() + } + + private fun saveRecord() { + scope.launch { + LoadingUtilKt.show(requireContext(), null) + + //开始事务 + SurveyorDataBase.getInstance().withTransaction { + if (isEdit()) { + savaRecordEdit(getCurrentProjectName(), getShowSlopSwitch()) + } else { + val projectRecord = ProjectRecord(getCurrentProjectName()) + projectRecord.projectType = getProjectType() + projectRecord.setToleranceId(selectedToleranceId) + projectRecord.isShowSlopDistance = getShowSlopSwitch() + savaRecordNew(projectRecord) + } + } + + LoadingUtilKt.dismiss() + + super.onConfirm() + } + } + + private suspend fun savaRecordNew(projectRecord: ProjectRecord) { + //存储 + SurveyorDatabaseFactory.instance + .projectDataSource + .saveRecordSync(projectRecord) + + if (ProjectType.HEIGHT_TRAVERSE.flag != projectRecord.getProjectType()) { + //非高程导线 + //创建默认测期 + val surveyorPeriodRecord = + SurveyorPeriodRecord(projectRecord.getId(), DefaultNameUtil.getDefaultPeriodName()) + SurveyorDatabaseFactory.instance + .surveyorPeriod + .saveRecordSync(surveyorPeriodRecord) + + //创建新项目的时候存默认的测期 + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PERIOD_ID, + surveyorPeriodRecord.getId() + ) + } else { + //创建高程导线时候清空默认路线 + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_ROUTE_ID, + null + ) + } + + //创建新项目的时候存默认的项目,无论是否是高程导线 + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PROJECT_ID, + projectRecord.getId() + ) + + saveOtherRecord(projectRecord.getId()) + } + + private suspend fun savaRecordEdit(currentProjectName: String, showSlopSwitch: Boolean) { + val projectRecord = SurveyorDatabaseFactory.instance + .projectDataSource + .getRecord(getProjectId()) + + projectRecord.setProjectName(currentProjectName) + projectRecord.setToleranceId(selectedToleranceId) + projectRecord.isShowSlopDistance = showSlopSwitch + + //存储 + SurveyorDatabaseFactory.instance + .projectDataSource + .saveRecordSync(projectRecord) + + saveOtherRecord(getProjectId()!!) + } + + protected fun isEdit() = getProjectId() != null + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditHeightTraverseFragment.kt new file mode 100644 index 0000000..65e7ad3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditHeightTraverseFragment.kt @@ -0,0 +1,239 @@ +package com.bingce.controlnetwork.fragment.projectedit + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.EveryWay +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.HeighTraverseConfigRecord +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.SeparateWay +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.StationLayout +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentProjectEditHeightTraverseBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 高程导线新建编辑 + */ +class ProjectEditHeightTraverseFragment : AbstractProjectEditFragment() { + + private val stationLayoutList = listOf( + "隔点设站,设站一次", + "隔点设站,设站两次", + "每点设站,单向观测", + "每点设站,对向观测", + ) + + companion object { +// const val POSITION_SEPARATION = 0//隔点设站的index + + const val POSITION_SEPARATE_SET_UP_ONCE = 0 + const val POSITION_SEPARATE_SET_UP_TWICE = 1 + const val POSITION_EVERY_SINGLE_MEASURE = 2 + const val POSITION_EVERY_OPPOSITE_MEASURE = 3 + } + + init { + initSelectToleranceLauncher(this) + } + + private var _binding: FragmentProjectEditHeightTraverseBinding? = null + private val mBinding get() = _binding!! + + override fun createContentView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentProjectEditHeightTraverseBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun initView() { + super.initView() + + mBinding.spinner.setAdapter( + ArrayAdapter( + requireContext(), + R.layout.item_spinner_text, + stationLayoutList + ) + ) +// mBinding.dtlStationMode.observeIndexChange { fromIndex, toIndex, reselect, fromUser -> +// if (toIndex == POSITION_SEPARATION) { +// //隔点设站 +// mBinding.everyMeasureModeParent.visibility = View.GONE +// mBinding.separationMeasureModeParent.visibility = View.VISIBLE +// } else { +// //每点设站 +// mBinding.everyMeasureModeParent.visibility = View.VISIBLE +// mBinding.separationMeasureModeParent.visibility = View.GONE +// } +// } + } + + override fun initData() { + super.initData() + getProjectId()?.let { + scope.launch { + setEditClickEnable(it) + setStationLayoutData(it) + } + } + } + + /** + *设置布局方式数据 + */ + private suspend fun setStationLayoutData(projectId: String) { + val record = withContext(Dispatchers.IO) { + getRecord(projectId) + } + record?.let { + val stationLayoutSpinnerPos = if (it.stationLayout == StationLayout.SEPARATE) { + if (it.separateWay == SeparateWay.SET_UP_ONCE) { + POSITION_SEPARATE_SET_UP_ONCE + } else { + POSITION_SEPARATE_SET_UP_TWICE + } + } else { + if (it.everyWay == EveryWay.SINGLE_MEASURE) { + POSITION_EVERY_SINGLE_MEASURE + } else { + POSITION_EVERY_OPPOSITE_MEASURE + } + } + mBinding.spinner.setSelection(stationLayoutSpinnerPos) +// mBinding.dtlStationMode.onPageSelected(it.stationLayout.ordinal) +// it.separateWay?.ordinal?.let { +// mBinding.dtlSeparationMeasureMode.onPageSelected(it) +// } +// it.everyWay?.ordinal?.let { +// mBinding.dtlEveryMeasureMode.onPageSelected(it) +// } + } + } + + /** + * 当项目中新建测站了就不能编辑了布置方式了 + */ + private suspend fun setEditClickEnable(projectId: String) { + withContext(Dispatchers.IO) { + val countByProjectId = + SurveyorDatabaseFactory.instance.surveyorStation.getCountByProjectId(projectId) + + if (countByProjectId != 0) { +// mBinding.dtlStationMode.itemEnableSelector = false +// mBinding.dtlSeparationMeasureMode.itemEnableSelector = false +// mBinding.dtlEveryMeasureMode.itemEnableSelector = false + mBinding.spinner.isEnabled = false + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + + override fun getCurrentProjectName(): String { + return mBinding.il.editor.text.toString().trim() + } + + override fun setToleranceName(name: String) { + mBinding.il.selectTolerance.text = name + } + + override fun setProjectName(name: String) { + mBinding.il.editor.setText(name) + } + + override fun setShowSlopSwitch(isChecked: Boolean) { + mBinding.il.showSlopSwitch.isChecked = isChecked + } + + override fun getToleranceBtn(): View { + return mBinding.il.selectTolerance + } + + override suspend fun saveOtherRecord(projectId: String) { + var record = getRecord(projectId) + if (record == null) { + record = HeighTraverseConfigRecord.newInstance( + projectId, getStationLayout(), + getSeparateWay(), + getEveryWay() + ) + } else { + record.stationLayout = getStationLayout() + record.separateWay = getSeparateWay() + record.everyWay = getEveryWay() + } + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource().saveRecord(record) + } + + private suspend fun getRecord(projectId: String): HeighTraverseConfigRecord? { + val heightTraverseConfigDataSource = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + return heightTraverseConfigDataSource.getRecordByProjectId(projectId) + } + +// private fun getStationLayout() = when (mBinding.dtlStationMode.currentItemIndex) { +// POSITION_SEPARATION -> { +// StationLayout.SEPARATE +// } +// +// else -> StationLayout.EVERY +// } +// +// private fun getSeparateWay() = getSeparateOrEveryWay(mBinding.dtlSeparationMeasureMode) { +// SeparateWay.values()[it] +// } +// +// private fun getEveryWay() = getSeparateOrEveryWay(mBinding.dtlEveryMeasureMode) { +// EveryWay.values()[it] +// } + + private fun getStationLayout() = when (mBinding.spinner.selectedItemPosition) { + POSITION_SEPARATE_SET_UP_ONCE, POSITION_SEPARATE_SET_UP_TWICE -> { + StationLayout.SEPARATE + } + + else -> StationLayout.EVERY + } + + private fun getSeparateWay() = when (mBinding.spinner.selectedItemPosition) { + POSITION_SEPARATE_SET_UP_ONCE -> { + SeparateWay.SET_UP_ONCE + } + + POSITION_SEPARATE_SET_UP_TWICE -> { + SeparateWay.SET_UP_TWICE + } + + else -> null + } + + private fun getEveryWay() = when (mBinding.spinner.selectedItemPosition) { + POSITION_EVERY_SINGLE_MEASURE -> { + EveryWay.SINGLE_MEASURE + } + + POSITION_EVERY_OPPOSITE_MEASURE -> { + EveryWay.OPPOSITE_MEASURE + } + + else -> null + } + + + override fun getShowSlopSwitch(): Boolean { + return mBinding.il.showSlopSwitch.isChecked + } + +} \ No newline at end of file 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 new file mode 100644 index 0000000..378ad93 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditTriangleFragment.kt @@ -0,0 +1,74 @@ +package com.bingce.controlnetwork.fragment.projectedit + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource +import com.bingce.controlnetwork.databinding.FragmentProjectEditTriangleBinding + +/** + * 三角测量和联系测量共用 + */ +class ProjectEditTriangleFragment : AbstractProjectEditFragment() { + + init { + initSelectToleranceLauncher(this) + } + + private var _binding: FragmentProjectEditTriangleBinding? = null + + private val mBinding get() = _binding!! + + + val configDataSource: IConfigDataSource = SurveyorDatabaseFactory.instance.configDataSource + + override fun createContentView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentProjectEditTriangleBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun quitWhenTouchBg(): Boolean { + return true + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun getCurrentProjectName(): String { + return mBinding.il.editor.text.toString().trim() + } + + override fun setToleranceName(name: String) { + mBinding.il.selectTolerance.text = name + } + + override fun setProjectName(name: String) { + mBinding.il.editor.setText(name) + } + + override fun setShowSlopSwitch(isChecked: Boolean) { + mBinding.il.showSlopSwitch.isChecked = isChecked + } + + override fun getToleranceBtn(): View { + return mBinding.il.selectTolerance + } + + override suspend fun saveOtherRecord(projectId: String) { + //暂无使用 + } + + override fun getShowSlopSwitch(): Boolean { + return mBinding.il.showSlopSwitch.isChecked + } + + +} \ No newline at end of file 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 new file mode 100644 index 0000000..5359839 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/AbstractStationFragment.java @@ -0,0 +1,112 @@ +package com.bingce.controlnetwork.fragment.station; + +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.appcompat.widget.SwitchCompat; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +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 { + + /** + * 错误提示-已经存在重复测期测站 + * + * @param duplicateStationName + */ + protected void tipsError(String duplicateStationName) { + runOnUI(() -> { + if (getContext() == null) { + return; + } + TipsFragment.tipsOnly( + getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + duplicateStationError(duplicateStationName)); + }); + } + + protected String duplicateStationError(String duplicateStationName) { + return Tools.getString(R.string.already_exist_station_period, duplicateStationName); + } + + protected abstract int layoutRes(); + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(layoutRes(), container, false); + } + + protected static boolean warningDataLosing(@NonNull Fragment fragment) { + TipsWith2OptionFragment + .tips( + fragment.getChildFragmentManager(), + fragment.getViewLifecycleOwner(), + fragment.getString(R.string.exit), + fragment.getString(R.string.cancel), + fragment.getString(R.string.tips_station_data_will_lose), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + if (fragment.getActivity() != null) { + fragment.getActivity().finish(); + } + } + } + ); + return true; + } + + protected static boolean switchIsChecked(View view, int id) { + if (view == null) { + return false; + } + 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; + } + + protected boolean needLeftRightSurveyor() { + return switchIsChecked(getView(), R.id.left_right_switch); + } + + protected void updateLeftRightMark(View view, boolean need) { + if (view == null) { + return; + } + SwitchWithText switchCompat = view.findViewById(R.id.left_right_switch); + if (switchCompat != null) { + switchCompat.setChecked(need); + } + } + + protected static boolean isListEmpty(List stationItems) { + return stationItems != null && !stationItems.isEmpty(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/AbstractSingleStationPointListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/AbstractSingleStationPointListFragment.java new file mode 100644 index 0000000..7a381a0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/AbstractSingleStationPointListFragment.java @@ -0,0 +1,201 @@ +package com.bingce.controlnetwork.fragment.station.defaultstation; + +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.BaseStationDetailAdapter; +import com.bingce.controlnetwork.adapter.stationdetail.EditableStationDetailAdapter; +import com.bingce.controlnetwork.adapter.stationdetail.NoEditableStationDetailAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.fragment.station.AbstractStationFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import blankj.utilcode.util.ToastUtils; + +public abstract class AbstractSingleStationPointListFragment extends AbstractStationFragment + implements BaseStationDetailAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + private static final String TYPE_SURVEYOR_STATION = "___station_points"; + private static final String TYPE_SURVEYOR_POINT = "___surveyor_points"; + private BaseStationDetailAdapter defaultStationDetailAdapter; + private final ActivityResultLauncher defaultStationLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (TYPE_SURVEYOR_STATION.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().get(0) == null || + pickPointResult.getSelectedNames().get(0) == null) { + showStationPointError(); + return; + } + defaultStationDetailAdapter.setStationPoint( + pickPointResult.getSelectedIds().get(0), + pickPointResult.getSelectedNames().get(0)); + } else if (TYPE_SURVEYOR_POINT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedNames().size() || + pickPointResult.getSelectedIds().size() < 2) { + showPointCountError(); + return; + } + defaultStationDetailAdapter.setSurveyorPoint( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } + onItemChanged(); + }); + + protected abstract void prepareAdapterData(IDataCallback callback); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + prepareAdapterData((editAble, items) -> { + if (getContext() == null) { + return; + } + if (editAble) { + defaultStationDetailAdapter = new EditableStationDetailAdapter( + AbstractSingleStationPointListFragment.this, + items); + } else { + defaultStationDetailAdapter = new NoEditableStationDetailAdapter(items); + } + runOnUI(() -> { + recyclerView.setAdapter(defaultStationDetailAdapter); + SwipeDraggableRecyclerViewUtil.setup(defaultStationDetailAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + this, + getContext()); + }); + }); + } + setHasOptionsMenu(true); + return view; + } + + protected final List collectDataItems() { + if (defaultStationDetailAdapter == null) { + return null; + } + return defaultStationDetailAdapter.collectData(); + } + + /** + * 将数据库存储的测站点列表和显示的顺序保持一致 + * + * @param surveyorStationRecord + */ + protected final void sortStationPoint(SurveyorStationRecord surveyorStationRecord) { + List currentItems = collectDataItems(); + if (currentItems == null) { + return; + } + //对现有数据进行排序 + Map map = new HashMap<>(); + for (SurveyorPoint item : surveyorStationRecord.getItems()) { + map.put(item.getPointId(), item); + } + for (int index = 0; index < currentItems.size(); index++) { + SurveyorPoint item = currentItems.get(index); + if (item == null) { + continue; + } + SurveyorPoint find = map.get(item.getPointId()); + if (find == null) { + continue; + } + currentItems.set(index, find); + } + surveyorStationRecord.setItems(currentItems); + } + + @Override + public void onSelectStationPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_SURVEYOR_STATION, + 1, + getContext().getString(R.string.select_station_point), + filters, + projectId, pickPointResult, defaultStationLauncher); + } + + @Override + public void onSelectSurveyorPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_SURVEYOR_POINT, + -1, + getContext().getString(R.string.select_surveyor_point), + filters, + projectId, pickPointResult, defaultStationLauncher); + } + + @Override + public void onItemRemoved(int adapterPosition) { + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + protected abstract void onItemChanged(); + + protected int surveyorPointSize() { + return defaultStationDetailAdapter.surveyorPointSize(); + } + + private void showPointCountError() { + ToastUtils.showShort(R.string.tips_surveyor_point_must_more_than_2); + } + + private void showStationPointError() { + ToastUtils.showShort(R.string.tips_please_select_station_point); + } + + public interface IDataCallback { + void onGetAdapterData(boolean editAble, List items); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/ComponentSingleStationPointListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/ComponentSingleStationPointListFragment.java new file mode 100644 index 0000000..c56a024 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/ComponentSingleStationPointListFragment.java @@ -0,0 +1,177 @@ +package com.bingce.controlnetwork.fragment.station.defaultstation; + +import android.os.Bundle; + +import androidx.annotation.WorkerThread; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +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.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.stationdetail.StationDetailViewModel; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.List; + +public class ComponentSingleStationPointListFragment extends AbstractSingleStationPointListFragment { + + @Override + protected int layoutRes() { + return R.layout.fragment_surveyor_station_point_list_layout; + } + + @Override + protected void prepareAdapterData(IDataCallback callback) { + if (getArguments() == null) { + return; + } + String stationId = getArguments().getString(KEY_STATION_ID); + IPointDataSource pointDataSource = SurveyorDatabaseFactory + .instance + .getPointDataSource(); + ThreadPoolUtil.execute(() -> { + if (getContext() == null) { + return; + } + //1.读取测站数据 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory.instance.getSurveyorStation().getRecordSync(stationId); + List items = surveyorStationRecord.getItems(); + //2.提取测站点和测点 + List pointIdsWithoutStation = new ArrayList<>(); + List pointNamesWithoutStation = new ArrayList<>(); + String stationPointId = null; + String stationPointName = null; + for (SurveyorPoint item : items) { + if (item == null) { + continue; + } + if (SurveyorPoint.TYPE_STATION.equals(item.getType())) { + stationPointId = item.getPointId(); + PointRecord pointRecord = pointDataSource.findByIdSync(stationPointId); + if (pointRecord != null) { + stationPointName = pointRecord.getName(); + } + } else if (SurveyorPoint.TYPE_POINT.equals(item.getType())) { + pointIdsWithoutStation.add(item.getPointId()); + PointRecord pointRecord = pointDataSource.findByIdSync(item.getPointId()); + if (pointRecord != null) { + pointNamesWithoutStation.add(pointRecord.getName()); + } + } + } + //3.为adapter创建数据源 + List itemList = new ArrayList<>(); + //添加测站title item + itemList.add( + new StationDetailItem( + getContext().getString(R.string.select_station_point), + StationDetailItem.ITEM_TYPE_STATION_GROUP, + null)); + if (stationPointId != null && stationPointName != null) { + //添加测站点 + StationDetailItem item = + new StationDetailItem( + stationPointName, + StationDetailItem.ITEM_TYPE_STATION_ITEM, + stationPointId); + itemList.add(item); + } + //添加测点title item + itemList.add( + new StationDetailItem( + getContext().getString(R.string.select_surveyor_point), + StationDetailItem.ITEM_TYPE_POINT_GROUP, + null)); + for (int index = 0; index < pointIdsWithoutStation.size(); index++) { + String id = pointIdsWithoutStation.get(index); + String name = pointNamesWithoutStation.get(index); + if (id == null || name == null) { + continue; + } + //添加测点 + StationDetailItem item = + new StationDetailItem( + name, + StationDetailItem.ITEM_TYPE_POINT_ITEM, + id); + itemList.add(item); + } + //4.回调 + callback.onGetAdapterData(isCanEditSurveyorPoint(surveyorStationRecord), itemList); + + runOnUI(() -> updateLeftRightMark(getView(), surveyorStationRecord.leftAndRightSurveyor)); + }); + } + + @Override + protected void onItemChanged() { + if (getArguments() == null) { + return; + } + String stationId = getArguments().getString(KEY_STATION_ID); + ThreadPoolUtil.execute(() -> { + if (getContext() == null) { + return; + } + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + //1.读取测站数据 + SurveyorStationRecord currentRecord = stationDataSource.getRecordSync(stationId); + if (currentRecord == null) { + return; + } + //2.排序测站列表 + sortStationPoint(currentRecord); + //3.存储测站record + stationDataSource.saveSync(currentRecord); + //4.更新测点数量 + runOnUI(() -> { + if (getActivity() == null) { + return; + } + }); + }); + } + + @Override + public boolean cancelBack() { + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + public static final String TAG = ComponentSingleStationPointListFragment.class.getName(); + + public static ComponentSingleStationPointListFragment newInstance(String stationId, String projectId) { + ComponentSingleStationPointListFragment fragment = new ComponentSingleStationPointListFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + fragment.setArguments(bundle); + return fragment; + } + + @WorkerThread + private boolean isCanEditSurveyorPoint(SurveyorStationRecord stationRecord) { + ProjectRecord projectRecord = SurveyorDatabaseFactory.instance.getProjectDataSource().getRecord(stationRecord.getProjectId()); + if (projectRecord.getProjectType() == null || projectRecord.getProjectType().equals(ProjectType.TRIANGLE.getFlag())) { + if (!SurveyorStationRecord.isLineStation(stationRecord.getLineId())) { + long surveyorRecordCount = + SurveyorDatabaseFactory + .instance + .getSurveyorRecordDataSource() + .recordCount(stationRecord.getId()); + return surveyorRecordCount <= 0; + } + } + return false; + } +} 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 new file mode 100644 index 0000000..424e32f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/DefaultStationSetupFragment.java @@ -0,0 +1,229 @@ +package com.bingce.controlnetwork.fragment.station.defaultstation; + +import android.content.Context; +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 com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +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.model.BundleConstants; +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; +import java.util.List; + +public class DefaultStationSetupFragment extends AbstractSingleStationPointListFragment { + 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; + } + + @Override + protected void prepareAdapterData(IDataCallback callback) { + if (callback == null || getContext() == null) { + return; + } + List itemList = Arrays.asList( + new StationDetailItem( + getContext().getString(R.string.select_station_point), + StationDetailItem.ITEM_TYPE_STATION_GROUP, + null), + new StationDetailItem( + getContext().getString(R.string.select_surveyor_point), + StationDetailItem.ITEM_TYPE_POINT_GROUP, + null)); + callback.onGetAdapterData(true, itemList); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(lastConfirmEnable); + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (R.id.menu_confirm == item.getItemId()) { + //收集信息,并创建站点记录 + List stationItems = collectDataItems(); + if (stationItems == null || getArguments() == null) { + return super.onOptionsItemSelected(item); + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + ThreadPoolUtil.execute(() -> { + //找到站的点id + String stationPointId = ""; + for (SurveyorPoint stationItem : stationItems) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + stationPointId = stationItem.getPointId(); + break; + } + } + String name = checkValidate(stationPointId, projectId, periodId); + if (name != null && !name.isEmpty()) { + tipsError(name); + return; + } + //先对stationItems点作处理 + //处理方式就是,如果这里面有点是global_control,将其拷贝到project known_point中 + //并使用拷贝的pointId替换stationItems里面的id + PointUtil.globalToProjectControlPoint(stationItems, projectId); + + IPointDataSource pointDataSource = + SurveyorDatabaseFactory.instance.getPointDataSource(); + PointRecord pointRecord = pointDataSource.findByIdSync(stationPointId); + if (pointRecord == null) { + return; + } + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(projectId); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.isShowSlopDistance(); + } + SurveyorStationRecord stationRecord = SurveyorStationRecord.mulAngle(projectId, periodId); + stationRecord.setItems(stationItems); + if (stationItems.size() > 4) { + stationRecord.setAutoClose(true); + } + //检测左右角 + stationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor()); + + stationRecord.setShowSlopDistance(showSlopDistance); + + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .saveSync(stationRecord); + + + runOnUI(() -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + }); + } + return super.onOptionsItemSelected(item); + } + + protected static String checkValidate(String stationPointId, String projectId, String periodId) { + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance + .getSurveyorStation(); + List stationRecordList = + stationDataSource.getDataList(projectId, periodId); + if (stationRecordList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : stationRecordList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + if (stationItem.getPointId().equals(stationPointId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + break; + } + } + } + } + } + return null; + } + + protected boolean isCurrentDataValidate() { + List stationItems = collectDataItems(); + if (stationItems == null || stationItems.size() < 3) { + return false; + } else { + //检测是否有station item + for (SurveyorPoint item : stationItems) { + if (item == null) { + continue; + } + if (SurveyorPoint.TYPE_STATION.equals(item.getType())) { + return true; + } + } + } + return false; + } + + @Override + protected void onItemChanged() { + if (confirmItem != null) {//设置menuItem enable + boolean confirmEnable = isCurrentDataValidate(); + confirmItem.setEnabled(confirmEnable); + lastConfirmEnable = confirmEnable; + } + //检测左右角是否 + SwitchWithText leftAndRightSwitch = findViewById(R.id.left_right_switch); + if (leftAndRightSwitch != null) { + int pointSize = surveyorPointSize(); + if (pointSize == 2) { + leftAndRightSwitch.setVisibility(View.VISIBLE); + } else { + leftAndRightSwitch.setChecked(false); + leftAndRightSwitch.setVisibility(View.GONE); + } + } + } + + @Override + public boolean cancelBack() { + List items = collectDataItems(); + if (isListEmpty(items)) { + return warningDataLosing(this); + } + return false; + } + + public static final int title = R.string.new_surveyor_station; + + public static void start(Context context, String projectId, String period) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, period); + FragmentContainerActivity.start(context, TAG, title, bundle); + } + + public static DefaultStationSetupFragment newInstance(Bundle bundle) { + DefaultStationSetupFragment fragment = new DefaultStationSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/SingleStationDetailAndEditContentFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/SingleStationDetailAndEditContentFragment.java new file mode 100644 index 0000000..0116ad2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/SingleStationDetailAndEditContentFragment.java @@ -0,0 +1,195 @@ +package com.bingce.controlnetwork.fragment.station.defaultstation; + + +import static com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord.isLineStation; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +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.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.stationdetail.StationDetailViewModel; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.List; + + +public class SingleStationDetailAndEditContentFragment extends AbstractSingleStationPointListFragment { + + private StationDetailViewModel viewModel; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + viewModel = new ViewModelProvider(requireActivity()).get(StationDetailViewModel.class); + } + + @Override + protected int layoutRes() { + return R.layout.item_recycler_view_layout; + } + + @Override + protected void prepareAdapterData(IDataCallback callback) { + if (getArguments() == null) { + return; + } + String stationId = getArguments().getString(KEY_STATION_ID); + IPointDataSource pointDataSource = SurveyorDatabaseFactory + .instance + .getPointDataSource(); + ThreadPoolUtil.execute(() -> { + if (getContext() == null) { + return; + } + //1.读取测站数据 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory.instance.getSurveyorStation().getRecordSync(stationId); + List items = surveyorStationRecord.getItems(); + //2.提取测站点和测点 + List pointIdsWithoutStation = new ArrayList<>(); + List pointNamesWithoutStation = new ArrayList<>(); + String stationPointId = null; + String stationPointName = null; + for (SurveyorPoint item : items) { + if (item == null) { + continue; + } + if (SurveyorPoint.TYPE_STATION.equals(item.getType())) { + stationPointId = item.getPointId(); + PointRecord pointRecord = pointDataSource.findByIdSync(stationPointId); + if (pointRecord != null) { + stationPointName = pointRecord.getName(); + } + } else if (SurveyorPoint.TYPE_POINT.equals(item.getType())) { + pointIdsWithoutStation.add(item.getPointId()); + PointRecord pointRecord = pointDataSource.findByIdSync(item.getPointId()); + if (pointRecord != null) { + pointNamesWithoutStation.add(pointRecord.getName()); + } + } + } + //3.为adapter创建数据源 + List itemList = new ArrayList<>(); + //添加测站title item + itemList.add( + new StationDetailItem( + getContext().getString(R.string.select_station_point), + StationDetailItem.ITEM_TYPE_STATION_GROUP, + null)); + if (stationPointId != null && stationPointName != null) { + //添加测站点 + StationDetailItem item = + new StationDetailItem( + stationPointName, + StationDetailItem.ITEM_TYPE_STATION_ITEM, + stationPointId); + itemList.add(item); + } + //添加测点title item + itemList.add( + new StationDetailItem( + getContext().getString(R.string.select_surveyor_point), + StationDetailItem.ITEM_TYPE_POINT_GROUP, + null)); + for (int index = 0; index < pointIdsWithoutStation.size(); index++) { + String id = pointIdsWithoutStation.get(index); + String name = pointNamesWithoutStation.get(index); + if (id == null || name == null) { + continue; + } + //添加测点 + StationDetailItem item = + new StationDetailItem( + name, + StationDetailItem.ITEM_TYPE_POINT_ITEM, + id); + itemList.add(item); + } + //4.回调 + boolean editAble; + if (isLineStation(surveyorStationRecord.getLineId())) { + editAble = false; + } else { + //检测记录数量,如果为0,则可编辑,否则不可编辑 + long surveyorRecordCount = + SurveyorDatabaseFactory + .instance + .getSurveyorRecordDataSource() + .recordCount(surveyorStationRecord.getId()); + editAble = surveyorRecordCount <= 0; + } + callback.onGetAdapterData(editAble, itemList); + + runOnUI(() -> { + viewModel.setLeftOrRight(surveyorStationRecord.isLeftAndRightSurveyor()); + updateSurverPointCount(); + }); + }); + } + + @Override + protected void onItemChanged() { + if (getArguments() == null) { + return; + } + String stationId = getArguments().getString(KEY_STATION_ID); + ThreadPoolUtil.execute(() -> { + if (getContext() == null) { + return; + } + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + //1.读取测站数据 + SurveyorStationRecord currentRecord = stationDataSource.getRecordSync(stationId); + if (currentRecord == null) { + return; + } + //2.排序测站列表 + sortStationPoint(currentRecord); + //3.存储测站record + stationDataSource.saveSync(currentRecord); + //4.更新测点数量 + runOnUI(() -> { + if (getActivity() == null) { + return; + } + updateSurverPointCount(); + }); + }); + } + + @Override + public boolean cancelBack() { + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + public static final String TAG = SingleStationDetailAndEditContentFragment.class.getName(); + + public static SingleStationDetailAndEditContentFragment newInstance(String stationId, String projectId) { + SingleStationDetailAndEditContentFragment fragment = new SingleStationDetailAndEditContentFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + fragment.setArguments(bundle); + return fragment; + } + + private void updateSurverPointCount() { + viewModel.setRefreshUi(); + } + + public int getSurveyorPointSize() { + return surveyorPointSize(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/AbstructSetupStationHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/AbstructSetupStationHeightTraverseFragment.kt new file mode 100644 index 0000000..33ace4c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/AbstructSetupStationHeightTraverseFragment.kt @@ -0,0 +1,181 @@ +package com.bingce.controlnetwork.fragment.station.heighttraverse + +import android.os.Bundle +import android.view.View +import androidx.annotation.WorkerThread +import androidx.fragment.app.Fragment +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.util.RegExUtil +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.utils.DateUtils +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import java.util.Date + +abstract class AbstructSetupStationHeightTraverseFragment : Fragment() { + + val prefixStation: String = Tools.getString(R.string.transfer) + val prefixJianXie: String = Tools.getString(R.string.break_point) + val prefixTransfer: String = Tools.getString(R.string.turn_point) + + private val mainScope = MainScope() + + abstract fun doConfirm() + abstract fun isCheckedJianXiePoint(): Boolean + abstract fun isCheckedEndPoint(): Boolean + abstract fun getFrontPointHeight(): String + + abstract suspend fun getBackPoint(): PointRecord + abstract suspend fun getFrontPoint(): PointRecord + abstract suspend fun getStationPoint(): PointRecord? + abstract fun initView() + abstract fun initListener() + abstract fun initData() + + fun launch(block: suspend CoroutineScope.() -> Unit) { + mainScope.launch(Dispatchers.IO) { + block.invoke(this) + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initView() + initListener() + initData() + } + + override fun onDestroyView() { + super.onDestroyView() + mainScope.cancel() + } + + fun getProjectId(): String { + val createStationForHeightTraverseFragment = + parentFragment as CreateStationForHeightTraverseFragment + return createStationForHeightTraverseFragment.getProjectId() + } + + fun getRouteId(): String { + val createStationForHeightTraverseFragment = + parentFragment as CreateStationForHeightTraverseFragment + return createStationForHeightTraverseFragment.getRouteId() + } + + fun createStationRecordNoSurveyorPoints( + projectId: String, + projectType: String, + relationStationId: String? + ): SurveyorStationRecord { + val stationRecord = SurveyorStationRecord() + stationRecord.id = DateUtils.genRandomTimeId() + stationRecord.projectId = projectId + stationRecord.projectType = projectType + stationRecord.showSlopDistance = true + stationRecord.createDate = Date() + stationRecord.routeId = getRouteId() + stationRecord.items = mutableListOf() + stationRecord.relationStationId = relationStationId + return stationRecord + } + + protected fun finish() { + requireActivity().finish() + } + + @WorkerThread + protected fun savePoint( + pointName: String, + pointTypeHeightTraverse: String?, + projectId: String, + height: String? + ): String { +// var pointRecord = +// SurveyorDatabaseFactory.instance.pointDataSource.findByNameSync( +// pointName, +// projectId +// ) +// if (pointRecord == null) { +// pointRecord = PointRecord.point( +// getProjectId(), +// PointRecord.TYPE_UNKNOWN_POINT, +// pointName, +// "", +// 0.0, +// 0.0, +// stringToDouble(height), +// "", +// -1 +// ) +// pointRecord.pointTypeHeightTraverse = pointTypeHeightTraverse +// SurveyorDatabaseFactory.instance.pointDataSource.saveSync(pointRecord) +// } else { +// pointRecord.setZ(stringToDouble(height)) +// SurveyorDatabaseFactory.instance.pointDataSource.update(pointRecord) +// } + + val pointRecord = PointRecord.point( + projectId, + PointRecord.TYPE_UNKNOWN_POINT, + pointName, + "", + 0.0, + 0.0, + stringToDouble(height), + "", + -1 + ) + pointRecord.pointTypeHeightTraverse = pointTypeHeightTraverse + SurveyorDatabaseFactory.instance.pointDataSource.saveSync(pointRecord) + + return pointRecord.getId() + } + + @WorkerThread + protected fun saveFrontPoint(projectId: String, frontName: String): String { + var frontPointTypeHeightTraverse: String? = null + if (isCheckedJianXiePoint()) { + frontPointTypeHeightTraverse = + PointRecord.TYPE_HEIGHT_TRAVERSE_INTERVAL + } else if (isCheckedEndPoint()) { + //终点 + } else { + frontPointTypeHeightTraverse = + PointRecord.TYPE_HEIGHT_TRAVERSE_TRANSFER + } + + val frontHeight = getFrontPointHeight() + + return savePoint(frontName, frontPointTypeHeightTraverse, projectId, frontHeight) + } + + fun doubleToString(value: Double) = value.toString() + fun stringToDouble(value: String?): Double { + if (value.isNullOrEmpty()) { + return 0.0 + } + return value.toDouble() + } + + @WorkerThread + protected fun getNewIndexFromTwoPointId(pointId1: String, pointId2: String): PointRecord { + val point1 = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId1) + val point2 = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId2) + val index1 = RegExUtil.getIndexFromName(point1.getName()) + val index2 = RegExUtil.getIndexFromName(point2.getName()) + if (index1 >= index2) { + return point1 + } + return point2 + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/CreateStationForHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/CreateStationForHeightTraverseFragment.kt new file mode 100644 index 0000000..bf62a2c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/CreateStationForHeightTraverseFragment.kt @@ -0,0 +1,176 @@ +package com.bingce.controlnetwork.fragment.station.heighttraverse + +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 androidx.fragment.app.Fragment +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.EveryWay +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.SeparateWay +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.StationLayout +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlnetwork.databinding.FragmentCreateStationForHeightTraverseBinding +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch + +/** + * 高程导线 新建测站 + */ +class CreateStationForHeightTraverseFragment : Fragment() { + + private lateinit var confirmItem: MenuItem + + private var _binding: FragmentCreateStationForHeightTraverseBinding? = null + val mBinding get() = _binding!! + private val mainScope = MainScope() + + private var currentFragment: AbstructSetupStationHeightTraverseFragment? = null + + + companion object { + @JvmField + val TAG: String = CreateStationForHeightTraverseFragment::class.java.name + + @JvmStatic + fun newInstance(args: Bundle?): Fragment { + val fragment: Fragment = CreateStationForHeightTraverseFragment() + fragment.arguments = args + return fragment + } + + @JvmStatic + fun start(context: Context, projectId: String?, routeId: String?) { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + bundle.putString(BundleConstants.KEY_ROUTE_ID, routeId) + FragmentContainerActivity.start( + context, + TAG, + R.string.new_surveyor_station,//新建测站 + bundle + ) + } + + } + + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + setHasOptionsMenu(true) + _binding = + FragmentCreateStationForHeightTraverseBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_confirm, menu) + confirmItem = menu.findItem(R.id.menu_confirm) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.menu_confirm == item.itemId) { + currentFragment?.doConfirm() + } + return super.onOptionsItemSelected(item) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + init() + } + + private fun init() { + mainScope.launch { + val configRecord = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + .getRecordByProjectId(getProjectId()) + configRecord?.let { + + val stringBuilder = StringBuilder() + stringBuilder.append(Tools.getString(R.string.note_current_station_is)) + + if (it.stationLayout == StationLayout.SEPARATE) { + + if (it.separateWay == SeparateWay.SET_UP_ONCE) { + stringBuilder.append(Tools.getString(R.string.set_up_station_is_seperate_once)) + + replaceFragment( + SeparatSetupStationFragment.newInstance( + SeparatSetupStationFragment.TYPE_ONCE + ) + ) + } else if (it.separateWay == SeparateWay.SET_UP_TWICE) { + stringBuilder.append(Tools.getString(R.string.set_up_station_is_seperate_twice)) + + replaceFragment( + SeparatSetupStationFragment.newInstance( + SeparatSetupStationFragment.TYPE_TWICE + ) + ) + } + } else if (it.stationLayout == StationLayout.EVERY) { + + if (it.everyWay == EveryWay.SINGLE_MEASURE) { + stringBuilder.append(Tools.getString(R.string.set_up_station_is_each_one_way)) + + replaceFragment( + EverySetUpStationFragment.newInstance( + EverySetUpStationFragment.TYPE_ONE_WAY + ) + ) + } else if (it.everyWay == EveryWay.OPPOSITE_MEASURE) { + stringBuilder.append(Tools.getString(R.string.set_up_station_is_each_opposite)) + + replaceFragment( + EverySetUpStationFragment.newInstance( + EverySetUpStationFragment.TYPE_TWO_WAY + ) + ) + } + } + + setTvHint(stringBuilder.toString()) + } + } + + + } + + private fun setTvHint(text: String) { + mBinding.tvHint.text = text + } + + fun getProjectId(): String { + return requireArguments().getString(BundleConstants.KEY_PROJECT_ID)!! + } + + fun getRouteId(): String { + return requireArguments().getString(BundleConstants.KEY_ROUTE_ID)!! + } + + private fun replaceFragment(fragment: AbstructSetupStationHeightTraverseFragment) { + currentFragment = fragment + + val beginTransaction = childFragmentManager.beginTransaction() + beginTransaction.replace(R.id.fl_container, fragment) + beginTransaction.commit() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/EverySetUpStationFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/EverySetUpStationFragment.kt new file mode 100644 index 0000000..994d027 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/EverySetUpStationFragment.kt @@ -0,0 +1,313 @@ +package com.bingce.controlnetwork.fragment.station.heighttraverse + +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.WorkerThread +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.heighttraverse.config.model.EveryWay +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint +import com.bingce.controlapphelper.util.RegExUtil +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentHeightTraverseEverySetupStationBinding +import com.bingce.utils.DateUtils +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * 每点设站 创建测站 + */ +class EverySetUpStationFragment : AbstructSetupStationHeightTraverseFragment() { + + private val mBinding get() = _binding!! + + private var _binding: FragmentHeightTraverseEverySetupStationBinding? = null + + private lateinit var backPoint: PointRecord + private var isFirstStation = false + + companion object { + private const val KEY_TYPE = "KEY_TYPE" + const val TYPE_ONE_WAY = 1 + const val TYPE_TWO_WAY = 2 + + @JvmStatic + fun newInstance(type: Int): EverySetUpStationFragment { + val fragment = EverySetUpStationFragment() + val bundle = Bundle() + bundle.putInt(KEY_TYPE, type) + fragment.arguments = bundle + return fragment + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = + FragmentHeightTraverseEverySetupStationBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun initView() { + mBinding.ilBackTitle.tvTitle.text = Tools.getString(R.string.back_station) + mBinding.ilFrontTitle.tvTitle.text = Tools.getString(R.string.front_station) + //说明信息 + mBinding.ilDesc.tvDesc.text = getString(R.string.staton_setup_every_height_traverse_hint) + //前视打开设置间歇点和终点 + mBinding.ilFrontTitle.llCb.visibility = View.VISIBLE + //设置不可点击 + mBinding.ilBack.etPoint.isFocusable = false + mBinding.ilBack.etHeight.isFocusable = false + mBinding.ilFront.etPoint.isFocusable = false + } + + override fun initListener() { + var isClickCheckBox = false + mBinding.ilFrontTitle.cbJianXie.setOnCheckedChangeListener { buttonView, isChecked -> + if (isClickCheckBox) return@setOnCheckedChangeListener + isClickCheckBox = true + mBinding.ilFrontTitle.cbEnd.isChecked = false + refreshFrontUi() + isClickCheckBox = false + } + mBinding.ilFrontTitle.cbEnd.setOnCheckedChangeListener { buttonView, isChecked -> + if (isClickCheckBox) return@setOnCheckedChangeListener + isClickCheckBox = true + mBinding.ilFrontTitle.cbJianXie.isChecked = false + refreshFrontUi() + isClickCheckBox = false + } + } + + override fun initData() { + launch { + backPoint = getBackPoint() + val frontPoint = getFrontPoint() + withContext(Dispatchers.Main) { + setUi(backPoint, frontPoint) + } + } + } + + private fun setUi(back: PointRecord, front: PointRecord) { + setUiBack(back) + setUiFront(front) + } + + private fun setUiBack(pointRecord: PointRecord) { + mBinding.ilBack.etPoint.setText(pointRecord.getName()) + mBinding.ilBack.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + private fun setUiFront(pointRecord: PointRecord) { + mBinding.ilFront.etPoint.setText(pointRecord.getName()) + mBinding.ilFront.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + + private fun refreshFrontUi() { + launch { + val frontPoint = getFrontPoint() + withContext(Dispatchers.Main) { + setUiFront(frontPoint) + } + } + } + + override suspend fun getBackPoint(): PointRecord { + val projectId = getProjectId() + val routeId = getRouteId() + + val stationLatest = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRouteLatest( + projectId, + routeId + ) + + if (stationLatest?.items != null && stationLatest.items.size >= 2) { + val pointRecord: PointRecord = + if (!TextUtils.isEmpty(stationLatest.relationStationId)) { + //对向观测 + getNewIndexFromTwoPointId( + stationLatest.items[0].originalPointId, + stationLatest.items[1].originalPointId + ) + } else { + val pointId = stationLatest.items[1].originalPointId + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId) + } + isFirstStation = false + return pointRecord + } + + isFirstStation = true + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.startPointId) + } + + override suspend fun getFrontPoint(): PointRecord { + var frontIndexNew = 1 + if (!isFirstStation) { + val index = RegExUtil.getIndexFromName(backPoint.getName()) + if (index != -1) { + frontIndexNew = index + 1 + } + } + +// val projectId = getProjectId() + val routeId = getRouteId() + + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + + if (mBinding.ilFrontTitle.cbEnd.isChecked) { + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.endPointId) + } else if (mBinding.ilFrontTitle.cbJianXie.isChecked) { +// val intervalPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_INTERVAL +// ) +// val intervalRecord = PointRecord() +// if (intervalPoint == null) { +// intervalRecord.name = "$prefixJianXie${1}" +// } else { +// val index = RegExUtil.getIndexFromName(intervalPoint.getName()) +// intervalRecord.name = "$prefixJianXie${index + 1}" +// } +// return intervalRecord + val intervalRecord = PointRecord() + intervalRecord.name = "$prefixJianXie${frontIndexNew}" + return intervalRecord + } else { +// val transferPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_TRANSFER +// ) +// val transferRecord = PointRecord() +// if (transferPoint == null) { +// transferRecord.name = "$prefixTransfer${1}" +// } else { +// val index = RegExUtil.getIndexFromName(transferPoint.getName()) +// transferRecord.name = "$prefixTransfer${index + 1}" +// } +// return transferRecord + + val transferRecord = PointRecord() + transferRecord.name = "$prefixTransfer${frontIndexNew}" + return transferRecord + } + } + + override suspend fun getStationPoint(): PointRecord? { + return null + } + + + override fun doConfirm() { + val backName = mBinding.ilBack.etPoint.text.toString().trim() + val frontName = mBinding.ilFront.etPoint.text.toString().trim() + + if (TextUtils.isEmpty(backName)) { + ToastUtils.showShort("backName is empty") + return + } + if (TextUtils.isEmpty(frontName)) { + ToastUtils.showShort("frontName is empty") + return + } + + launch { + val projectId = getProjectId() + val projectRecord = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + + val heightTraverseConfig = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + .getRecordByProjectId(projectId) + + val isTwiceSetup = heightTraverseConfig?.everyWay == EveryWay.OPPOSITE_MEASURE + + SurveyorDataBase.getInstance().withTransaction { + val frontSetupId = saveFrontPoint(projectId, frontName) + + val relationStationId = if (isTwiceSetup) DateUtils.genRandomTimeId() else null + + saveStationRecord( + projectId, + projectRecord.getProjectType(), + backPoint.getId(), + frontSetupId, + relationStationId + ) + + if (isTwiceSetup) { + saveStationRecord( + projectId, + projectRecord.getProjectType(), + frontSetupId, + backPoint.getId(), + relationStationId + ) + } + withContext(Dispatchers.Main) { + finish() + } + } + + } + + } + + override fun isCheckedJianXiePoint(): Boolean { + return mBinding.ilFrontTitle.cbJianXie.isChecked + } + + override fun isCheckedEndPoint(): Boolean { + return mBinding.ilFrontTitle.cbEnd.isChecked + } + + override fun getFrontPointHeight(): String { + return mBinding.ilFront.etHeight.text.toString().trim() + } + + @WorkerThread + private fun saveStationRecord( + projectId: String, + projectType: String, + stationPointId: String, + surveyorPointId: String, + relationStationId: String? + ) { + val stationRecord = + createStationRecordNoSurveyorPoints(projectId, projectType, relationStationId) + stationRecord.items.add( + SurveyorPoint.newInstance( + stationPointId, + SurveyorPoint.TYPE_STATION + ) + ) + stationRecord.items.add( + SurveyorPoint.newInstance( + surveyorPointId, + SurveyorPoint.TYPE_POINT + ) + ) + SurveyorDatabaseFactory.instance.surveyorStation.saveSync(stationRecord) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/SeparatSetupStationFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/SeparatSetupStationFragment.kt new file mode 100644 index 0000000..26c0596 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/SeparatSetupStationFragment.kt @@ -0,0 +1,428 @@ +package com.bingce.controlnetwork.fragment.station.heighttraverse + +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.WorkerThread +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.heighttraverse.config.model.SeparateWay +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint +import com.bingce.controlapphelper.util.RegExUtil +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentHeightTraverseSeperateSetupStationBinding +import com.bingce.utils.DateUtils +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * 隔点设站 创建测站 + */ +class SeparatSetupStationFragment : AbstructSetupStationHeightTraverseFragment() { + private val mBinding get() = _binding!! + private var _binding: FragmentHeightTraverseSeperateSetupStationBinding? = null + + private lateinit var backPoint: PointRecord + private var isFirstStation = false + + companion object { + private const val KEY_TYPE = "KEY_TYPE" + const val TYPE_ONCE = 1 + const val TYPE_TWICE = 2 + + @JvmStatic + fun newInstance(type: Int): SeparatSetupStationFragment { + val separatSetupStationFragment = SeparatSetupStationFragment() + val bundle = Bundle() + bundle.putInt(KEY_TYPE, type) + separatSetupStationFragment.arguments = bundle + return separatSetupStationFragment + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = + FragmentHeightTraverseSeperateSetupStationBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun initView() { + mBinding.ilBackTitle.tvTitle.text = Tools.getString(R.string.rearview) + mBinding.ilStationTitle.tvTitle.text = Tools.getString(R.string.measure_station) + mBinding.ilFrontTitle.tvTitle.text = Tools.getString(R.string.forward_view) + //说明信息 + mBinding.ilDesc.tvDesc.text = getString(R.string.staton_setup_separate_height_traverse_hint) + //前视打开设置间歇点和终点 + mBinding.ilFrontTitle.llCb.visibility = View.VISIBLE + //设置不可点击 + mBinding.ilBack.etPoint.isFocusable = false + mBinding.ilBack.etHeight.isFocusable = false + mBinding.ilStation.etPoint.isFocusable = false + mBinding.ilFront.etPoint.isFocusable = false + } + + override fun initListener() { + var isClickCheckBox = false + mBinding.ilFrontTitle.cbJianXie.setOnCheckedChangeListener { buttonView, isChecked -> + if (isClickCheckBox) return@setOnCheckedChangeListener + isClickCheckBox = true + mBinding.ilFrontTitle.cbEnd.isChecked = false + refreshFrontUi() + isClickCheckBox = false + } + mBinding.ilFrontTitle.cbEnd.setOnCheckedChangeListener { buttonView, isChecked -> + if (isClickCheckBox) return@setOnCheckedChangeListener + isClickCheckBox = true + mBinding.ilFrontTitle.cbJianXie.isChecked = false + refreshFrontUi() + isClickCheckBox = false + } + } + + override fun initData() { + launch { + backPoint = getBackPoint() + val frontPoint = getFrontPoint() + val stationPoint = getStationPoint() + + withContext(Dispatchers.Main) { + setUi(backPoint, stationPoint, frontPoint) + } + } + } + + private fun setUi(back: PointRecord, station: PointRecord, front: PointRecord) { + setUiBack(back) + setUiStation(station) + setUiFront(front) + } + + private fun setUiFront(pointRecord: PointRecord) { + mBinding.ilFront.etPoint.setText(pointRecord.getName()) + mBinding.ilFront.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + private fun setUiBack(pointRecord: PointRecord) { + mBinding.ilBack.etPoint.setText(pointRecord.getName()) + mBinding.ilBack.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + private fun setUiStation(pointRecord: PointRecord) { + mBinding.ilStation.etPoint.setText(pointRecord.getName()) + mBinding.ilStation.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + + private fun refreshFrontUi() { + launch { + val frontPoint = getFrontPoint() + withContext(Dispatchers.Main) { + setUiFront(frontPoint) + } + } + } + + override fun doConfirm() { + + val backName = mBinding.ilBack.etPoint.text.toString().trim() + val stationName = mBinding.ilStation.etPoint.text.toString().trim() + val frontName = mBinding.ilFront.etPoint.text.toString().trim() + + if (TextUtils.isEmpty(backName)) { + ToastUtils.showShort("backName is empty") + return + } + if (TextUtils.isEmpty(stationName)) { + ToastUtils.showShort("stationName is empty") + return + } + if (TextUtils.isEmpty(frontName)) { + ToastUtils.showShort("frontName is empty") + return + } + + launch { + val projectId = getProjectId() + val projectRecord = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + + val configRecord = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + .getRecordByProjectId(getProjectId()) + + val isTwiceSetup = configRecord?.separateWay == SeparateWay.SET_UP_TWICE + + SurveyorDataBase.getInstance().withTransaction { + + val stationSetupIdList = + saveStationPoint(projectId, stationName, isTwiceSetup) + + val frontSetupId = saveFrontPoint(projectId, frontName) + + val relationStationId = if (isTwiceSetup) DateUtils.genRandomTimeId() else null + + for (stationPointId in stationSetupIdList) { + val stationRecord = + createStationRecordNoSurveyorPoints( + projectId, + projectRecord.getProjectType(), + relationStationId + ) + + stationRecord.items.add( + SurveyorPoint.newInstance( + stationPointId, + SurveyorPoint.TYPE_STATION + ) + ) + stationRecord.items.add( + SurveyorPoint.newInstance( + backPoint.getId(), + SurveyorPoint.TYPE_POINT + ) + ) + stationRecord.items.add( + SurveyorPoint.newInstance( + frontSetupId, + SurveyorPoint.TYPE_POINT + ) + ) + SurveyorDatabaseFactory.instance.surveyorStation.saveSync(stationRecord) + } + + withContext(Dispatchers.Main) { + finish() + } + } + + } + } + + override fun isCheckedJianXiePoint(): Boolean { + return mBinding.ilFrontTitle.cbJianXie.isChecked + } + + override fun isCheckedEndPoint(): Boolean { + return mBinding.ilFrontTitle.cbEnd.isChecked + } + + override fun getFrontPointHeight(): String { + return mBinding.ilFront.etHeight.text.toString().trim() + } + + override suspend fun getBackPoint(): PointRecord { + val projectId = getProjectId() + val routeId = getRouteId() + +// val stationLatest = +// SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRouteLatest( +// projectId, +// routeId +// ) +// +// if (stationLatest?.items != null && stationLatest.items.size >= 3) { +// val surveyorPoint = stationLatest.items[2] +// return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(surveyorPoint.originalPointId) +// } + + val stationList = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRouteLastTwo( + projectId, + routeId + ) + val newestPointRecord = getNewestPointRecord(stationList, 2) + if (newestPointRecord != null) { + isFirstStation = false + return newestPointRecord + } + + isFirstStation = true + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.startPointId) + } + + override suspend fun getFrontPoint(): PointRecord { +// val projectId = getProjectId() + val routeId = getRouteId() + + var frontIndexNew = 1 + if (!isFirstStation) { + val index = RegExUtil.getIndexFromName(backPoint.getName()) + if (index != -1) { + frontIndexNew = index + 1 + } + } + + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + + if (mBinding.ilFrontTitle.cbEnd.isChecked) { + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.endPointId) + } else if (mBinding.ilFrontTitle.cbJianXie.isChecked) { +// val intervalPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_INTERVAL +// ) +// +// val intervalRecord = PointRecord() +// if (intervalPoint == null) { +// intervalRecord.name = "$prefixJianXie${1}" +// } else { +// val index = RegExUtil.getIndexFromName(intervalPoint.getName()) +// intervalRecord.name = "$prefixJianXie${index + 1}" +// } +// return intervalRecord + val intervalRecord = PointRecord() + intervalRecord.name = "$prefixJianXie${frontIndexNew}" + return intervalRecord + } else { +// val transferPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_TRANSFER +// ) +// +// val transferRecord = PointRecord() +// if (transferPoint == null) { +// transferRecord.name = "$prefixTransfer${1}" +// } else { +// val index = RegExUtil.getIndexFromName(transferPoint.getName()) +// transferRecord.name = "$prefixTransfer${index + 1}" +// } +// return transferRecord + val transferRecord = PointRecord() + transferRecord.name = "$prefixTransfer$frontIndexNew" + return transferRecord + } + } + + override suspend fun getStationPoint(): PointRecord { + val projectId = getProjectId() + val routeId = getRouteId() + val stationList = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRouteLastTwo( + projectId, + routeId + ) + + var index = 1 + val newestPointRecord = getNewestPointRecord(stationList, 0) + if (newestPointRecord != null) { + val indexFromName = RegExUtil.getIndexFromName(newestPointRecord.name) + if (indexFromName != -1) { + index = indexFromName + 1 + } + } + val stationRecord = PointRecord() + stationRecord.name = "$prefixStation${index}" + return stationRecord +// val stationPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_STATION_TRANSFER +// ) +// val stationRecord = PointRecord() +// if (stationPoint == null) { +// stationRecord.name = "$prefixStation${1}" +// } else { +// val index = RegExUtil.getIndexFromName(stationPoint.getName()) +// stationRecord.name = "$prefixStation${index+1}" +// } +// return stationRecord + } + + + /** + * 存储测站点并返回测站id + * + * return 新建测站的ids + */ + @WorkerThread + private fun saveStationPoint( + projectId: String, + stationNameShow: String, + isTwiceSetup: Boolean + ): List { + + val stationHeight = mBinding.ilStation.etHeight.text.toString().trim() + + val index = RegExUtil.getIndexFromName(stationNameShow) + val stationIdList = mutableListOf() + + val pointTypeHeightTraverse = PointRecord.TYPE_HEIGHT_TRAVERSE_STATION_TRANSFER + + if (isTwiceSetup) { + stationIdList.add( + savePoint( + "$prefixStation${index}${Tools.getString(R.string._left)}", + pointTypeHeightTraverse, + projectId, + stationHeight + ) + ) + stationIdList.add( + savePoint( + "$prefixStation${index}${Tools.getString(R.string._right)}", + pointTypeHeightTraverse, + projectId, + stationHeight + ) + ) + } else { + stationIdList.add( + savePoint( + "$prefixStation${index}", + pointTypeHeightTraverse, + projectId, + stationHeight + ) + ) + } + + return stationIdList + } + + /** + * type 0 站点,1 后视 2 前视 + */ + @WorkerThread + private fun getNewestPointRecord( + stationList: List, + type: Int + ): PointRecord? { + var pointRecord: PointRecord? = null + for (item in stationList) { + if (item.items != null && item.items.size >= 3) { + val surveyorPoint = item.items[type] + val everyPointRecord = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(surveyorPoint.originalPointId) + val indexFromName = RegExUtil.getIndexFromName(everyPointRecord?.name ?: "") + if (indexFromName != -1) { + if (pointRecord == null) pointRecord = everyPointRecord + if (pointRecord != null) { + val indexLast = RegExUtil.getIndexFromName(pointRecord.name) + if (indexFromName > indexLast) { + pointRecord = everyPointRecord + } + } + } + } + } + return pointRecord + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownKnownSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownKnownSetupFragment.java new file mode 100644 index 0000000..2826426 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownKnownSetupFragment.java @@ -0,0 +1,247 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +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 androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineKnownUnknownKnownAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +public abstract class AbstractLineStationKnownUnknownKnownSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineKnownUnknownKnownAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + private static final String TYPE_KNOWN_POINT1 = "___known_points1"; + private static final String TYPE_UNKNOWN_POINT = "___unknown_points"; + private static final String TYPE_KNOWN_POINT2 = "___known_points2"; + private StationCreateLineKnownUnknownKnownAdapter stationCreateLineAttachAdapter; + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (TYPE_KNOWN_POINT1.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().size() != knownItemMinCount()) { + showKnownPointError(); + return; + } + stationCreateLineAttachAdapter.setKnownPoints1( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } else if (TYPE_UNKNOWN_POINT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().isEmpty()) { + showUnknownPointError(); + return; + } + stationCreateLineAttachAdapter.setUnknownPoints( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } else if (TYPE_KNOWN_POINT2.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().size() != knownItemMinCount()) { + showKnownPointError(); + return; + } + stationCreateLineAttachAdapter.setKnownPoints2( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } + onItemChanged(); + }); + private MenuItem confirmItem; + + protected abstract int selectKnownPointTitle(); + + protected abstract int knownItemMinCount(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(instance -> runOnUI(() -> { + stationCreateLineAttachAdapter = new StationCreateLineKnownUnknownKnownAdapter( + AbstractLineStationKnownUnknownKnownSetupFragment.this, instance); + recyclerView.setAdapter(stationCreateLineAttachAdapter); + SwipeDraggableRecyclerViewUtil.setup(stationCreateLineAttachAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationKnownUnknownKnownSetupFragment.this, + getContext()); + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onSelectKnownPoint1(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_KNOWN_POINT1, + knownItemMinCount(), + getString(R.string.title_pick_known_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectUnknownPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_UNKNOWN_POINT, + -1, + getString(R.string.title_pick_unknown_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectKnownPoint2(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_KNOWN_POINT2, + knownItemMinCount(), + getString(R.string.title_pick_known_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onItemRemoved(int adapterPosition) { + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + protected void onItemChanged() { + //检测数据是否合法 + List knownItems1 = stationCreateLineAttachAdapter.knownItems1(); + List unknownItems = stationCreateLineAttachAdapter.unknownItems(); + List knownItems2 = stationCreateLineAttachAdapter.knownItems2(); + if (confirmItem != null) { + confirmItem.setEnabled(!(knownItems1.size() < knownItemMinCount() || + unknownItems.isEmpty() || + knownItems2.size() < knownItemMinCount())); + } + } + + private void showUnknownPointError() { + ToastUtils.showShort(R.string.tips_unknown_point_must_not_empty); + } + + protected abstract int knownPointCountError(); + + private void showKnownPointError() { + ToastUtils.showShort(knownPointCountError()); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } + requestLineName(string -> { + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + //1.收集所有点信息 + List knownItems1 = stationCreateLineAttachAdapter.knownItems1(); + List unknownItems = stationCreateLineAttachAdapter.unknownItems(); + List knownItems2 = stationCreateLineAttachAdapter.knownItems2(); + //2.建站 + setup(projectId, periodId, string, knownItems1, unknownItems, knownItems2, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + List knownItems1 = stationCreateLineAttachAdapter.knownItems1(); + List unknownItems = stationCreateLineAttachAdapter.unknownItems(); + List knownItems2 = stationCreateLineAttachAdapter.knownItems2(); + if (isListEmpty(knownItems1) || + isListEmpty(unknownItems) || + isListEmpty(knownItems2)) { + return warningDataLosing(this); + } + return false; + } + + protected abstract void setup(String projectId, String periodId, + String lineName, + List knownItems1, + List unknownItems, + List knownItems2, + Runnable callback); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownSetupFragment.java new file mode 100644 index 0000000..fa93ec2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownSetupFragment.java @@ -0,0 +1,251 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +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 androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineSingleAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +public abstract class AbstractLineStationKnownUnknownSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineSingleAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + private static final String TYPE_KNOWN_POINT = "___known_points"; + private static final String TYPE_UNKNOWN_POINT = "___unknown_points"; + private StationCreateLineSingleAdapter stationCreateLineSingleAdapter; + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (TYPE_KNOWN_POINT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().size() < knownItemMinCount()) { + showKnownPointError(); + return; + } + stationCreateLineSingleAdapter.setKnownPoints( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } else if (TYPE_UNKNOWN_POINT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().size() < unknownItemMinCount()) { + showUnknownPointError(); + return; + } + stationCreateLineSingleAdapter.setUnknownPoints( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } + onItemChanged(); + }); + private MenuItem confirmItem; + + protected abstract int knownItemMinCount(); + + protected abstract int knownGroupTitle(); + + protected abstract int knownPointCountError(); + + protected abstract int unknownItemMinCount(); + + protected abstract int unknownGroupTitle(); + + protected abstract int unknownPointCountError(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(instance -> runOnUI(() -> { + stationCreateLineSingleAdapter = new StationCreateLineSingleAdapter( + AbstractLineStationKnownUnknownSetupFragment.this, instance); + recyclerView.setAdapter(stationCreateLineSingleAdapter); + SwipeDraggableRecyclerViewUtil.setup(stationCreateLineSingleAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationKnownUnknownSetupFragment.this, + getContext()); + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onSelectKnownPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_KNOWN_POINT, + knownItemMinCount(), + getString(R.string.title_pick_known_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectUnknownPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_UNKNOWN_POINT, + -1, + getString(R.string.title_pick_unknown_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onItemRemoved(int adapterPosition) { + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + protected void onItemChanged() { + //检测数据是否合法 + List knownItems = knownItems(); + List unknownItems = unknownItems(); + if (confirmItem != null) { + confirmItem.setEnabled(!(knownItems.size() < knownItemMinCount() || unknownItems.isEmpty())); + } + } + + private void showUnknownPointError() { + ToastUtils.showShort(unknownPointCountError()); + } + + private void showKnownPointError() { + ToastUtils.showShort(knownPointCountError()); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + if (confirmItem == null) { + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } + //1.收集所有点信息 + List knownItems = knownItems(); + List unknownItems = unknownItems(); + //2.循环创建测站 + if (knownItems.size() != knownItemMinCount()) { + //当已知点不满足最少点的个数时提示 + showKnownPointError(); + return super.onOptionsItemSelected(item); + } + if (unknownItems.size() < unknownItemMinCount()) { + //当未知点不满足最少点的个数时提示 + showUnknownPointError(); + return super.onOptionsItemSelected(item); + } + //设置导线的名称(弹框设置名称) + requestLineName(lineName -> { + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + setup(projectId, periodId, lineName, knownItems, unknownItems, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + List knownItems = knownItems(); + List unknownItems = unknownItems(); + if (isListEmpty(knownItems) || + isListEmpty(unknownItems)) { + return warningDataLosing(this); + } + return false; + } + + /** + * 设置导线 + * + * @param projectId + * @param periodId + * @param lineName + * @param knownItems + * @param unknownItems + * @param runnable + */ + protected abstract void setup(String projectId, String periodId, + String lineName, + List knownItems, + List unknownItems, + Runnable runnable); + + protected List knownItems() { + return stationCreateLineSingleAdapter.knownItems(); + } + + protected List unknownItems() { + return stationCreateLineSingleAdapter.unknownItems(); + } +} 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 new file mode 100644 index 0000000..d41096f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationSetupFragment.java @@ -0,0 +1,109 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +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; + +import org.jetbrains.annotations.NotNull; + +public abstract class AbstractLineStationSetupFragment extends AbstractStationFragment { + private LineRecord currentBatch; + private ProjectRecord projectRecord; + + @Override + protected int layoutRes() { + return R.layout.fragment_line_surveyor_station_setup_layout; + } + + @Override + protected String duplicateStationError(String duplicateStationName) { + return Tools.getString(R.string.station_already_exist_same_name, duplicateStationName); + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + setLeftRightEnable(initLeftRightMeasure()); + //读取projectRecord + ThreadPoolUtil.execute(() -> { + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + projectRecord = + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(projectId); + }); + } + + private void setLeftRightEnable(boolean isEnable) { + //显示左右角开关 + View view = getView(); + if (view != null) { + SwitchWithText switchCompat = view.findViewById(R.id.left_right_switch); + if (switchCompat != null) { + switchCompat.setEnabled(isEnable); + } + } + } + + + protected String projectId() { + return projectRecord == null ? null : projectRecord.getId(); + } + + protected ProjectRecord currentProject() { + return projectRecord; + } + + protected void loadBatchRecord(String batchId, IOnListGetCallback callback) { + SurveyorStationUtil.getBatchItemList(batchId, lineRecord -> { + if (lineRecord == null) { + return; + } + callback.onGet(lineRecord.items); + currentBatch = lineRecord; + }); + } + + private String lineName() { + if (currentBatch != null) { + return currentBatch.name; + } + return defaultLineName(); + } + + protected LineRecord getCurrentBatch() { + return currentBatch; + } + + protected abstract boolean initLeftRightMeasure(); + + protected abstract String defaultLineName(); + + final protected void requestLineName(StringInputFragment.IInputCallback callback) { + StringInputFragment.input(getChildFragmentManager(), + getString(R.string.tips_please_input_line_name), + lineName(), + getViewLifecycleOwner(), + callback); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleGroundSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleGroundSetupFragment.java new file mode 100644 index 0000000..9c6f0dd --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleGroundSetupFragment.java @@ -0,0 +1,333 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +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.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineWellDoubleGroundAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.controlnetwork.util.SurveyorStationUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 二井定向地上父类 + */ +public abstract class AbstractLineStationWellDoubleGroundSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineWellDoubleGroundAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + + public static final String LINE_NAME = Tools.getString(R.string.erjing_directional_above_ground); + + private MenuItem confirmItem; + //选择到的点 + private List groundLinkLeftDataList; + private List groundLinkMiddleDataList; + private List groundLinkRightDataList; + private List groundSideADataList; + private List groundSideBDataList; + + private StationCreateLineWellDoubleGroundAdapter mAdapter; + + private final Handler handler = new Handler(Looper.getMainLooper()); + + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundLinkLeftMinCount()) { + showErrorMsg(Tools.getString(R.string.well_a_ground_connection_hint)); + return; + } + mAdapter.setGroundLinkLeftPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideAMinCount()) { + showErrorMsg(Tools.getString(R.string.well_a_surface_near_well_hint)); + return; + } + mAdapter.setGroundSideAPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideBMinCount()) { + showErrorMsg(Tools.getString(R.string.well_b_surface_near_well_hint)); + return; + } + mAdapter.setGroundSideBPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(type)) { + if (pickPointResult.getSelectedIds().size() < groundLinkRightMinCount()) { + showErrorMsg(Tools.getString(R.string.well_b_ground_connection_hint)); + return; + } + mAdapter.setGroundLinkRightPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE.equals(type)) { + mAdapter.setGroundLinkMiddlePoints(pickPointResult); + } + onItemChanged(); + }); + + protected abstract int groundLinkLeftMinCount(); + + protected abstract int groundSideAMinCount(); + + protected abstract int groundLinkMiddleMinCount(); + + protected abstract int groundSideBMinCount(); + + protected abstract int groundLinkRightMinCount(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + protected List getAdapterDataList() { + List items = null; + if (mAdapter != null) { + items = mAdapter.getItems(); + } + return items; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(stationDetailItemList -> runOnUI(() -> { + mAdapter = new StationCreateLineWellDoubleGroundAdapter( + AbstractLineStationWellDoubleGroundSetupFragment.this, stationDetailItemList); + + recyclerView.setAdapter(mAdapter); + SwipeDraggableRecyclerViewUtil.setup(mAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationWellDoubleGroundSetupFragment.this, + getContext()); + + refreshFiveDataList(); + + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); +// initAutoCloseView(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (handler != null) + handler.removeCallbacksAndMessages(null); + } + + protected void goSelectPoint(String type, int maxCount, String title, List filters, PickPointResult pickPointResult) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + type, + maxCount, + title, + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectGroundLinkLeft(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + groundLinkLeftMinCount() + 1, Tools.getString(R.string.well_a_ground_connection_direction_point), + filters, pickPointResult); + } + + @Override + public void onSelectGroundLinkRight(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + groundLinkRightMinCount() + 1, Tools.getString(R.string.well_b_ground_connection_direction_point), + filters, pickPointResult); + } + + @Override + public void onSelectGroundLinkMiddle(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE, + Integer.MAX_VALUE, Tools.getString(R.string.ground_connection_point), filters, pickPointResult); + } + + @Override + public void onSelectGroundSideA(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + 1, Tools.getString(R.string.well_a_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectGroundSideB(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + 1, Tools.getString(R.string.well_b_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectOnlyMeasureHorAngle(boolean measureHorAngle) { + LineRecord currentBatch = getCurrentBatch(); + SurveyorStationUtil.updateLineRecord(currentBatch); + SurveyorStationUtil.updateStationPointsMeasureHorAag(currentBatch); + } + + @Override + public void onItemRemoved(int adapterPosition) { + mAdapter.removeItemForLastSelect(adapterPosition); + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + private void onItemChanged() { + handler.postDelayed(() -> { + refreshFiveDataList(); + //检测数据是否合法 + if (confirmItem != null) { + confirmItem.setEnabled(!(groundLinkLeftDataList.size() < groundLinkLeftMinCount() || + groundLinkMiddleDataList.size() < groundLinkMiddleMinCount() || + groundLinkRightDataList.size() < groundLinkRightMinCount() || + groundSideADataList.size() < groundSideAMinCount() || + groundSideBDataList.size() < groundSideBMinCount() + )); + } + }, 80); + } + + private void refreshFiveDataList() { + groundLinkLeftDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT + StationDetailItem._DATA); + groundLinkMiddleDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE + StationDetailItem._DATA); + groundLinkRightDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT + StationDetailItem._DATA); + groundSideADataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A + StationDetailItem._DATA); + groundSideBDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B + StationDetailItem._DATA); + } + + protected void showErrorMsgForWell(String type) { + switch (type) { + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT: + showErrorMsg(Tools.getString(R.string.well_a_ground_connection_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE: + //中间点是可选 + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT: + showErrorMsg(Tools.getString(R.string.well_b_ground_connection_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A: + showErrorMsg(Tools.getString(R.string.well_a_surface_near_well_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B: + showErrorMsg(Tools.getString(R.string.well_b_surface_near_well_hint)); + break; + default: + break; + } + } + + private void showErrorMsg(String msg) { + ToastUtils.showShort(msg); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + // TODO: 2022/6/15 + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } +// //设置导线的弹框 +// requestLineName(string -> { +// //建站 +// }); + + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + setup(projectId, periodId, LINE_NAME, groundLinkLeftDataList, groundLinkMiddleDataList, groundLinkRightDataList, groundSideBDataList, groundSideADataList, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + // TODO: 2022/6/15 +// List knownItems1 = mAdapter.getGroundLinkPoints(); +// List unknownItems = mAdapter.unknownItems(); +// List knownItems2 = mAdapter.knownItems2(); +// if (isListEmpty(knownItems1) || +// isListEmpty(unknownItems) || +// isListEmpty(knownItems2)) { +// return warningDataLosing(this); +// } + return false; + } + + protected abstract void setup(String projectId, String periodId, + String lineName, + List groundLinkLeftDataList, + List groundLinkMiddleDataList, + List groundLinkRightDataList, + List groundSideBDataList, + List groundSideADataList, + Runnable callback); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleUnderGroundSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleUnderGroundSetupFragment.java new file mode 100644 index 0000000..cf33e4c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleUnderGroundSetupFragment.java @@ -0,0 +1,422 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +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.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.RegExUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineWellDoubleUnderGroundAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.controlnetwork.util.SurveyorStationUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 一井定向的父类 + */ +public abstract class AbstractLineStationWellDoubleUnderGroundSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineWellDoubleUnderGroundAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + + public static final String LINE_NAME = Tools.getString(R.string.second_well_directional_underground); + + private final Handler handler = new Handler(Looper.getMainLooper()); + + private MenuItem confirmItem; + //选择到的点 + private List groundLinkLeftDataList; + private List groundSideADataList; + private List steelADataList; + private List underGroundLinkDataList; + private List steeBDataList; + private List groundSideBDataList; + private List groundLinkRightDataList; + + private StationCreateLineWellDoubleUnderGroundAdapter mAdapter; + + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundLinkLeftMinCount()) { + showErrorMsg(Tools.getString(R.string.well_a_ground_connection_hint)); + return; + } + mAdapter.setGroundLinkLeftPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideAMinCount()) { + showErrorMsg(Tools.getString(R.string.well_a_surface_near_well_hint)); + return; + } + mAdapter.setGroundSideAPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideBMinCount()) { + showErrorMsg(Tools.getString(R.string.well_b_surface_near_well_hint)); + return; + } + mAdapter.setGroundSideBPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(type)) { + if (pickPointResult.getSelectedIds().size() < groundLinkRightMinCount()) { + showErrorMsg(Tools.getString(R.string.well_b_ground_connection_hint)); + return; + } + mAdapter.setGroundLinkRightPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideAMinCount()) { + showErrorMsg(Tools.getString(R.string.please_select_well_a_wire)); + return; + } + mAdapter.setSteelAPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideBMinCount()) { + showErrorMsg(Tools.getString(R.string.please_select_well_b_wire)); + return; + } + mAdapter.setSteelBPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < underGroundLinkMinCount()) { + showErrorMsg(Tools.getString(R.string.underground_connection_point_min_hint)); + return; + } + mAdapter.setUnderGroundLinkPoints(pickPointResult); + } + onItemChanged(); + }); + + protected abstract int groundLinkLeftMinCount(); + + protected abstract int groundSideAMinCount(); + + protected abstract int steelAMinCount(); + + protected abstract int underGroundLinkMinCount(); + + protected abstract int steelBMinCount(); + + protected abstract int groundSideBMinCount(); + + protected abstract int groundLinkRightMinCount(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + protected List getAdapterDataList() { + List items = null; + if (mAdapter != null) { + items = mAdapter.getItems(); + } + return items; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(stationDetailItemList -> runOnUI(() -> { + mAdapter = new StationCreateLineWellDoubleUnderGroundAdapter( + AbstractLineStationWellDoubleUnderGroundSetupFragment.this, stationDetailItemList); + + recyclerView.setAdapter(mAdapter); + SwipeDraggableRecyclerViewUtil.setup(mAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationWellDoubleUnderGroundSetupFragment.this, + getContext()); + + refreshFiveDataList(); + + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); +// initAutoCloseView(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (handler != null) + handler.removeCallbacksAndMessages(null); + } + + protected void goSelectPoint(String type, int maxCount, String title, List filters, PickPointResult pickPointResult) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + type, + maxCount, + title, + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectGroundLinkLeft(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + groundLinkLeftMinCount() + 1, Tools.getString(R.string.well_a_surface_connection_point), + filters, pickPointResult); + } + + @Override + public void onSelectGroundLinkRight(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + groundLinkRightMinCount() + 1, Tools.getString(R.string.well_b_surface_connection_point), + filters, pickPointResult); + } + + @Override + public void onSelectGroundSideA(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + 1, Tools.getString(R.string.well_a_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectGroundSideB(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + 1, Tools.getString(R.string.well_b_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectSteelA(PickPointResult pickPointResult, List filters) { +// goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A, +// steelAMinCount() + 1, "A井钢丝", filters, pickPointResult); + addSteelOnCurrentPage(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A, steelAMinCount() + 1); + } + + @Override + public void onSelectSteelB(PickPointResult pickPointResult, List filters) { +// goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B, +// steelBMinCount() + 1, "B井钢丝", filters, pickPointResult); + addSteelOnCurrentPage(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B, steelBMinCount() + 1); + } + + @Override + public void onSelectUnderGroundLink(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK, + Integer.MAX_VALUE, Tools.getString(R.string.underground_connection_point), filters, pickPointResult); + } + + @Override + public void onSelectOnlyMeasureHorAngle(boolean measureHorAngle) { + LineRecord currentBatch = getCurrentBatch(); + SurveyorStationUtil.updateLineRecord(currentBatch); + SurveyorStationUtil.updateStationPointsMeasureHorAag(currentBatch); + } + + + private void addSteelOnCurrentPage(String groupType, int steelMaxCount) { + List pointsFromType = mAdapter.getPointsFromType(groupType + StationDetailItem._DATA); + PickPointResult lastSteelPickPoint = PickPointResult.create(); + int newName = 1; + if (pointsFromType != null && !pointsFromType.isEmpty()) { + PickPointResult.initPicPointResultData(lastSteelPickPoint, pointsFromType); + //获取新的钢丝的索引 + StationDetailItem stationDetailItem = pointsFromType.get(pointsFromType.size() - 1); + String num = RegExUtil.findNum(stationDetailItem.getName()); + assert num != null; + newName = Integer.parseInt(num) + 1; + } + if (lastSteelPickPoint.getSelectedIds().size() >= steelMaxCount) { + ToastUtils.showShort(R.string.steel_max_hint, steelMaxCount); + return; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A.equals(groupType)) { + PickPointResult.createPointResultNewData(lastSteelPickPoint, Tools.getString(R.string.wire_a) + newName); + mAdapter.setSteelAPoints(lastSteelPickPoint); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B.equals(groupType)) { + PickPointResult.createPointResultNewData(lastSteelPickPoint, Tools.getString(R.string.wire_b) + newName); + mAdapter.setSteelBPoints(lastSteelPickPoint); + } + onItemChanged(); + } + + + @Override + public void onItemRemoved(int adapterPosition) { + mAdapter.removeItemForLastSelect(adapterPosition); + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + private void onItemChanged() { + handler.postDelayed(() -> { + refreshFiveDataList(); + //检测数据是否合法 + if (confirmItem != null) { + confirmItem.setEnabled(!(groundLinkLeftDataList.size() < groundLinkLeftMinCount() || + groundSideADataList.size() < groundSideAMinCount() || + steelADataList.size() < steelAMinCount() || + underGroundLinkDataList.size() < underGroundLinkMinCount() || + steeBDataList.size() < steelBMinCount() || + groundSideBDataList.size() < groundSideBMinCount() || + groundLinkRightDataList.size() < groundLinkRightMinCount() + )); + } + }, 80); + } + + private void refreshFiveDataList() { + String _data = StationDetailItem._DATA; + groundLinkLeftDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT + _data); + groundSideADataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A + _data); + steelADataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A + _data); + underGroundLinkDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK + _data); + steeBDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B + _data); + groundSideBDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B + _data); + groundLinkRightDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT + _data); + } + + protected void showErrorMsgForWell(String type) { + switch (type) { + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT: + showErrorMsg(Tools.getString(R.string.well_a_ground_connection_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT: + showErrorMsg(Tools.getString(R.string.well_b_ground_connection_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A: + showErrorMsg(Tools.getString(R.string.well_a_surface_near_well_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B: + showErrorMsg(Tools.getString(R.string.well_b_surface_near_well_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A: + showErrorMsg(Tools.getString(R.string.please_select_well_a_wire)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B: + showErrorMsg(Tools.getString(R.string.please_select_well_b_wire)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK: + showErrorMsg(Tools.getString(R.string.please_select_an_underground_connection_point)); + break; + default: + break; + } + } + + private void showErrorMsg(String msg) { + ToastUtils.showShort(msg); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + // TODO: 2022/6/15 + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } +// //设置导线的弹框 +// requestLineName(string -> { +// //建站 +// }); + + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + + setup(projectId, periodId, LINE_NAME, + groundLinkLeftDataList, + groundSideADataList, + steelADataList, + underGroundLinkDataList, + steeBDataList, + groundSideBDataList, + groundLinkRightDataList, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + // TODO: 2022/6/15 +// List knownItems1 = mAdapter.getGroundLinkPoints(); +// List unknownItems = mAdapter.unknownItems(); +// List knownItems2 = mAdapter.knownItems2(); +// if (isListEmpty(knownItems1) || +// isListEmpty(unknownItems) || +// isListEmpty(knownItems2)) { +// return warningDataLosing(this); +// } + return false; + } + + protected abstract void setup(String projectId, String periodId, + String lineName, + List groundLinkLeftDataList, + List groundSideADataList, + List steelADataList, + List underGroundLinkDataList, + List steeBDataList, + List groundSideBDataList, + List groundLinkRightDataList, + Runnable callback); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellSetupFragment.java new file mode 100644 index 0000000..4d98d41 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellSetupFragment.java @@ -0,0 +1,421 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +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.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationConstants; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.RegExUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineWellAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 一井定向的父类 + */ +public abstract class AbstractLineStationWellSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineWellAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + + public static final String LINE_NAME = Tools.getString(R.string.one_well_orientation); + + private MenuItem confirmItem; + //选择到的点 + private List groundLinkDataList; + private List groundSideDataList; + private List steelWireDataList; + private List ungroundSideDataList; + private List ungroundLinkDataList; + + private StationCreateLineWellAdapter mAdapter; + + + private final Handler handler = new Handler(); + + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundLinkMinCount()) { + showErrorMsg(Tools.getString(R.string.underground_connection_min_hint)); + return; + } + mAdapter.setGroundLinkPoints(pickPointResult); + } else if (StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideMinCount()) { + showErrorMsg(Tools.getString(R.string.please_select_the_surface_near_well_point)); + return; + } + mAdapter.setGroundSidePoints(pickPointResult); + } else if (StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < steelWireMinCount()) { + showErrorMsg(Tools.getString(R.string.wire_at_least_two_points)); + return; + } + mAdapter.setSteelWirePoints(pickPointResult); + } else if (StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE.equals(type)) { + if (pickPointResult.getSelectedIds().size() < undergroundSideMinCount()) { + showErrorMsg(Tools.getString(R.string.please_select_the_underground_near_well_point)); + return; + } + mAdapter.setUndergroudSidePoints(pickPointResult); + } else if (StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK.equals(type)) { + if (pickPointResult.getSelectedIds().size() < undergroundLinkMinCount()) { + showErrorMsg(Tools.getString(R.string.underground_connection_direction_min_hint)); + return; + } + mAdapter.setUndergroudLinkPoints(pickPointResult); + } + onItemChanged(); + }); + + protected abstract int groundLinkMinCount(); + + protected abstract int groundSideMinCount(); + + protected abstract int steelWireMinCount(); + + protected abstract int undergroundSideMinCount(); + + protected abstract int undergroundLinkMinCount(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + protected List getAdapterDataList() { + List items = null; + if (mAdapter != null) { + items = mAdapter.getItems(); + } + return items; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(stationDetailItemList -> runOnUI(() -> { + mAdapter = new StationCreateLineWellAdapter( + AbstractLineStationWellSetupFragment.this, stationDetailItemList); + + recyclerView.setAdapter(mAdapter); + SwipeDraggableRecyclerViewUtil.setup(mAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationWellSetupFragment.this, + getContext()); + + refreshFiveDataList(); +// refreshAutoCloseView(); + + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); +// initAutoCloseView(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (handler != null) + handler.removeCallbacksAndMessages(null); + } + + + @Override + public void onSelectGroundLink(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK, + groundLinkMinCount() + 1, Tools.getString(R.string.select_the_ground_connection_direction_point), filters, pickPointResult); + } + + protected void goSelectPoint(String type, int maxCount, String title, List filters, PickPointResult pickPointResult) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + type, + maxCount, + title, + filters, + projectId, pickPointResult, activityResultLauncher); + } + + + @Override + public void onSelectGroundSide(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE, + 1, Tools.getString(R.string.select_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectSteelWire(PickPointResult pickPointResult, List filters) { +// goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE, +// steelWireMinCount() + 1, "选择钢丝点", filters, pickPointResult); + PickPointResult lastSteelPickPoint = PickPointResult.create(); + int newName = 1; + List pointsFromType = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE + StationDetailItem._DATA); + if (pointsFromType != null && !pointsFromType.isEmpty()) { + PickPointResult.initPicPointResultData(lastSteelPickPoint, pointsFromType); + //获取新的钢丝的索引 + StationDetailItem stationDetailItem = pointsFromType.get(pointsFromType.size() - 1); + String num = RegExUtil.findNum(stationDetailItem.getName()); + assert num != null; + newName = Integer.parseInt(num) + 1; + } + + if (lastSteelPickPoint.getSelectedIds().size() >= steelWireMinCount() + 1) { + ToastUtils.showShort(R.string.steel_max_hint, (steelWireMinCount() + 1)); + return; + } + + PickPointResult.createPointResultNewData(lastSteelPickPoint, Tools.getString(R.string.wire) + newName); + mAdapter.setSteelWirePoints(lastSteelPickPoint); + + onItemChanged(); + } + + @Override + public void onSelectUndergroundLink(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK, + undergroundLinkMinCount() + 1, Tools.getString(R.string.select_underground_connection_direction_point), filters, pickPointResult); + } + + @Override + public void onSelectUndergroundSide(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE, + 1, Tools.getString(R.string.select_underground_near_well_point), filters, pickPointResult); + } + +// @Override +// public void onSelectOnlyMeasureHorAngle(boolean measureHorAngle) { +// LineRecord currentBatch = getCurrentBatch(); +// SurveyorStationUtil.updateLineRecord(currentBatch); +// SurveyorStationUtil.updateStationPointsMeasureHorAag(currentBatch); +// } + + @Override + public void onItemRemoved(int adapterPosition) { + mAdapter.removeItemForLastSelect(adapterPosition); + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + private void onItemChanged() { + handler.postDelayed(() -> { + refreshFiveDataList(); + //检测数据是否合法 + if (confirmItem != null) { + confirmItem.setEnabled(!(groundLinkDataList.size() < groundLinkMinCount() || + groundSideDataList.size() < groundSideMinCount() || + steelWireDataList.size() < steelWireMinCount() || + ungroundSideDataList.size() < undergroundSideMinCount() || + ungroundLinkDataList.size() < undergroundLinkMinCount() + )); + } +// refreshAutoCloseView(); + }, 80); + } + + private void refreshFiveDataList() { + String _data = StationDetailItem._DATA; + groundLinkDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK + _data); + groundSideDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE + _data); + steelWireDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE + _data); + ungroundSideDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE + _data); + ungroundLinkDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK + _data); + } + +// private void refreshAutoCloseView() { +// if (isCanSetAutoCloseCheck()) { +// setAutoCloseCheckEnable(true, true); +// } else { +// setAutoCloseCheckEnable(false, false); +// } +// } + + private boolean isCanSetAutoCloseCheck() { + if (groundLinkDataList == null || steelWireDataList == null || ungroundLinkDataList == null) { + return false; + } + int groundLinkSize = groundLinkDataList.size(); + int steelWireSize = steelWireDataList.size(); + int ungroundLinkSize = ungroundLinkDataList.size(); + return groundLinkSize + steelWireSize >= SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION + || ungroundLinkSize + steelWireSize >= SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION; + } + + + protected void showErrorMsgForWell(String type) { + switch (type) { + case StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK: + showErrorMsg(Tools.getString(R.string.underground_connection_min_hint)); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE: + showErrorMsg(Tools.getString(R.string.please_select_the_surface_near_well_point)); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE: + showErrorMsg(Tools.getString(R.string.wire_at_least_two_points)); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE: + showErrorMsg(Tools.getString(R.string.please_select_the_underground_near_well_point)); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK: + showErrorMsg(Tools.getString(R.string.underground_connection_direction_min_hint)); + break; + default: + break; + } + } + + private void showErrorMsg(String msg) { + ToastUtils.showShort(msg); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + // TODO: 2022/6/15 + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } +// //设置导线的弹框 +// requestLineName(string -> { +// //建站 +// }); + + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + setup(projectId, periodId, LINE_NAME, groundLinkDataList, groundSideDataList, steelWireDataList, ungroundLinkDataList, ungroundSideDataList, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + // TODO: 2022/6/15 +// List knownItems1 = mAdapter.getGroundLinkPoints(); +// List unknownItems = mAdapter.unknownItems(); +// List knownItems2 = mAdapter.knownItems2(); +// if (isListEmpty(knownItems1) || +// isListEmpty(unknownItems) || +// isListEmpty(knownItems2)) { +// return warningDataLosing(this); +// } + return false; + } + + protected abstract void setup(String projectId, String cycleId, + String lineName, + List groundLinkDataList, + List groundSideDataList, + List steelWireDataList, + List ungroundLinkDataList, + List ungroundSideDataList, + Runnable callback); + + +// private SwitchCompat getAutoCloseView() { +// if (getView() != null) { +// return getView().findViewById(R.id.auto_close_switch); +// } +// return null; +// } +// +// private void setAutoCloseCheckEnable(boolean isCheck, boolean isEnable) { +// SwitchCompat autoCloseView = getAutoCloseView(); +// if (autoCloseView != null) { +// autoCloseView.setChecked(isCheck); +// autoCloseView.setEnabled(isEnable); +// } +// } +// +// /** +// * 默认是自动闭合的 +// * +// * @return +// */ +// protected boolean isAutoClose() { +// SwitchCompat autoCloseView = getAutoCloseView(); +// if (autoCloseView != null) { +// return autoCloseView.isChecked(); +// } +// return true; +// } +// +// private void initAutoCloseView() { +// SwitchCompat autoCloseView = getAutoCloseView(); +// if (autoCloseView != null) { +// autoCloseView.setOnCheckedChangeListener((buttonView, isChecked) -> { +// if (isCanSetAutoCloseCheck()) { +// setAutoCloseCheckEnable(isChecked, true); +// } +// }); +// } +// } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/attached/LineStationAttachedSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/attached/LineStationAttachedSetupFragment.java new file mode 100644 index 0000000..53521bb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/attached/LineStationAttachedSetupFragment.java @@ -0,0 +1,280 @@ +package com.bingce.controlnetwork.fragment.station.line.attached; + +import android.content.Context; +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +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.model.BundleConstants; +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.fragment.station.line.AbstractLineStationKnownUnknownKnownSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 新建附合导线 + */ +public class LineStationAttachedSetupFragment extends AbstractLineStationKnownUnknownKnownSetupFragment { + + @Override + protected int knownItemMinCount() { + return 2; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + if (batchId == null || batchId.isEmpty()) { + callback.onGet(Arrays.asList( + new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1, + null), + new StationDetailItem( + getString(R.string.select_1_unknown_point), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null), + new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2, + null))); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected int selectKnownPointTitle() { + return R.string.select_2_known_point; + } + + @Override + protected int knownPointCountError() { + return R.string.tips_known_point_must_more_than_2; + } + + @Override + protected boolean initLeftRightMeasure() { + return true; + } + + @Override + protected String defaultLineName() { + return getString(R.string.wire_fuhe); + } + + @Override + protected void setup(String projectId, String periodId, + String lineName, + List knownItems1, + List unknownItems, + List knownItems2, + Runnable runnable) { + //判断数据是否准确 + if (knownItems1.size() != knownItemMinCount()) { + ToastUtils.showShort(knownPointCountError()); + return; + } + if (unknownItems.isEmpty()) { + ToastUtils.showShort(R.string.tips_unknown_point_must_not_empty); + return; + } + if (knownItems2.size() != knownItemMinCount()) { + ToastUtils.showShort(knownPointCountError()); + return; + } + //切换线程 + ThreadPoolUtil.execute(() -> { + + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, + unknownItems, knownItems1, knownItems2); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(knownItems1, projectId); + PointUtil.globalToProjectControlPoint(unknownItems, projectId); + PointUtil.globalToProjectControlPoint(knownItems2, projectId); + + + //1.创建并存储batch + List records = new ArrayList<>(); + records.add(new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1, + null)); + records.addAll(knownItems1); + records.add(new StationDetailItem( + getString(R.string.select_1_unknown_point), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null)); + records.addAll(unknownItems); + records.add(new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2, + null)); + records.addAll(knownItems2); + LineRecord batchRecord = LineRecord.attach(lineName, projectId, periodId, records); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + + //2.创建测站列表 + StationDetailItem item1 = knownItems1.get(0); + StationDetailItem item2 = knownItems1.get(1); + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + //添加konwn point2 + for (int index = 0; index < knownItems2.size(); index++) { + StationDetailItem item3 = knownItems2.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + + //3.存储新建的测站列表 + stationDataSource.save(stationRecordList); + + if (runnable != null) { + runnable.run(); + } + }); + } + + private static String checkValidate(String projectId, String cycleId, + List unknownItems, + List knownItems1, + List knownItems2) { + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance + .getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + StationDetailItem tmp = knownItems1.get(1); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + //添加konwn point2 + for (int index = 0; index < knownItems2.size(); index++) { + StationDetailItem item3 = knownItems2.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + public static final int titleCreate = R.string.title_create_attach_line_station; + public static final int titleEdit = R.string.title_edit_attach_line_station; + public static final String TAG = LineStationAttachedSetupFragment.class.getName(); + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationAttachedSetupFragment newInstance(Bundle bundle) { + LineStationAttachedSetupFragment fragment = new LineStationAttachedSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } +} 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 new file mode 100644 index 0000000..1e5d2f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/close/LineStationCloseSetupFragment.java @@ -0,0 +1,326 @@ +package com.bingce.controlnetwork.fragment.station.line.close; + +import android.content.Context; +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +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.model.BundleConstants; +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.fragment.station.line.single.LineStationSingleSetupFragment; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 新建闭合导线 + */ +public class LineStationCloseSetupFragment extends LineStationSingleSetupFragment { + + @Override + protected int layoutRes() { + return R.layout.fragment_close_line_surveyor_station_setup_layout; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + View leftRightSwitch = view.findViewById(R.id.left_right_switch); + if (leftRightSwitch != null) { + leftRightSwitch.setVisibility(View.GONE); + } + } + + @Override + protected int unknownItemMinCount() { + return 2; + } + + @Override + protected int unknownGroupTitle() { + return R.string.select_2_unknown_point; + } + + @Override + protected int unknownPointCountError() { + return R.string.tips_unknown_point_must_more_than_2; + } + + @Override + protected String defaultLineName() { + return getString(R.string.wire_bihe); + } + + @Override + protected void setup(String projectId, String periodId, + String lineName, + List knownItems, + List unknownItems, + Runnable runnable) { + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + ThreadPoolUtil.execute(() -> { + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + //验证重复测站 + String name = checkValidate(projectId, periodId, + startPointSetupOnce(), knownItems, unknownItems); + if (name != null && !name.isEmpty()) { + tipsError(name); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(knownItems, projectId); + PointUtil.globalToProjectControlPoint(unknownItems, projectId); + + //1.创建并存储batch + List records = new ArrayList<>(); + records.add(new StationDetailItem( + getString(knownGroupTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP, + null)); + records.addAll(knownItems); + records.add(new StationDetailItem( + getString(unknownGroupTitle()), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null)); + records.addAll(unknownItems); + LineRecord lineRecord = LineRecord.close(lineName, projectId, periodId, records); + stationBatchDataSource.save(lineRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + //2.创建测站列表 + if (startPointSetupOnce()) { + List stationRecordList = setup2( + projectId, periodId, lineRecord.id, showSlopDistance, needLeftRightSurveyor(), knownItems, unknownItems); + //3.存储 + stationDataSource.save(stationRecordList); + } else { + List stationRecordList = setup1( + projectId, periodId, lineRecord.id, showSlopDistance, needLeftRightSurveyor(), knownItems, unknownItems); + //3.存储 + stationDataSource.save(stationRecordList); + } + + if (runnable != null) { + runnable.run(); + } + }); + } + + protected static String checkValidate(String projectId, String cycleId, + boolean startPointSetupOnce, + List unknownItems, + List knownItems) { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + //检测该测期下是否有同名测站 + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + if (startPointSetupOnce) { + StationDetailItem tmp2 = knownItems.get(1); + StationDetailItem tmp3 = unknownItems.get(0); + //起算点有3个测点 + expectedStationIds.add(tmp2.getOriginalPointId()); + tmp2 = tmp3; + for (int index = 1; index < unknownItems.size(); index++) { + tmp3 = unknownItems.get(index); + expectedStationIds.add(tmp2.getOriginalPointId()); + tmp2 = tmp3; + } + //创建最后一个闭合站 + expectedStationIds.add(tmp2.getOriginalPointId()); + } else { + StationDetailItem tmp = knownItems.get(1); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + //--闭合导线添加最后一个闭环 + StationDetailItem item3 = knownItems.get(1); + expectedStationIds.add(tmp.getOriginalPointId()); + //--最后以known2做站点再加一站 + tmp = item3; + expectedStationIds.add(tmp.getOriginalPointId()); + } + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + protected boolean startPointSetupOnce() { + return switchIsChecked(getView(), R.id.start_point_setup_once); + } + + private static final int titleCreate = R.string.title_create_close_line_station; + private static final int titleEdit = R.string.title_edit_close_line_station; + public static final String TAG = LineStationCloseSetupFragment.class.getName(); + + public static void startCreateCloseLine(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationCloseSetupFragment newInstance(Bundle bundle) { + LineStationCloseSetupFragment fragment = new LineStationCloseSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } + + private static List setup1(String projectId, String cycleId, String lineId, + boolean showSlopDistance, boolean needLeftRightSurveyor, + List knownItems, List unknownItems) { + StationDetailItem item1 = knownItems.get(0); + StationDetailItem item2 = knownItems.get(1); + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + //--闭合导线添加最后一个闭环 + StationDetailItem item3 = knownItems.get(1); + SurveyorStationRecord record1 = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record1.setLeftAndRightSurveyor(needLeftRightSurveyor); + record1.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record1); + + //--最后以known2做站点再加一站 + item1 = item2; + item2 = item3; + item3 = knownItems.get(0); + SurveyorStationRecord record2 = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record2.setLeftAndRightSurveyor(needLeftRightSurveyor); + record2.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record2); + + return stationRecordList; + } + + private static List setup2(String projectId, String cycleId, String lineId, + boolean showSlopDistance, boolean needLeftRightSurveyor, + List knownItems, List unknownItems) { + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + + StationDetailItem item1 = knownItems.get(0); + StationDetailItem item2 = knownItems.get(1); + StationDetailItem item3 = unknownItems.get(0); + StationDetailItem item4 = unknownItems.get(unknownItems.size() - 1); + //起算点有3个测点 + SurveyorStationRecord startStation = + SurveyorStationRecord.closeLineStartPointStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3, item4); + startStation.setLeftAndRightSurveyor(false); + startStation.setShowSlopDistance(showSlopDistance); + stationRecordList.add(startStation); + + item1 = item2; + item2 = item3; + + for (int index = 1; index < unknownItems.size(); index++) { + item3 = unknownItems.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + + //创建最后一个闭合站 + item3 = knownItems.get(1); + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + return stationRecordList; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/random/LineStationRandomSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/random/LineStationRandomSetupFragment.java new file mode 100644 index 0000000..0d10ef1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/random/LineStationRandomSetupFragment.java @@ -0,0 +1,272 @@ +package com.bingce.controlnetwork.fragment.station.line.random; + +import android.content.Context; +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +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.model.BundleConstants; +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.fragment.station.line.AbstractLineStationKnownUnknownKnownSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 新建无定向导线 + */ +public class LineStationRandomSetupFragment extends AbstractLineStationKnownUnknownKnownSetupFragment { + + @Override + protected int knownItemMinCount() { + return 1; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + if (batchId == null || batchId.isEmpty()) { + callback.onGet(Arrays.asList( + new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1, + null), + new StationDetailItem( + getString(R.string.select_1_unknown_point), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null), + new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2, + null))); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected int selectKnownPointTitle() { + return R.string.select_1_known_point; + } + + @Override + protected int knownPointCountError() { + return R.string.tips_known_point_must_more_than_1; + } + + @Override + protected boolean initLeftRightMeasure() { + return true; + } + + @Override + protected String defaultLineName() { + return getString(R.string.wire_wudingxxiang); + } + + @Override + protected void setup(String projectId, String periodId, + String lineName, + List knownItems1, + List unknownItems, + List knownItems2, + Runnable runnable) { + //检测条件是否合法 + if (knownItems1.size() != knownItemMinCount()) { + ToastUtils.showShort(knownPointCountError()); + return; + } + if (unknownItems.isEmpty()) { + ToastUtils.showShort(R.string.tips_unknown_point_must_not_empty); + return; + } + if (knownItems2.size() != knownItemMinCount()) { + ToastUtils.showShort(knownPointCountError()); + return; + } + ThreadPoolUtil.execute(() -> { + + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, unknownItems, knownItems2); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(knownItems1, projectId); + PointUtil.globalToProjectControlPoint(unknownItems, projectId); + PointUtil.globalToProjectControlPoint(knownItems2, projectId); + + //1.创建并存储batch + List records = new ArrayList<>(); + records.add(new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1, + null)); + records.addAll(knownItems1); + records.add(new StationDetailItem( + getString(R.string.select_1_unknown_point), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null)); + records.addAll(unknownItems); + records.add(new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2, + null)); + records.addAll(knownItems2); + LineRecord batchRecord = LineRecord.random(lineName, projectId, periodId, records); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + //2.创建测站列表 + StationDetailItem item1 = knownItems1.get(0); + StationDetailItem item2 = unknownItems.get(0); + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + for (int index = 1; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + //添加konwn point2 + for (int index = 0; index < knownItems2.size(); index++) { + StationDetailItem item3 = knownItems2.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + + stationDataSource.save(stationRecordList); + + if (runnable != null) { + runnable.run(); + } + }); + } + + private static String checkValidate(String projectId, String cycleId, + List unknownItems, + List knownItems2) { + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + + StationDetailItem tmp = unknownItems.get(0); + for (int index = 1; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + //添加konwn point2 + for (int index = 0; index < knownItems2.size(); index++) { + StationDetailItem item3 = knownItems2.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + public static final int titleCreate = R.string.title_create_random_line_station; + public static final int titleEdit = R.string.title_edit_random_line_station; + public static final String TAG = LineStationRandomSetupFragment.class.getName(); + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationRandomSetupFragment newInstance(Bundle bundle) { + LineStationRandomSetupFragment fragment = new LineStationRandomSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/single/LineStationSingleSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/single/LineStationSingleSetupFragment.java new file mode 100644 index 0000000..9d55c3f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/single/LineStationSingleSetupFragment.java @@ -0,0 +1,240 @@ +package com.bingce.controlnetwork.fragment.station.line.single; + +import android.content.Context; +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +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.model.BundleConstants; +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.fragment.station.line.AbstractLineStationKnownUnknownSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * 新建支导线 + */ +public class LineStationSingleSetupFragment extends AbstractLineStationKnownUnknownSetupFragment { + + @Override + protected int knownItemMinCount() { + return 2; + } + + @Override + protected int knownGroupTitle() { + return R.string.select_2_known_point; + } + + @Override + protected int knownPointCountError() { + return R.string.tips_known_point_must_more_than_2; + } + + @Override + protected int unknownItemMinCount() { + return 1; + } + + @Override + protected int unknownGroupTitle() { + return R.string.select_1_unknown_point; + } + + @Override + protected int unknownPointCountError() { + return R.string.tips_unknown_point_must_not_empty; + } + + @Override + protected boolean initLeftRightMeasure() { + return true; + } + + @Override + protected String defaultLineName() { + return getString(R.string.wire_zhi); + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + if (batchId == null || batchId.isEmpty()) { + callback.onGet(Arrays.asList( + new StationDetailItem( + getString(knownGroupTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP, + null), + new StationDetailItem( + getString(unknownGroupTitle()), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null))); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected void setup(String projectId, String periodId, + String lineName, + List knownItems, + List unknownItems, + Runnable runnable) { + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + ThreadPoolUtil.execute(() -> { + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, knownItems, unknownItems); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(knownItems, projectId); + PointUtil.globalToProjectControlPoint(unknownItems, projectId); + + //1.创建并存储batch + List records = new ArrayList<>(); + records.add(new StationDetailItem( + getString(knownGroupTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP, + null)); + records.addAll(knownItems); + records.add(new StationDetailItem( + getString(unknownGroupTitle()), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null)); + records.addAll(unknownItems); + LineRecord batchRecord = LineRecord.single(lineName, projectId, periodId, records); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + //2.创建测站列表 + StationDetailItem item1 = knownItems.get(0); + StationDetailItem item2 = knownItems.get(1); + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + + stationDataSource.save(stationRecordList); + + if (runnable != null) { + runnable.run(); + } + }); + } + + private static String checkValidate(String projectId, String cycleId, + List knownItems, + List unknownItems) { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + //检测该测期下是否有同名测站 + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + StationDetailItem tmp = knownItems.get(1); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { +// return false; + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + public static final int titleCreate = R.string.title_create_sinle_line_station; + public static final int titleEdit = R.string.title_edit_sinle_line_station; + + public static final String TAG = LineStationSingleSetupFragment.class.getName(); + + public static void startCreate(Context context, String projectId, String period) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, period); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationSingleSetupFragment newInstance(Bundle bundle) { + LineStationSingleSetupFragment fragment = new LineStationSingleSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleGroundSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleGroundSetupFragment.java new file mode 100644 index 0000000..7abcc1a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleGroundSetupFragment.java @@ -0,0 +1,342 @@ +package com.bingce.controlnetwork.fragment.station.line.well; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.AbstractLineStationWellDoubleGroundSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * 新建二井定向-地上 + */ +public class LineStationWellDoubleGroundSetupFragment extends AbstractLineStationWellDoubleGroundSetupFragment { + + public static final int titleCreate = R.string.title_create_well_line_station_double_ground; + public static final int titleEdit = R.string.title_edit_well_line_station_double_ground; + public static final String TAG = LineStationWellDoubleGroundSetupFragment.class.getName(); + //区分是初始页面还是编辑页面 + private boolean isDefaultPage; + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationWellDoubleGroundSetupFragment newInstance(Bundle bundle) { + LineStationWellDoubleGroundSetupFragment fragment = new LineStationWellDoubleGroundSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } + + @Override + protected boolean initLeftRightMeasure() { + return false; + } + + @Override + protected int groundLinkLeftMinCount() { + return 1; + } + + @Override + protected int groundSideAMinCount() { + return 1; + } + + @Override + protected int groundLinkMiddleMinCount() { + return 0; + } + + @Override + protected int groundSideBMinCount() { + return 1; + } + + @Override + protected int groundLinkRightMinCount() { + return 1; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + isDefaultPage = TextUtils.isEmpty(batchId); + if (isDefaultPage) { + callback.onGet(Arrays.asList( + new StationDetailItem( + Tools.getString(R.string.well_a_surface_connection_direction_limit), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + null), + new StationDetailItem( + Tools.getString(R.string.well_a_surface_near_well_point), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + null), + new StationDetailItem( + Tools.getString(R.string.ground_connection_point_optional), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE, + null), + new StationDetailItem( + Tools.getString(R.string.well_b_surface_near_well_point), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + null), + new StationDetailItem( + Tools.getString(R.string.well_b_surface_connection_direction_limit), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + null) + )); + } else { + loadBatchRecord(batchId, callback); + } + } + + + @Override + protected String defaultLineName() { + return getString(R.string.station_type_well_wire_double); + } + + @Override + protected void setup(String projectId, String periodId, String lineName, + List groundLinkLeftDataList, List groundLinkMiddleDataList, + List groundLinkRightDataList, List groundSideBDataList, + List groundSideADataList, Runnable callback) { + //判断数据是否准确 + if (groundLinkLeftDataList.size() < groundLinkLeftMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT); + return; + } + if (groundLinkMiddleDataList.size() < groundLinkMiddleMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE); + return; + } + if (groundLinkRightDataList.size() < groundLinkRightMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT); + return; + } + if (groundSideBDataList.size() < groundSideBMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B); + return; + } + if (groundSideADataList.size() < groundSideAMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A); + return; + } + //切换线程 + ThreadPoolUtil.execute(() -> { + + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, + groundLinkMiddleDataList, groundSideADataList, groundSideBDataList); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(groundLinkLeftDataList, projectId); + PointUtil.globalToProjectControlPoint(groundLinkMiddleDataList, projectId); + PointUtil.globalToProjectControlPoint(groundLinkRightDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideBDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideADataList, projectId); + + //1.创建并存储batch + List lineRecordPointList = getAdapterDataList(); + LineRecord batchRecord = LineRecord.well(LineRecord.TYPE_WELL_DOUBLE_GROUND, lineName, projectId, periodId, lineRecordPointList); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + + //2.创建测站列表 + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + + for (StationDetailItem itemSideA : groundSideADataList) { + List pointList = new ArrayList<>(); + pointList.add(itemSideA); + pointList.addAll(groundLinkLeftDataList); + if (groundLinkMiddleDataList != null && !groundLinkMiddleDataList.isEmpty()) { + pointList.add(groundLinkMiddleDataList.get(0)); + } else { + pointList.add(groundSideBDataList.get(0)); + } + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + if (groundLinkMiddleDataList != null && !groundLinkMiddleDataList.isEmpty()) { + for (int i = 0; i < groundLinkMiddleDataList.size(); i++) { + List pointList = new ArrayList<>(); + pointList.add(groundLinkMiddleDataList.get(i)); + + if (i - 1 < 0) { + //第一个节点 + pointList.add(groundSideADataList.get(0)); + } else { + pointList.add(groundLinkMiddleDataList.get(i - 1)); + } + + if (i + 1 > groundLinkMiddleDataList.size() - 1) { + pointList.add(groundSideBDataList.get(0)); + } else { + pointList.add(groundLinkMiddleDataList.get(i + 1)); + } + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); +// 设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + } + + for (StationDetailItem itemSideB : groundSideBDataList) { + List pointList = new ArrayList<>(); + pointList.add(itemSideB); + if (groundLinkMiddleDataList != null && !groundLinkMiddleDataList.isEmpty()) { + pointList.add(groundLinkMiddleDataList.get(groundLinkMiddleDataList.size() - 1)); + } else { + pointList.add(groundSideADataList.get(0)); + } + pointList.addAll(groundLinkRightDataList); + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + //3.存储新建的测站列表 + stationDataSource.save(stationRecordList); + + if (callback != null) { + callback.run(); + } + }); + } + + private String checkValidate(String projectId, String cycleId, + List groundLinkMiddleDataList, + List groundSideADataList, List groundSideBDataList) { + //如果是编辑页面就不检查 + if (!isDefaultPage) return null; + + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + collectIdsFromList(expectedStationIds, groundLinkMiddleDataList); + collectIdsFromList(expectedStationIds, groundSideADataList); + collectIdsFromList(expectedStationIds, groundSideBDataList); + + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + private void collectIdsFromList(List collectIdList, List tagetList) { + for (StationDetailItem stationDetailItem : tagetList) { + String pointId = stationDetailItem.getOriginalPointId(); + if (!TextUtils.isEmpty(pointId)) { + collectIdList.add(pointId); + } + } + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleUnderGroundSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleUnderGroundSetupFragment.java new file mode 100644 index 0000000..3aba334 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleUnderGroundSetupFragment.java @@ -0,0 +1,382 @@ +package com.bingce.controlnetwork.fragment.station.line.well; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecordOperate; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.AbstractLineStationWellDoubleUnderGroundSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * 新建二井定向-地下 + */ +public class LineStationWellDoubleUnderGroundSetupFragment extends AbstractLineStationWellDoubleUnderGroundSetupFragment { + + public static final int titleCreate = R.string.title_create_well_line_station_double_under_ground; + public static final int titleEdit = R.string.title_edit_well_line_station_double_under_ground; + public static final String TAG = LineStationWellDoubleUnderGroundSetupFragment.class.getName(); + //区分是初始页面还是编辑页面 + private boolean isDefaultPage; + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationWellDoubleUnderGroundSetupFragment newInstance(Bundle bundle) { + LineStationWellDoubleUnderGroundSetupFragment fragment = new LineStationWellDoubleUnderGroundSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } + + @Override + protected boolean initLeftRightMeasure() { + return false; + } + + @Override + protected int groundLinkLeftMinCount() { + return 1; + } + + @Override + protected int groundSideAMinCount() { + return 1; + } + + @Override + protected int steelAMinCount() { + return 1; + } + + @Override + protected int underGroundLinkMinCount() { + return 2; + } + + @Override + protected int steelBMinCount() { + return 1; + } + + @Override + protected int groundSideBMinCount() { + return 1; + } + + @Override + protected int groundLinkRightMinCount() { + return 1; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + isDefaultPage = TextUtils.isEmpty(batchId); + if (isDefaultPage) { + callback.onGet(Arrays.asList( + new StationDetailItem( + Tools.getString(R.string.well_a_surface_connection_direction_limit), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + null), + new StationDetailItem( + Tools.getString(R.string.well_a_surface_near_well_point), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + null), + new StationDetailItem( + Tools.getString(R.string.a_well_wire), + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A, + null), + new StationDetailItem( + Tools.getString(R.string.underground_connection_points_min_hint), + StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK, + null), + new StationDetailItem( + Tools.getString(R.string.b_well_wire), + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B, + null), + new StationDetailItem( + Tools.getString(R.string.well_b_surface_near_well_point), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + null), + new StationDetailItem( + Tools.getString(R.string.well_b_surface_connection_direction_limit), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + null) + )); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected void setup(String projectId, String periodId, String lineName, + List groundLinkLeftDataList, List groundSideADataList, + List steelADataList, List underGroundLinkDataList, + List steelBDataList, List groundSideBDataList, + List groundLinkRightDataList, + Runnable callback) { + //判断数据是否准确 + if (groundLinkLeftDataList.size() < groundLinkLeftMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT); + return; + } + if (groundSideADataList.size() < groundSideAMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A); + return; + } + if (steelADataList.size() < steelAMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A); + return; + } + if (underGroundLinkDataList.size() < underGroundLinkMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK); + return; + } + if (steelBDataList.size() < steelBMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B); + return; + } + if (groundSideBDataList.size() < groundSideBMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B); + return; + } + if (groundLinkRightDataList.size() < groundLinkRightMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT); + return; + } + + //存储钢丝点到数据库 + List stationDetailItemList = new ArrayList<>(); + stationDetailItemList.addAll(steelADataList); + stationDetailItemList.addAll(steelBDataList); + //save里有切换到子线程 + PointRecordOperate.saveStationDetailItemListToPointRecord(stationDetailItemList, projectId()); + + //切换线程 + ThreadPoolUtil.execute(() -> { + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, + groundSideADataList, + underGroundLinkDataList, + groundSideBDataList); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(groundLinkLeftDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideADataList, projectId); +// ProjectPointUtil.dealGlobalControlPoints2(steelADataList, projectId); + PointUtil.globalToProjectControlPoint(underGroundLinkDataList, projectId); +// ProjectPointUtil.dealGlobalControlPoints2(steelBDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideBDataList, projectId); + PointUtil.globalToProjectControlPoint(groundLinkRightDataList, projectId); + //1.创建并存储batch + List lineRecordPointList = getAdapterDataList(); + LineRecord batchRecord = LineRecord.well(LineRecord.TYPE_WELL_DOUBLE_UNDERGROUND, lineName, projectId, periodId, lineRecordPointList); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + + //2.创建测站列表 + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + + //A井地面近井点 + for (StationDetailItem itemSideA : groundSideADataList) { + List pointList = new ArrayList<>(); + pointList.add(itemSideA); + pointList.addAll(groundLinkLeftDataList); + pointList.addAll(steelADataList); + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); +// //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + //地下连接点至少两个 + if (underGroundLinkDataList != null && !underGroundLinkDataList.isEmpty()) { + for (int i = 0; i < underGroundLinkDataList.size(); i++) { + List pointList = new ArrayList<>(); + pointList.add(underGroundLinkDataList.get(i)); + + if (i - 1 < 0) { + //第一个节点 + pointList.addAll(steelADataList); + } else { + pointList.add(underGroundLinkDataList.get(i - 1)); + } + + if (i + 1 > underGroundLinkDataList.size() - 1) { + pointList.addAll(steelBDataList); + } else { + pointList.add(underGroundLinkDataList.get(i + 1)); + } + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); + + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + } + + //B井地面近井点 + for (StationDetailItem itemSideB : groundSideBDataList) { + List pointList = new ArrayList<>(); + pointList.add(itemSideB); + pointList.addAll(steelBDataList); + pointList.addAll(groundLinkRightDataList); + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + + //3.存储新建的测站列表 + stationDataSource.save(stationRecordList); + + if (callback != null) { + callback.run(); + } + }); + + } + + + @Override + protected String defaultLineName() { + return getString(R.string.station_type_well_wire_double); + } + + + private String checkValidate(String projectId, String cycleId, + List groundSideADataList, + List underGroundLinkDataList, + List groundSideBDataList) { + + //如果是编辑页面就不检查 + if (!isDefaultPage) return null; + + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + collectIdsFromList(expectedStationIds, groundSideADataList); + collectIdsFromList(expectedStationIds, underGroundLinkDataList); + collectIdsFromList(expectedStationIds, groundSideBDataList); + + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + private void collectIdsFromList(List collectIdList, List tagetList) { + for (StationDetailItem stationDetailItem : tagetList) { + String pointId = stationDetailItem.getOriginalPointId(); + if (!TextUtils.isEmpty(pointId)) { + collectIdList.add(pointId); + } + } + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellSetupFragment.java new file mode 100644 index 0000000..ff2de9c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellSetupFragment.java @@ -0,0 +1,312 @@ +package com.bingce.controlnetwork.fragment.station.line.well; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecordOperate; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.AbstractLineStationWellSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + + +/** + * 新建一井定向 + */ +public class LineStationWellSetupFragment extends AbstractLineStationWellSetupFragment { + + public static final int titleCreate = R.string.title_create_well_line_station; + public static final int titleEdit = R.string.title_edit_well_line_station; + public static final String TAG = LineStationWellSetupFragment.class.getName(); + //区分是初始页面还是编辑页面 + private boolean isDefaultPage; + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationWellSetupFragment newInstance(Bundle bundle) { + LineStationWellSetupFragment fragment = new LineStationWellSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } + + @Override + protected boolean initLeftRightMeasure() { + return false; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + isDefaultPage = TextUtils.isEmpty(batchId); + if (isDefaultPage) { + callback.onGet(Arrays.asList( + new StationDetailItem( + Tools.getString(R.string.ground_connection_direction_one_or_two), + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK, + null), + new StationDetailItem( + Tools.getString(R.string.surface_near_well_point), + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE, + null), + new StationDetailItem( + Tools.getString(R.string.steel_wire_two_or_three), + StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE, + null), + new StationDetailItem( + Tools.getString(R.string.underground_near_well_point), + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE, + null), + new StationDetailItem( + Tools.getString(R.string.underground_connection_direction_one_or_two), + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK, + null) + )); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected int groundLinkMinCount() { + return 1; + } + + @Override + protected int groundSideMinCount() { + return 1; + } + + @Override + protected int steelWireMinCount() { + return 2; + } + + @Override + protected int undergroundSideMinCount() { + return 1; + } + + @Override + protected int undergroundLinkMinCount() { + return 1; + } + + @Override + protected String defaultLineName() { + return getString(R.string.station_type_well_wire); + } + + @Override + protected void setup(String projectId, String cycleId, String lineName, + List groundLinkDataList, List groundSideDataList, + List steelWireDataList, List ungroundLinkDataList, + List ungroundSideDataList, Runnable callback) { + //判断数据是否准确 + if (groundLinkDataList.size() < groundLinkMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK); + return; + } + if (groundSideDataList.size() < groundSideMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE); + return; + } + if (steelWireDataList.size() < steelWireMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE); + return; + } + if (ungroundLinkDataList.size() < undergroundLinkMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK); + return; + } + if (ungroundSideDataList.size() < undergroundSideMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE); + return; + } + + //存储钢丝点到数据库 + List stationDetailItemList = new ArrayList<>(); + stationDetailItemList.addAll(steelWireDataList); + //save里有切换到子线程 + PointRecordOperate.saveStationDetailItemListToPointRecord(stationDetailItemList, projectId()); + + //切换线程 + ThreadPoolUtil.execute(() -> { + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, cycleId, + groundSideDataList, ungroundSideDataList); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(groundLinkDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideDataList, projectId); + PointUtil.globalToProjectControlPoint(steelWireDataList, projectId); + PointUtil.globalToProjectControlPoint(ungroundLinkDataList, projectId); + PointUtil.globalToProjectControlPoint(ungroundSideDataList, projectId); + //1.创建并存储batch + List lineRecordPointList = getAdapterDataList(); + LineRecord batchRecord = LineRecord.well(LineRecord.TYPE_WELL, lineName, projectId, cycleId, lineRecordPointList); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + + //2.创建测站列表 + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + + for (StationDetailItem groundStationDetailItem : groundSideDataList) { + List pointList = new ArrayList<>(); + pointList.add(groundStationDetailItem); + //添加地上观测点 + pointList.addAll(groundLinkDataList); + //添加钢丝点 + pointList.addAll(steelWireDataList); + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, cycleId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + for (StationDetailItem ungroundStationDetailItem : ungroundSideDataList) { + List pointList = new ArrayList<>(); + pointList.add(ungroundStationDetailItem); + //添加地下观测点 + pointList.addAll(ungroundLinkDataList); + //添加钢丝点 + pointList.addAll(steelWireDataList); + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, cycleId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + + //3.存储新建的测站列表 + stationDataSource.save(stationRecordList); + + if (callback != null) { + callback.run(); + } + }); + } + + private String checkValidate(String projectId, String cycleId, + List groundSideDataList, + List ungroundSideDataList) { + //如果是编辑页面就不检查 + if (!isDefaultPage) return null; + + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + collectIdsFromList(expectedStationIds, groundSideDataList); + collectIdsFromList(expectedStationIds, ungroundSideDataList); + + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + private void collectIdsFromList(List collectIdList, List tagetList) { + for (StationDetailItem stationDetailItem : tagetList) { + String pointId = stationDetailItem.getOriginalPointId(); + if (!TextUtils.isEmpty(pointId)) { + collectIdList.add(pointId); + } + } + } + + +} 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 new file mode 100644 index 0000000..8c27a9d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/SingleStationDetailAndEditFragment.java @@ -0,0 +1,141 @@ +package com.bingce.controlnetwork.fragment.stationdetail; + +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.station.defaultstation.SingleStationDetailAndEditContentFragment; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + + +/** + * 测站编辑--包含编辑测点、站点功能,可能是「多测回测角」,也可能是「导线测站」中某站 + */ +public class SingleStationDetailAndEditFragment extends BaseFragment { + public static final int title = R.string.title_surveyor_station_edit; + public static final String TAG = SingleStationDetailAndEditFragment.class.getName(); + + private StationDetailViewModel stationDetailViewModel; + private String lineType; + private SwitchWithText leftRightSwitch; + private SingleStationDetailAndEditContentFragment contentFragment; + + @Override + public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_surveyor_station_detail_or_edit_layout, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getArguments() == null) { + return; + } + //创建显示点列表的fragment + String stationId = getArguments().getString(BundleConstants.KEY_SURVEYOR_STATION_ID); + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + lineType = getArguments().getString(BundleConstants.KEY_LINE_TYPE); + + leftRightSwitch = view.findViewById(R.id.left_right_switch); + leftRightSwitch.setEnabled(true); + + stationDetailViewModel = new ViewModelProvider(requireActivity()).get(StationDetailViewModel.class); + stationDetailViewModel.getRefreshUiLiveData().observe(getViewLifecycleOwner(), refresh -> { + if (contentFragment != null) { + int surveyorPointSize = contentFragment.getSurveyorPointSize(); + + boolean leftAndRightSurveyor = stationDetailViewModel.isLeftAndRightSurveyor(); + if (surveyorPointSize == 2) { + leftRightSwitch.setVisibility(View.VISIBLE); + leftRightSwitch.setChecked(leftAndRightSurveyor); + updateStationLeftRightSurveyor(leftAndRightSurveyor, stationId); + } else { + leftRightSwitch.setVisibility(View.GONE); + updateStationLeftRightSurveyor(false, stationId); + } + + updateStationAutoClose(surveyorPointSize > 3, stationId); + + } + + }); + + contentFragment = SingleStationDetailAndEditContentFragment.newInstance(stationId, projectId); + //添加fragment + getChildFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, + contentFragment, + SingleStationDetailAndEditContentFragment.TAG) + .commit(); + + leftRightSwitch.setOnCheckChangeListener(checked -> { + stationDetailViewModel.setLeftOrRight(checked); + updateStationLeftRightSurveyor(checked, stationId); + }); + } + + private void updateStationAutoClose(boolean autoClose, String stationId) { + ThreadPoolUtil.execute(() -> { + ISurveyorStationDataSource surveyorStationDataSource = + SurveyorDatabaseFactory + .instance + .getSurveyorStation(); + SurveyorStationRecord surveyorStationRecord = + surveyorStationDataSource.getRecordSync(stationId); + //修改 + surveyorStationRecord.setAutoClose(autoClose); + //存储 + surveyorStationDataSource.save(surveyorStationRecord); + }); + } + + private void updateStationLeftRightSurveyor(boolean leftRightSurveyor, String stationId) { + Log.d("hwhw", "更新左右角到数据库"); + ThreadPoolUtil.execute(() -> { + ISurveyorStationDataSource surveyorStationDataSource = + SurveyorDatabaseFactory + .instance + .getSurveyorStation(); + SurveyorStationRecord surveyorStationRecord = + surveyorStationDataSource.getRecordSync(stationId); + //修改 + surveyorStationRecord.setLeftAndRightSurveyor(leftRightSurveyor); + //存储 + surveyorStationDataSource.save(surveyorStationRecord); + }); + } + + public static void start(Context context, String surveyorStationId, + String surveyorStationName, String projectId, String lineType) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_NAME, surveyorStationName); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_TYPE, lineType); + FragmentContainerActivity.start(context, TAG, context.getString(title) + "-" + surveyorStationName, bundle); + } + + public static SingleStationDetailAndEditFragment newInstance(Bundle bundle) { + SingleStationDetailAndEditFragment fragment = new SingleStationDetailAndEditFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/StationDetailViewModel.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/StationDetailViewModel.java new file mode 100644 index 0000000..41d4dbc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/StationDetailViewModel.java @@ -0,0 +1,26 @@ +package com.bingce.controlnetwork.fragment.stationdetail; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class StationDetailViewModel extends ViewModel { + private final MutableLiveData refreshUiLiveData = new MutableLiveData<>(); + private boolean leftAndRightSurveyor; + + public LiveData getRefreshUiLiveData() { + return refreshUiLiveData; + } + + public void setRefreshUi() { + refreshUiLiveData.setValue(true); + } + + public void setLeftOrRight(boolean leftAndRightSurveyor) { + this.leftAndRightSurveyor = leftAndRightSurveyor; + } + + public boolean isLeftAndRightSurveyor() { + return leftAndRightSurveyor; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/BaseStationSettingFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/BaseStationSettingFragment.kt new file mode 100644 index 0000000..eea4028 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/BaseStationSettingFragment.kt @@ -0,0 +1,49 @@ +package com.bingce.controlnetwork.fragment.stationsetting + +import android.os.Bundle +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import com.bingce.controlnetwork.fragment.base.BaseFragment +import com.bingce.controlnetwork.R + +abstract class BaseStationSettingFragment : BaseFragment() { + + companion object { + const val DEFAULT_TEMPERATURE = "12" + const val DEFAULT_HUMIDITY = "60" + const val DEFAULT_AIR_PRESSURE = "1013.3" + const val DEFAULT_CONSTANT = "0" + const val DEFAULT_INSTRUMEN_HEIGHT = "0" + + const val KEY_SURVEYOR_STATION_ID = "___surveyor_station_id___" + + } + + protected abstract fun clickConfirm() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setHasOptionsMenu(true) + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_confirm, menu) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.menu_confirm === item.itemId) { + clickConfirm() + } + return super.onOptionsItemSelected(item) + } + + /** + * 返回非空测站id + */ + fun stationId(): String { + return requireArguments().getString(KEY_SURVEYOR_STATION_ID)!! + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingHeightTraverseFragment.kt new file mode 100644 index 0000000..b559ec3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingHeightTraverseFragment.kt @@ -0,0 +1,496 @@ +package com.bingce.controlnetwork.fragment.stationsetting + +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.EditText +import androidx.annotation.WorkerThread +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +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.heighttraverse.stationsetting.model.StationSettingHeightTraverseRecord +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentStationSettingHeightTraverseBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class StationSettingHeightTraverseFragment : BaseStationSettingFragment() { + + + private var _binding: FragmentStationSettingHeightTraverseBinding? = null + + val mBinding get() = _binding!! + + private val mainScope = MainScope() + + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = + FragmentStationSettingHeightTraverseBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + mainScope.cancel() + _binding = null + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initView() + initData() + initListener() + } + + private fun initListener() { + + //距离修正参数 + mBinding.ilTitle1.button1.setOnClickListener { + //默认设置 + setDataFromRecord(null) + } + + mBinding.ilTitle1.button2.setOnClickListener { + //使用上次数据 + setDataFromLast() + } + + //仪器高,棱镜高 + mBinding.ilInstrumentHeight.button1.setOnClickListener { + mBinding.ilInstrumentHeight.etValueAfter.setText( + getEtText(mBinding.ilInstrumentHeight.etValueBefore) + ) + } + mBinding.ilBackPrismHeight.button1.setOnClickListener { + mBinding.ilBackPrismHeight.etValueAfter.setText( + getEtText(mBinding.ilBackPrismHeight.etValueBefore) + ) + } + mBinding.ilFrontPrismHeight.button1.setOnClickListener { + mBinding.ilFrontPrismHeight.etValueAfter.setText( + getEtText(mBinding.ilFrontPrismHeight.etValueBefore) + ) + } + + } + + private fun setDataFromLast() { + mainScope.launch { + val record = withContext(Dispatchers.IO) { + val dryTemperature = getValueFromLastKey(ConfigConstants.KEY_LAST_DRY_TEMPERATURE) + val humidityTemperature = + getValueFromLastKey(ConfigConstants.KEY_LAST_HUMIDITY_TEMPERATURE) + val airPressure = getValueFromLastKey(ConfigConstants.KEY_LAST_AIR_PRESSURE) + val additionConstant = + getValueFromLastKey(ConfigConstants.KEY_LAST_ADDITION_CONSTANT) + val multiplicationConstant = + getValueFromLastKey(ConfigConstants.KEY_LAST_MULTIPLICATION_CONSTANT) + val instrumentHeightBefore = + getValueFromLastKey(ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_BEFORE) + val instrumentHeightAfter = + getValueFromLastKey(ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_AFTER) + val backPrismHeightBefore = + getValueFromLastKey(ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_BEFORE) + val backPrismHeightAfter = + getValueFromLastKey(ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_AFTER) + val frontPrismHeightBefore = + getValueFromLastKey(ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_BEFORE) + val frontPrismHeightAfter = + getValueFromLastKey(ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_AFTER) + + if (dryTemperature == null + || humidityTemperature == null + || airPressure == null + || additionConstant == null + || multiplicationConstant == null + || instrumentHeightBefore == null + || instrumentHeightAfter == null + || backPrismHeightBefore == null + || backPrismHeightAfter == null + || frontPrismHeightBefore == null + || frontPrismHeightAfter == null + ) { + return@withContext null + } + + StationSettingHeightTraverseRecord.newInstance( + stationId(), + dryTemperature, + humidityTemperature, + airPressure, + additionConstant, + multiplicationConstant, + instrumentHeightBefore, + instrumentHeightAfter, + backPrismHeightBefore, + backPrismHeightAfter, + frontPrismHeightBefore, + frontPrismHeightAfter + ) + } + + setDataFromRecord(record) + } + } + + private fun getValueFromLastKey(key: String): String? { + val record = + SurveyorDatabaseFactory.instance.configDataSource.getByKeySync(key) + return record?.configValue + } + + private fun initData() { + + mainScope.launch { + val record = withContext(Dispatchers.IO) { + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .getRecordByStationId(stationId()) + } + setDataFromRecord(record) + } + } + + private fun setDataFromRecord(record: StationSettingHeightTraverseRecord?) { + mBinding.ilDryTemperature.etValue.setText( + record?.dryTemperature ?: DEFAULT_TEMPERATURE + ) + mBinding.ilHumidityTemperature.etValue.setText( + record?.humidityTemperature ?: DEFAULT_TEMPERATURE + ) + mBinding.ilAirPressure.etValue.setText(record?.airPressure ?: DEFAULT_AIR_PRESSURE) + mBinding.ilAdditionConstant.etValue.setText( + record?.additionConstant ?: DEFAULT_CONSTANT + ) + mBinding.ilmultiplicationConstant.etValue.setText( + record?.multiplicationConstant ?: DEFAULT_CONSTANT + ) + + mBinding.ilInstrumentHeight.etValueBefore.setText( + record?.instrumentHeightBefore ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilInstrumentHeight.etValueAfter.setText( + record?.instrumentHeightAfter ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilBackPrismHeight.etValueBefore.setText( + record?.backPrismHeightBefore ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilBackPrismHeight.etValueAfter.setText( + record?.backPrismHeightAfter ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilFrontPrismHeight.etValueBefore.setText( + record?.frontPrismHeightBefore ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilFrontPrismHeight.etValueAfter.setText( + record?.frontPrismHeightAfter ?: DEFAULT_INSTRUMEN_HEIGHT + ) + } + + + private fun initView() { + mBinding.ilTitle1.title.text = Tools.getString(R.string.distance_correction_parameter) + mBinding.ilTitle1.button1.text = Tools.getString(R.string.default_setting) + mBinding.ilTitle1.button2.text = Tools.getString(R.string.button_use_last_station_settings) + + mBinding.ilTitle2.title.text = Tools.getString(R.string.instrument_height_prism_height_m) + + + mBinding.ilDryTemperature.tvName.text = getString(R.string.dry_temperature) + mBinding.ilDryTemperature.etValue.hint = getString(R.string.dry_temperature) + mBinding.ilDryTemperature.tvUnit.text = "℃" + + mBinding.ilHumidityTemperature.tvName.text = getString(R.string.humidity_temperature) + mBinding.ilHumidityTemperature.etValue.hint = getString(R.string.humidity_temperature) + mBinding.ilHumidityTemperature.tvUnit.text = "℃" + + mBinding.ilAirPressure.tvName.text = getString(R.string.hint_air_pressure) + mBinding.ilAirPressure.etValue.hint = getString(R.string.hint_air_pressure) + mBinding.ilAirPressure.tvUnit.text = "hPa" + + mBinding.ilAdditionConstant.tvName.text = getString(R.string.addition_constant) + mBinding.ilAdditionConstant.etValue.hint = getString(R.string.addition_constant) + mBinding.ilAdditionConstant.tvUnit.text = "mm" + + mBinding.ilmultiplicationConstant.tvName.text = getString(R.string.multiplication_constant) + mBinding.ilmultiplicationConstant.etValue.hint = getString(R.string.multiplication_constant) + mBinding.ilmultiplicationConstant.tvUnit.text = "ppm" + + mBinding.ilInstrumentHeight.tvName.text = getString(R.string.instrument_height) + mBinding.ilBackPrismHeight.tvName.text = getString(R.string.back_prism_height) + mBinding.ilFrontPrismHeight.tvName.text = getString(R.string.front_prism_height) + } + + companion object { + + @JvmField + val TAG: String = StationSettingHeightTraverseFragment::class.java.name + + @JvmStatic + fun newInstance(bundle: Bundle?): StationSettingHeightTraverseFragment { + val fragment = StationSettingHeightTraverseFragment() + fragment.arguments = bundle + return fragment + } + + @JvmStatic + fun start(context: Context, surveyorStationId: String?) { + val bundle = Bundle() + bundle.putString(KEY_SURVEYOR_STATION_ID, surveyorStationId) + FragmentContainerActivity.start( + context, + TAG, + R.string.surveyor_station_edit, + bundle + ) + } + } + + override fun clickConfirm() { + + mainScope.launch(Dispatchers.IO) { + if (checkConfirmEmpty()) { + return@launch + } + + val stationId = stationId() + + val stationSettingHeightTraverseRecord = + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .getRecordByStationId(stationId) + + + val dryTemperature = getEtText(mBinding.ilDryTemperature.etValue) + val humidityTemperature = getEtText(mBinding.ilHumidityTemperature.etValue) + val airPressure = getEtText(mBinding.ilAirPressure.etValue) + val additionConstant = getEtText(mBinding.ilAdditionConstant.etValue) + val multiplicationConstant = getEtText(mBinding.ilmultiplicationConstant.etValue) + val instrumentHeightBefore = getEtText(mBinding.ilInstrumentHeight.etValueBefore) + val instrumentHeightAfter = getEtText(mBinding.ilInstrumentHeight.etValueAfter) + val backPrismHeightBefore = getEtText(mBinding.ilBackPrismHeight.etValueBefore) + val backPrismHeightAfter = getEtText(mBinding.ilBackPrismHeight.etValueAfter) + val frontPrismHeightBefore = getEtText(mBinding.ilFrontPrismHeight.etValueBefore) + val frontPrismHeightAfter = getEtText(mBinding.ilFrontPrismHeight.etValueAfter) + + if (stationSettingHeightTraverseRecord == null) { + val stationSettingHeightTraverseRecordNew = + StationSettingHeightTraverseRecord.newInstance( + stationId, + dryTemperature, + humidityTemperature, + airPressure, + additionConstant, + multiplicationConstant, + instrumentHeightBefore, + instrumentHeightAfter, + backPrismHeightBefore, + backPrismHeightAfter, + frontPrismHeightBefore, + frontPrismHeightAfter + ) + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .saveRecord(stationSettingHeightTraverseRecordNew) + } else { + stationSettingHeightTraverseRecord.dryTemperature = dryTemperature + stationSettingHeightTraverseRecord.humidityTemperature = humidityTemperature + stationSettingHeightTraverseRecord.airPressure = airPressure + stationSettingHeightTraverseRecord.additionConstant = additionConstant + stationSettingHeightTraverseRecord.multiplicationConstant = multiplicationConstant + stationSettingHeightTraverseRecord.instrumentHeightBefore = instrumentHeightBefore + stationSettingHeightTraverseRecord.instrumentHeightAfter = instrumentHeightAfter + stationSettingHeightTraverseRecord.backPrismHeightBefore = backPrismHeightBefore + stationSettingHeightTraverseRecord.backPrismHeightAfter = backPrismHeightAfter + stationSettingHeightTraverseRecord.frontPrismHeightBefore = frontPrismHeightBefore + stationSettingHeightTraverseRecord.frontPrismHeightAfter = frontPrismHeightAfter + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .updateRecord(stationSettingHeightTraverseRecord) + } + + val stationRecord = + SurveyorDatabaseFactory.instance.surveyorStation.getRecordSync(stationId) + if (stationRecord != null) { + stationRecord.instrumentHeight = instrumentHeightBefore + if (!stationRecord.items.isNullOrEmpty()) { + stationRecord.items.last().prismHeight = frontPrismHeightBefore + if (stationRecord.items.size > 2) { + stationRecord.items[1].prismHeight = backPrismHeightBefore + } + } + } + SurveyorDatabaseFactory.instance.surveyorStation.update(stationRecord) + + saveLastData( + dryTemperature, + humidityTemperature, + airPressure, + additionConstant, + multiplicationConstant, + instrumentHeightBefore, + instrumentHeightAfter, + backPrismHeightBefore, + backPrismHeightAfter, + frontPrismHeightBefore, + frontPrismHeightAfter + ) + + ToastUtils.showShort(R.string.save_success) + requireActivity().finish() + + } + + } + + @WorkerThread + private fun saveLastData( + dryTemperature: String, + humidityTemperature: String, + airPressure: String, + additionConstant: String, + multiplicationConstant: String, + instrumentHeightBefore: String, + instrumentHeightAfter: String, + backPrismHeightBefore: String, + backPrismHeightAfter: String, + frontPrismHeightBefore: String, + frontPrismHeightAfter: String + ) { + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_DRY_TEMPERATURE, + dryTemperature + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_HUMIDITY_TEMPERATURE, + humidityTemperature + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_AIR_PRESSURE, + airPressure + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_ADDITION_CONSTANT, + additionConstant + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_MULTIPLICATION_CONSTANT, + multiplicationConstant + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_BEFORE, + instrumentHeightBefore + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_AFTER, + instrumentHeightAfter + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_BEFORE, + backPrismHeightBefore + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_AFTER, + backPrismHeightAfter + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_BEFORE, + frontPrismHeightBefore + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_AFTER, + frontPrismHeightAfter + ) + ) + } + + + private fun checkConfirmEmpty(): Boolean { + if (editTextEmpty(mBinding.ilDryTemperature.etValue)) { + ToastUtils.showShort(R.string.please_enter_dry_temperature) + return true + } + if (editTextEmpty(mBinding.ilHumidityTemperature.etValue)) { + ToastUtils.showShort(R.string.please_enter_humidity_temperature) + return true + } + if (editTextEmpty(mBinding.ilAirPressure.etValue)) { + ToastUtils.showShort(Tools.getString(R.string.please_enter_air_pressure)) + return true + } + if (editTextEmpty(mBinding.ilAdditionConstant.etValue)) { + ToastUtils.showShort(R.string.please_enter_addition_constant) + return true + } + if (editTextEmpty(mBinding.ilmultiplicationConstant.etValue)) { + ToastUtils.showShort(R.string.please_enter_multiplication_constant) + return true + } + + if (editTextEmpty(mBinding.ilInstrumentHeight.etValueBefore)) { + ToastUtils.showShort(R.string.please_enter_instrument_height_before) + return true + } + if (editTextEmpty(mBinding.ilInstrumentHeight.etValueAfter)) { + ToastUtils.showShort(R.string.please_enter_instrument_height_after) + return true + } + if (editTextEmpty(mBinding.ilBackPrismHeight.etValueBefore)) { + ToastUtils.showShort(R.string.please_enter_back_prism_height_before) + return true + } + if (editTextEmpty(mBinding.ilBackPrismHeight.etValueAfter)) { + ToastUtils.showShort(R.string.please_enter_back_prism_height_after) + return true + } + if (editTextEmpty(mBinding.ilFrontPrismHeight.etValueBefore)) { + ToastUtils.showShort(R.string.please_enter_front_prism_height_before) + return true + } + if (editTextEmpty(mBinding.ilFrontPrismHeight.etValueAfter)) { + ToastUtils.showShort(R.string.please_enter_front_prism_height_after) + return true + } + return false + } + + + private fun editTextEmpty(et: EditText): Boolean { + return TextUtils.isEmpty(getEtText(et)) + } + + private fun getEtText(et: EditText) = et.text.toString().trim() + + +} \ No newline at end of file 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 new file mode 100644 index 0000000..7fc342e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingsFragment.java @@ -0,0 +1,774 @@ +package com.bingce.controlnetwork.fragment.stationsetting; + +import android.content.Context; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.CheckBox; +import android.widget.Spinner; +import android.widget.TextView; + +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; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.prism.IPrismManagerDataSource; +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; +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; +import com.bingce.utils.ThreadPoolUtil; +import com.rengwuxian.materialedittext.MaterialEditText; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 仪器棱镜设置 + */ +public class StationSettingsFragment extends BaseStationSettingFragment { + public static final String TAG = StationSettingsFragment.class.getName(); + private SurveyorStationRecord surveyorStationRecord; + private _Adapter adapter = null; + private List prismRecords; + + private StationSettingsFragment() { + super(); + } + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_list_layout, container, false); + RecyclerView recyclerView = view.findViewById(R.id.list); + if (recyclerView != null && getArguments() != null) { + String stationId = getArguments().getString(KEY_SURVEYOR_STATION_ID); + ThreadPoolUtil.execute(() -> { + surveyorStationRecord = + SurveyorDatabaseFactory.instance.getSurveyorStation() + .getRecordSync(stationId); + if (surveyorStationRecord == null) { + return; + } + + + IConfigDataSource configDataSource = + SurveyorDatabaseFactory + .instance.getConfigDataSource(); + + ConfigRecord temperature = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_TEMPERATURE); + ConfigRecord humidity = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_HUMIDITY); + ConfigRecord airPress = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_AIR_PRESSURE); + + List<_Item> items = new ArrayList<>(); + //添加环境title + items.add(new _TitleWithButtonItem(getString(R.string.title_set_environment_info), + getString(R.string.button_use_default_station_settings), + getString(R.string.button_use_last_station_settings), + items)); + //添加温度 + items.add(new _1EditTextItem(getString(R.string.hint_temperature), + temperature(surveyorStationRecord, temperature, DEFAULT_TEMPERATURE), + getString(R.string.hint_temperature), + "℃", + _VH.ATTRIBUTE_TEMPERATURE, + surveyorStationRecord)); + //添加湿度 + items.add(new _1EditTextItem(getString(R.string.hint_humidity), + humidity(surveyorStationRecord, humidity, DEFAULT_HUMIDITY), + getString(R.string.hint_humidity), + "%", + _VH.ATTRIBUTE_HUMIDITY, + surveyorStationRecord)); + //添加气压 + items.add(new _1EditTextItem(getString(R.string.hint_air_pressure), + airPress(surveyorStationRecord, airPress, DEFAULT_AIR_PRESSURE), + getString(R.string.hint_air_pressure), + "hPa", + _VH.ATTRIBUTE_AIR_PRESSURE, + surveyorStationRecord)); + + if (surveyorStationRecord.getTemperature() == null) { + surveyorStationRecord.setTemperature(DEFAULT_TEMPERATURE); + } + if (surveyorStationRecord.getHumidity() == null) { + surveyorStationRecord.setHumidity(DEFAULT_HUMIDITY); + } + if (surveyorStationRecord.getAirPressure() == null) { + surveyorStationRecord.setAirPressure(DEFAULT_AIR_PRESSURE); + } + + //添加高度title + items.add(new _TitleItem(getString(R.string.title_set_height_info))); + //添加仪器高 + items.add(new _1EditTextItem(getString(R.string.instrument_height), + valueOf(surveyorStationRecord.getInstrumentHeight()), + getString(R.string.instrument_height), + "m", + _VH.ATTRIBUTE_INSTRUMENT_HEIGHT, + surveyorStationRecord)); + if (surveyorStationRecord.getInstrumentHeight() == null) { + surveyorStationRecord.setInstrumentHeight("0"); + } + //是否是联系测量 + boolean isConnection = ProjectType.isConnection(surveyorStationRecord.projectType); + + //添加point title + items.add(new _PointTitleItem(isConnection)); + //添加点坐标 + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + List stationItems = surveyorStationRecord.getItems(); + + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + prismRecords = prismManagerDataSource.getAllRecordSync(); + + boolean stationHasRecord = StationUtil.hasRecord(surveyorStationRecord.getId()); + if (stationItems != null) { + for (SurveyorPoint surveyorPoint : stationItems) { + if (surveyorPoint == null || !SurveyorPoint.TYPE_POINT.equals(surveyorPoint.getType())) { + continue; + } + if (surveyorPoint.isWellSteel()) { + continue; + } + + if (surveyorPoint.getPrismHeight() == null) { + surveyorPoint.setPrismHeight("0"); + } + + //当是测点的时候 + PointRecord pointRecord = pointDataSource.findByIdSync(surveyorPoint.getOriginalPointId()); + items.add(new _2EditTextItem( + pointRecord.getName(), + surveyorPoint, + prismRecords, + !stationHasRecord, + isConnection + )); + } + } + //刷新recycle view + adapter = new _Adapter(items); + runOnUI(() -> recyclerView.setAdapter(adapter)); + }); + } + return view; + } + + @Override + protected void clickConfirm() { + if (adapter != null) { + String error = adapter.checkSave(); + if (error == null || error.isEmpty()) {//成功 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .save(surveyorStationRecord); + + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + configDataSource.set(ConfigConstants.KEY_LAST_TEMPERATURE, surveyorStationRecord.getTemperature()); + configDataSource.set(ConfigConstants.KEY_LAST_AIR_PRESSURE, surveyorStationRecord.getAirPressure()); + configDataSource.set(ConfigConstants.KEY_LAST_HUMIDITY, surveyorStationRecord.getHumidity()); + + HideKeyUtil.hideSoftInput(getActivity()); + if (getActivity() != null) { + getActivity().finish(); + } + } else { + ToastUtils.showShort(error); + } + } + } + + private abstract static class _Item { + final int type; + final String name; + View itemView = null; + + _Item(int type, String name) { + this.type = type; + this.name = name; + } + + void attach(View itemView) { + this.itemView = itemView; + } + + abstract String prepare2Save(); + } + + private static class _TitleItem extends _Item { + _TitleItem(String name) { + super(_VH.TYPE_TITLE, name); + } + + @Override + String prepare2Save() { + return null; + } + } + + private static class _TitleWithButtonItem extends _Item { + final String button1; + final String button2; + final List<_Item> items; + + _TitleWithButtonItem(String name, String button1, String button2, List<_Item> items) { + super(_VH.TYPE_TITLE_WITH_2BUTTON, name); + this.button1 = button1; + this.button2 = button2; + this.items = items; + } + + @Override + String prepare2Save() { + return null; + } + } + + private static class _PointTitleItem extends _Item { + 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 { + private final String value; + private final String hintString; + private final String unit; + private final SurveyorStationRecord stationRecord; + private final int attributeType; + + _1EditTextItem(String name, String value, + String hintString, String unit, + int attributeType, + SurveyorStationRecord stationRecord) { + super(_VH.TYPE_1_EDIT_TEXT, name); + this.value = value; + this.hintString = hintString; + this.unit = unit; + this.attributeType = attributeType; + this.stationRecord = stationRecord; + } + + @Override + void attach(View itemView) { + super.attach(itemView); + MaterialEditText value = itemView.findViewById(R.id.value); + if (value != null) { + Watcher watcher = new Watcher() { + @Override + void onChanged(String string) { + if (_VH.ATTRIBUTE_TEMPERATURE == attributeType) { + stationRecord.setTemperature(string); + } else if (_VH.ATTRIBUTE_HUMIDITY == attributeType) { + stationRecord.setHumidity(string); + } else if (_VH.ATTRIBUTE_AIR_PRESSURE == attributeType) { + stationRecord.setAirPressure(string); + } else if (_VH.ATTRIBUTE_INSTRUMENT_HEIGHT == attributeType) { + stationRecord.setInstrumentHeight(string); + } + } + }; + value.addTextChangedListener(watcher); + } + } + + @Override + String prepare2Save() { + if (_VH.ATTRIBUTE_TEMPERATURE == attributeType) { + if (!isEmptyString(stationRecord.getTemperature())) { + return null; + } + } else if (_VH.ATTRIBUTE_HUMIDITY == attributeType) { + if (!isEmptyString(stationRecord.getHumidity())) { + return null; + } + } else if (_VH.ATTRIBUTE_AIR_PRESSURE == attributeType) { + if (!isEmptyString(stationRecord.getAirPressure())) { + return null; + } + } else if (_VH.ATTRIBUTE_INSTRUMENT_HEIGHT == attributeType) { + if (!isEmptyString(stationRecord.getInstrumentHeight())) { + return null; + } + } + return Tools.getString(R.string.please_enter) + name; + } + } + + private static class _2EditTextItem extends _Item { + 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 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()); + } + } + + @Override + void attach(View itemView) { + super.attach(itemView); + MaterialEditText value1 = itemView.findViewById(R.id.value1); + if (value1 != null) { + value1.addTextChangedListener(new Watcher() { + @Override + void onChanged(String string) { + surveyorPoint.setPrismHeight(string); + } + }); + } + + Spinner spinner = itemView.findViewById(R.id.spinner); + if (spinner != null) { + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + PrismRecord prismRecord = prismRecords.get(position); + surveyorPoint.setPrismType(prismRecord.prismType); + surveyorPoint.setPrismTypeConstant(prismRecord.prismTypeConstant); + surveyorPoint.setPrismTypeName(prismRecord.getShowPrismTypeName()); + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } + + CheckBox checkBox = itemView.findViewById(R.id.checkBox); + if (checkBox != null) { + if (isConnection) { + checkBox.setVisibility(View.VISIBLE); + checkBox.setEnabled(isCanSelectAloneDistance); + checkBox.setOnCheckedChangeListener((compoundButton, checked) -> { + surveyorPoint.setAloneDistance(checked); + }); + } else { + checkBox.setVisibility(View.INVISIBLE); + } + } + + } + + @Override + String prepare2Save() { + if (!isEmptyString(surveyorPoint.getPrismHeight())) { + return null; + } + return Tools.getString(R.string.please_enter) + name + Tools.getString(R.string.prism_height); + } + } + + private static abstract class _VH extends RecyclerView.ViewHolder { + static final int TYPE_TITLE = 0; + static final int TYPE_TITLE_WITH_2BUTTON = TYPE_TITLE + 1; + static final int TYPE_POINT_TITLE = TYPE_TITLE_WITH_2BUTTON + 1; + static final int TYPE_1_EDIT_TEXT = TYPE_POINT_TITLE + 1; + static final int TYPE_2_EDIT_TEXT = TYPE_1_EDIT_TEXT + 1; + + static final int ATTRIBUTE_TEMPERATURE = 0;//温度 + static final int ATTRIBUTE_HUMIDITY = ATTRIBUTE_TEMPERATURE + 1;//湿度 + static final int ATTRIBUTE_AIR_PRESSURE = ATTRIBUTE_HUMIDITY + 1;//气压 + static final int ATTRIBUTE_INSTRUMENT_HEIGHT = ATTRIBUTE_AIR_PRESSURE + 1;//仪器高 + + public _VH(@NonNull @NotNull View itemView) { + super(itemView); + } + + abstract void setup(_Item item); + } + + private static class _TitleVH extends _VH { + private final TextView titleText; + + public _TitleVH(@NonNull @NotNull View itemView) { + super(itemView); + titleText = itemView.findViewById(R.id.title); + } + + @Override + void setup(_Item item) { + if (titleText != null) { + titleText.setText(item.name); + } + } + } + + private static class _TitleWith2ButtonVH extends _TitleVH { + final TextView button1; + final TextView button2; + + public _TitleWith2ButtonVH(@NonNull @NotNull View itemView) { + super(itemView); + button1 = itemView.findViewById(R.id.button1); + button2 = itemView.findViewById(R.id.button2); + } + + @Override + void setup(_Item item) { + super.setup(item); + if (item instanceof _TitleWithButtonItem) { + _TitleWithButtonItem titleWithButtonItem = (_TitleWithButtonItem) item; + if (button1 != null) { + button1.setText(titleWithButtonItem.button1); + button1.setOnClickListener(v -> update(titleWithButtonItem.items, + DEFAULT_TEMPERATURE, DEFAULT_HUMIDITY, DEFAULT_AIR_PRESSURE)); + } + if (button2 != null) { + button2.setText(titleWithButtonItem.button2); + //判断能否点击 + ThreadPoolUtil.execute(() -> { + IConfigDataSource configDataSource = + SurveyorDatabaseFactory + .instance.getConfigDataSource(); + + ConfigRecord temperature = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_TEMPERATURE); + ConfigRecord humidity = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_HUMIDITY); + ConfigRecord airPress = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_AIR_PRESSURE); + if (temperature != null && humidity != null && airPress != null) { + ThreadPoolUtil.executeInMain(() -> { + button2.setEnabled(true); + button2.setAlpha(1); + button2.setOnClickListener(v -> update(titleWithButtonItem.items, + temperature.getConfigValue(), + humidity.getConfigValue(), + airPress.getConfigValue())); + }); + } + }); + } + } + } + + private void update(List<_Item> items, String temperature, String humidity, String airPress) { + for (int index = 0; index < items.size(); index++) { + _Item item = items.get(index); + if (!(item instanceof _1EditTextItem)) { + continue; + } + _1EditTextItem editTextItem = (_1EditTextItem) item; + MaterialEditText value = item.itemView.findViewById(R.id.value); + if (editTextItem.attributeType == _VH.ATTRIBUTE_TEMPERATURE) {//温度 + if (value != null) { + value.setText(temperature); + } + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_AIR_PRESSURE) {//气压 + if (value != null) { + value.setText(airPress); + } + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_HUMIDITY) {//湿度 + if (value != null) { + value.setText(humidity); + } + } + } + } + } + + private static class _PointTitleVH extends _VH { + public _PointTitleVH(@NonNull @NotNull View itemView) { + super(itemView); + } + + @Override + void setup(_Item item) { + } + } + + private static class _1EditTextVH extends _VH { + private final TextView name; + private final MaterialEditText value; + private final TextView unit; + + public _1EditTextVH(@NonNull @NotNull View itemView) { + super(itemView); + name = itemView.findViewById(R.id.name); + value = itemView.findViewById(R.id.value); + unit = itemView.findViewById(R.id.unit); + } + + @Override + void setup(_Item item) { + if (item instanceof _1EditTextItem) { + _1EditTextItem editTextItem = (_1EditTextItem) item; + if (name != null) { + name.setText(editTextItem.name); + } + String v1 = null; + if (editTextItem.attributeType == _VH.ATTRIBUTE_INSTRUMENT_HEIGHT) { + v1 = editTextItem.stationRecord.getInstrumentHeight(); + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_TEMPERATURE) {//温度 + v1 = editTextItem.stationRecord.getTemperature(); + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_AIR_PRESSURE) {//气压 + v1 = editTextItem.stationRecord.getAirPressure(); + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_HUMIDITY) {//湿度 + v1 = editTextItem.stationRecord.getHumidity(); + } + + + if (value != null) { + value.setText(v1); + value.setHint(editTextItem.hintString); + } + if (unit != null) { + unit.setText(editTextItem.unit); + } + } + } + } + + private static class _2EditTextVH extends _VH { + private final TextView tvPointName; + private final MaterialEditText etPrismHeight; + private final Spinner spinnerPrismType; + private final CheckBox checkBoxAloneDistance; + + public _2EditTextVH(@NonNull @NotNull View itemView) { + super(itemView); + tvPointName = itemView.findViewById(R.id.name); + etPrismHeight = itemView.findViewById(R.id.value1); + spinnerPrismType = itemView.findViewById(R.id.spinner); + checkBoxAloneDistance = itemView.findViewById(R.id.checkBox); + } + + @Override + void setup(_Item item) { + if (item instanceof _2EditTextItem) { + _2EditTextItem editTextItem = (_2EditTextItem) item; + if (tvPointName != null) { + tvPointName.setText(editTextItem.name); + } + + if (etPrismHeight != null) { + etPrismHeight.setText(editTextItem.surveyorPoint.getPrismHeight()); + } + + if (spinnerPrismType != null) { + SpinnerAdapter spinnerAdapter = new SpinnerAdapter(itemView.getContext(), editTextItem.prismTypes); + spinnerPrismType.setAdapter(spinnerAdapter); + spinnerPrismType.setSelection(editTextItem.prismTypes.indexOf(editTextItem.surveyorPoint.getPrismTypeName())); + } + + if (checkBoxAloneDistance != null) { + checkBoxAloneDistance.setChecked(editTextItem.surveyorPoint.isAloneDistance()); + } + + } + } + } + + private static class _Adapter extends BaseAdapter<_Item, _VH> { + + public _Adapter(List<_Item> items) { + super(items); + } + + @Override + public int getItemViewType(int position) { + _Item item = getItem(position); + return item.type; + } + + @Override + protected _VH createVH(@NotNull ViewGroup parent, int viewType) { + if (_VH.TYPE_TITLE == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_title_layout, parent, false); + return new _TitleVH(itemView); + } else if (_VH.TYPE_TITLE_WITH_2BUTTON == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_title_with_2button_layout, parent, false); + return new _TitleWith2ButtonVH(itemView); + } else if (_VH.TYPE_POINT_TITLE == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_point_title_layout, parent, false); + return new _PointTitleVH(itemView); + } else if (_VH.TYPE_1_EDIT_TEXT == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_1_edittext_layout, parent, false); + return new _1EditTextVH(itemView); + } else if (_VH.TYPE_2_EDIT_TEXT == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_2_edittext_layout, parent, false); + return new _2EditTextVH(itemView); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull StationSettingsFragment._VH holder, int position) { + _Item item = getItem(position); + item.attach(holder.itemView); + holder.setup(item); + } + + /** + * 保存前的检查 + * + * @return + */ + String checkSave() { + for (int index = 0; index < getItemCount(); index++) { + _Item item = getItem(index); + String error = item.prepare2Save(); + if (error != null && !error.isEmpty()) { + return error; + } + } + return null; + } + } + + private static String getString(MaterialEditText editText) { + if (editText == null) { + return ""; + } + if (editText.getText() == null) { + return ""; + } + return editText.getText().toString(); + } + + private String valueOf(String value) { + if (value == null) { + return ""; + } + return value; + } + + public static StationSettingsFragment newInstance(Bundle bundle) { + StationSettingsFragment fragment = new StationSettingsFragment(); + fragment.setArguments(bundle); + return fragment; + } + + public static void start(Context context, String surveyorStationId) { + Bundle bundle = new Bundle(); + bundle.putString(KEY_SURVEYOR_STATION_ID, surveyorStationId); + FragmentContainerActivity.start(context, TAG, R.string.title_instrument_prism_setting, bundle); + } + + private String temperature(SurveyorStationRecord surveyorStationRecord, + ConfigRecord lastRecord, + String defaultRecord) { + if (surveyorStationRecord != null && !valueOf(surveyorStationRecord.temperature).isEmpty()) { + return surveyorStationRecord.temperature; + } + + return configValue(lastRecord, defaultRecord); + } + + private String humidity(SurveyorStationRecord surveyorStationRecord, + ConfigRecord lastRecord, + String defaultRecord) { + if (surveyorStationRecord != null && !valueOf(surveyorStationRecord.humidity).isEmpty()) { + return surveyorStationRecord.humidity; + } + + return configValue(lastRecord, defaultRecord); + } + + private String airPress(SurveyorStationRecord surveyorStationRecord, + ConfigRecord lastRecord, + String defaultRecord) { + if (surveyorStationRecord != null && !valueOf(surveyorStationRecord.airPressure).isEmpty()) { + return surveyorStationRecord.airPressure; + } + + return configValue(lastRecord, defaultRecord); + } + + private String configValue(ConfigRecord lastRecord, String defaultRecord) { + if (lastRecord != null && !valueOf(lastRecord.getConfigValue()).isEmpty()) { + return lastRecord.getConfigValue(); + } + return defaultRecord; + } + + private abstract static class Watcher implements TextWatcher { + @Override + final public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + final public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + final public void afterTextChanged(Editable s) { + onChanged(s.toString()); + } + + abstract void onChanged(String string); + } + + private static boolean isEmptyString(String string) { + return string == null || string.isEmpty(); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/IMeasureOperate.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/IMeasureOperate.java new file mode 100644 index 0000000..ac6ee3c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/IMeasureOperate.java @@ -0,0 +1,28 @@ +package com.bingce.controlnetwork.fragment.stationsurvey; + +/** + * 开始测量等操作接口 + */ +public interface IMeasureOperate { + void doSurveyor(); + + void autoSurvey(); + + void switchCycle(int cycleIndex); + + void deleteStationAllPeroidRecord(); + + void deleteStationOnePeriodRecord(int cycleIndex); + + String stationCheck(); + + void stationAdjust(); + + void goBack(); + + boolean isCurrentCycleComplete(); + + void refreshGoBackBtnEnable(); + + int measureTypePosition(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/MethodCheckSetting.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/MethodCheckSetting.java new file mode 100644 index 0000000..3a14141 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/MethodCheckSetting.java @@ -0,0 +1,93 @@ +package com.bingce.controlnetwork.fragment.stationsurvey; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +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.util.IUIRunner; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.newui.stationsetting.StationSettingsActivity; + +import java.util.List; + +public class MethodCheckSetting { + /** + * 检测测站是否设置了棱镜相关属性,如果没有则跳转到设置界面 + */ + @WorkerThread + public static void checkStationSettings(String stationId, + @NonNull Fragment fragment, + @NonNull IUIRunner runner) { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + //检测温度、湿度、气压、棱镜是否设置 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + if (stationRecord == null) { + return; + } + List stationItemList = stationRecord.getItems(); + if (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) { + TipsWith2OptionFragment.dismissNowMe(); + return; + } + + runner.runOnUI(() -> { + TipsWith2OptionFragment.Argument argument = new TipsWith2OptionFragment.Argument(); + argument.content(Tools.getString(R.string.please_set_environment)); + argument.cancelable(false); + argument.autoDismiss(false); + + TipsWith2OptionFragment.tips( + fragment.getChildFragmentManager(), + fragment.getViewLifecycleOwner(), + argument, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + StationSettingsActivity.start(fragment.requireContext(), stationId); +// StationSettingsFragment.start(fragment.getContext(), stationId); + } + + @Override + public void onCancel() { + if (fragment.getActivity() != null) { + fragment.getActivity().finish(); + } + } + }); + }); + } + + public static boolean isEmpty(String string) { + return string == null || string.isEmpty(); + } +} 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 new file mode 100644 index 0000000..304d5a6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/StationSurveyorFragment.java @@ -0,0 +1,414 @@ +package com.bingce.controlnetwork.fragment.stationsurvey; + +import android.content.Context; +import android.graphics.Color; +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.view.WindowManager; +import android.widget.Button; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.BottomSheetSelectListFragment; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +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; +import com.github.razir.progressbutton.ProgressButtonHolderKt; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; + +/** + * 测站测量页面(开始测量) + */ +public class StationSurveyorFragment extends BaseFragment { + public static final String TAG = StationSurveyorFragment.class.getName(); + private ComponentStationSurveyorDataListFragment fragment; + private MenuItem goBack = null;//数据回退菜单 + private SurveyorStationRecord surveyorStationRecord; + private int cycleIndex = 0; + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onRefreshGoBack(RefreshGoBackButton event) { + if (goBack != null) { + goBack.setEnabled(event.validate); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onSurveyorStateChanged(SurveyStateEvent event) { + if (getView() == null) { + return; + } + Button surveyorButton = getView().findViewById(R.id.surveyor); + if (surveyorButton == null) { + return; + } + if (event.isIdle() || event.isSuccess() || event.isCompleted()) { + DrawableButtonExtensionsKt.hideProgress(surveyorButton, R.string.start_surveyor); + } else if (event.isSurveying()) { + DrawableButtonExtensionsKt.showProgress(surveyorButton, progressParams -> { + progressParams.setButtonTextRes(R.string.tips_surveying); + progressParams.setProgressColor(Color.WHITE); + return null; + }); + } else if (event.isFailure()) { + DrawableButtonExtensionsKt.hideProgress(surveyorButton, R.string.tips_surveyor_failure_and_retry); + } + + boolean enable = event.isIdle() || event.isFailure() || event.isSuccess(); + setSurveyorEnable(getView(), R.id.surveyor, enable); + setSurveyorEnable(getView(), R.id.auto_surveyor, enable); + } + + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onAutoSurveyorChanged(AutoSurveyorButtonVisibleEvent event) { + if (getView() == null) { + return; + } + Button autoSurveyButton = getView().findViewById(R.id.auto_surveyor); + if (autoSurveyButton != null) { + autoSurveyButton.setVisibility(event.isReadyAutoSurvey() && !event.isOpenAutoSurvey() + ? View.VISIBLE : View.GONE); + } + } + + private String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(BundleConstants.KEY_SURVEYOR_STATION_ID); + } + + @Override + public void onResume() { + super.onResume(); + //测量界面保持常亮 + if (getActivity() != null) { + getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + @Override + public void onPause() { + super.onPause(); + //关闭测量界面保持常亮 + if (getActivity() != null) { + getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + @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); + + replaceFragment(); + + //2.设置测量按钮 + Button surveyor = view.findViewById(R.id.surveyor); + if (surveyor != null) { + ProgressButtonHolderKt.bindProgressButton(getViewLifecycleOwner(), surveyor); + } + setSurveyorClick(view, R.id.surveyor, () -> { + if (fragment != null) { + fragment.doSurveyor(); + } + }); + setSurveyorClick(view, R.id.auto_surveyor, () -> { + if (fragment != null) { + fragment.autoSurvey(); + } + }); + //3.查询测站信息 + ThreadPoolUtil.execute(() -> { + surveyorStationRecord = SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId()); + //监听当前测回切换 + initObserver(view); + //监听数据变化 + ToleranceDetailRecord toleranceRecord = getTolerance(surveyorStationRecord); + if (toleranceRecord == null) { + return; + } + //注册UI监听 + View pick = view.findViewById(R.id.cycleLayout); + if (pick == null) { + return; + } + int cycleCount = toleranceRecord.getCycleCount(); + pick.setOnClickListener(v -> { + ArrayList cycleList = SurveyorCycleUtil.cycleStrings(cycleCount, + surveyorStationRecord != null && surveyorStationRecord.leftAndRightSurveyor); + + TextView circleText = view.findViewById(R.id.circle_text); + runOnUI(() -> BottomSheetSelectListFragment.showSelect( + getChildFragmentManager(), + getViewLifecycleOwner(), + cycleIndex, + cycleList, + null,//不再限制测期 + (index, string) -> { + if (circleText != null) { + circleText.setText(string); + } + cycleIndex = index; + if (fragment != null) { + //检测当前测回是否完成 + fragment.switchCycle(cycleIndex); + } + })); + }); + }); + + + setHasOptionsMenu(true); + + return view; + } + + private void replaceFragment() { + //1.添加测量数据显示fragment + fragment = ComponentStationSurveyorDataListFragment + .newInstance(stationId()); + getChildFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, fragment, "___station_list") + .commit(); + } + + private void initObserver(View view) { + runOnUI(() -> { + monitorCurrentCycle(view); + //监听测站变化 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + stationRecord -> { + replaceFragment(); + 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); + + + } + + private void monitorCurrentCycle(View view) { + 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)); + } + StationSurveyorFragment.this.cycleIndex = cycleIndex; + }); + } + + private static void setSurveyorClick(View rootView, int id, Runnable runnable) { + View view = rootView.findViewById(id); + if (view != null) { + view.setOnClickListener(v -> runnable.run()); + } + } + + private static void setSurveyorEnable(View rootView, int id, boolean enable) { + if (rootView == null) { + return; + } + View view = rootView.findViewById(id); + if (view != null) { + view.setEnabled(enable); + if (enable) { + view.setAlpha(1); + } else { + view.setAlpha(.4f); + } + } + } + + @Override + public void onCreateOptionsMenu(@NonNull @NotNull Menu menu, @NonNull @NotNull MenuInflater inflater) { + if (Test.DEBUG) { + inflater.inflate(R.menu.menu_surveyor_station_record_data_edit_debug, menu); + } 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); + 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); +// } +// }); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (R.id.menu_item_delete_current_records == item.getItemId()) { + //删除当前测回记录 + if (surveyorStationRecord != null) { + //通知fragment + fragment.deleteByStationAndPeriod(cycleIndex); + } + } else if (R.id.menu_item_delete_all_records == item.getItemId()) { + //删除所有测回记录 + if (surveyorStationRecord != null) { + //通知fragment + fragment.deleteCurrentStationSurveyorData(); + } + } else if (R.id.menu_item_station_check == item.getItemId()) { + //测站检测,检测所有测回 + fragment.stationCheck(); + } else if (R.id.menu_item_data_source == item.getItemId()) { + //数据源 debug使用 + TestDataSelectFragment.show(getChildFragmentManager()); + } else if (R.id.menu_item_go_back == item.getItemId()) { + //回退 + fragment.goBack(); + } else if (R.id.menu_item_station_environment_prism_settings == item.getItemId()) { + //环境、棱镜设置 + StationSettingsActivity.start(requireContext(), stationId()); +// StationSettingsFragment.start(getContext(), stationId()); + } else if (R.id.menu_item_surveyor_settings == item.getItemId()) { + //测量设置 + ThreadPoolUtil.execute(() -> { + String name = StationUtil.getStationName(surveyorStationRecord); + runOnUI(() -> SurveyorSettingsFragment.start(getContext(), surveyorStationRecord.getId(), name)); + }); + } 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); + } + + @WorkerThread + private static ToleranceDetailRecord getTolerance(SurveyorStationRecord surveyorStationRecord) { + if (surveyorStationRecord == null) { + return null; + } + //获取project信息 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + return null; + } + //获取限差数据 + return SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + } + + public static void start(Context context, String surveyorStationId, String surveyorStationName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId); + FragmentContainerActivity.start(context, TAG, surveyorStationName, bundle); + } + + public static Fragment newInstance(Bundle args) { + Fragment fragment = new StationSurveyorFragment(); + fragment.setArguments(args); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDefaultFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDefaultFragment.java new file mode 100644 index 0000000..d381b58 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDefaultFragment.java @@ -0,0 +1,411 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import android.content.Context; +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.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ViewModelProvider; +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.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.surveyor.data.CachedData; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.SurveyorData; +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.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.angledistance.StateManager; +import com.bingce.controlnetwork.surveyor.state.angledistance._IsSingleCycleCompletedState; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.angledistance.StateManager; +import com.bingce.controlnetwork.surveyor.state.angledistance._IsSingleCycleCompletedState; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; + +/** + * 测角测距 + */ +public class MeasureDefaultFragment extends BaseFragment + implements IDistanceTypeChangeListener, ISurveyState, IMeasureOperate { + private MeasureAngleDistanceAdapter adapter = null; + private StateManager stateManager; + private RecyclerView recyclerView; + private ICachedData cachedData = null; + private ISurveyorData surveyedData = null; + private ISurveyState surveyState; + + private String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(KEY_STATION_ID); + } + + private String getTypeAngleOrDistance() { + if (getArguments() != null) { + return getArguments().getString(KEY_TYPE_ANGLE_OR_DISTANCE); + } + return null; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate( + R.layout.fragment_project_surveyor_station_point_list_layout, + container, + false); + String stationId = stationId(); + recyclerView = view.findViewById(R.id.recycler_view); + if (stationId != null) { + //收集信息 + collectData(stationId, + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + index -> { + if (index >= 0 && adapter != null && index < adapter.getItemCount()) { + recyclerView.scrollToPosition(index); + } + }, + new ICollectCacheCallback() { + @Override + public void onFailure() { + } + + @Override + public void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManager stateManager) { + onCollectStationData(showSlopDistance, cachedData, surveyorData, stateManager); + surveyState = stateManager; + } + } + ); + } + + return view; + } + + @WorkerThread + private void onCollectStationData( + boolean showSlopDistance, + ICachedData cachedData, + SurveyorData surveyorData, + StateManager stateManager) { + this.stateManager = stateManager; + this.cachedData = cachedData; + surveyedData = surveyorData; + + //测量数据收集完毕后,就可以更新UI了 + runOnUI(() -> { + //刷新UI + if (adapter == null) { + adapter = new MeasureAngleDistanceAdapter(stationId(), + cachedData, surveyorData, surveyorData, getTypeAngleOrDistance()); + adapter.onShowSlopDistance(showSlopDistance); + if (recyclerView != null) { + recyclerView.setAdapter(adapter); + //滚动到当前目标点 + int currentItemIndex = surveyorData.currentIndex(); + if (currentItemIndex >= 0 && currentItemIndex < adapter.getItemCount()) { + recyclerView.scrollToPosition(currentItemIndex); + } + } + } + + //监听测站数据 + //监听「平距」「斜距」切换,更新UI显示 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + surveyorStationRecord -> onShowSlopDistance(surveyorStationRecord.isShowSlopDistance())); + }); + } + + /** + * 收集测站信息 + */ + private void collectData( + String stationId, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner runner, + IScrollDelegate scrollDelegate, + ICollectCacheCallback callback) { + if (callback == null) { + return; + } + boolean isSupportAutoMode = TotalStation.getInstance().isSupportMotor(); + ThreadPoolUtil.execute(() -> { + //读取当前测站的当前测回--很重要 + SurveyorScheduleRecord scheduleRecord = + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(SurveyorScheduleConstants.getCurrentCycleKey(stationId, SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE)); + int defaultCycle = scheduleRecord == null ? 0 : + DigitalUtil.valueOfIntString(scheduleRecord.getStatue(), 0); + //加载测站信息 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + //加载对应项目 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + callback.onFailure(); + return; + } + //加载对应限差 + ToleranceDetailRecord toleranceRecord = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + if (toleranceRecord == null) { + callback.onFailure(); + return; + } + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(surveyorStationRecord.isAutoClose(), + surveyorStationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + callback.onFailure(); + return; + } + + + //是否显示斜距? + cachedData.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + if (cachedData.pointCount() <= 0) { + callback.onFailure(); + return; + } + + //创建stateManager实例 + SurveyorData surveyorDataSource = new SurveyorData(toleranceRecord.getSurveyorCount()); + surveyorDataSource.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + + //存入cacheData 用于自动测量时使用 + MeasureVm measureVm = new ViewModelProvider(requireParentFragment()).get(MeasureVm.class); + RequestSurveyorParamAuto requestSurveyorParamAuto = new RequestSurveyorParamAuto(stationId, cachedData); + measureVm.setRequestSurveyorParamAuto(requestSurveyorParamAuto); + + StateManager stateManager = StateManager.newInstance( + isSupportAutoMode, + requestSurveyorParamAuto, + surveyorStationRecord, + context, + fragmentManager, + lifecycleOwner, + toleranceRecord, + surveyorDataSource, + surveyorDataSource, + cachedData, + scrollDelegate, + runner); + //fragment创建后立即计算当前cycle的测量状态 + runner.runOnUI(() -> stateManager.calScheduleWhenEnterSurveyFragment(defaultCycle)); + callback.onSuccess(surveyorStationRecord.isShowSlopDistance(), cachedData, surveyorDataSource, stateManager); + }); + } + + @Override + public void onResume() { + super.onResume(); + if (stateManager != null) { + stateManager.resume(); + } + } + + @Override + public void onPause() { + super.onPause(); + if (stateManager != null) { + stateManager.quite(); + } + } + + public interface ICollectCacheCallback { + void onFailure(); + + void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManager stateManager); + } + + @Override + public void doSurveyor() { + if (stateManager == null) { + return; + } + stateManager.doSurveyor(); + } + + @Override + public void autoSurvey() { + if (stateManager == null) { + return; + } + stateManager.doAutoSurveyor(); + } + + @Override + public void switchCycle(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.switch2Cycle(cycleIndex); + } + + @Override + public void deleteStationAllPeroidRecord() { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(); + } + + @Override + public void deleteStationOnePeriodRecord(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(cycleIndex); + } + + @Override + public String stationCheck() { + if (stateManager == null) { + return null; + } + return stateManager.stationCheckOnly(); + } + + @Override + public void stationAdjust() { + if (stateManager == null) { + return; + } + stateManager.stationAdjustOnly(StationDataAdjustDialogFragment.TYPE_ANGLE_DISTANCE); + } + + @Override + public void goBack() { + if (stateManager == null) { + return; + } + stateManager.moveBack(); + } + + @Override + public boolean isCurrentCycleComplete() { + if (stateManager == null) + return false; + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + stateManager.getCurrentCycle(), + stateManager.getCachedData()); + return completed; + } + + @Override + public void refreshGoBackBtnEnable() { + if (stateManager == null || stateManager.getCachedData().pointCount() == 0) { + EventBus.getDefault().post(new RefreshGoBackButton(false)); + return; + } + stateManager.refreshGoBackBtnEnable(); + } + + @Override + public int measureTypePosition() { + return MeasureFragment.POSITION_DIRECTION_MEASURE; + } + + @Override + public void onShowSlopDistance(boolean value) { + if (cachedData != null) { + cachedData.onShowSlopDistance(value); + } + if (surveyedData != null) { + surveyedData.onShowSlopDistance(value); + } + if (adapter != null) { + adapter.onShowSlopDistance(value); + adapter.notifyItemRangeChanged(0, adapter.getItemCount()); + } + } + + @Override + public boolean isSurveying() { + if (surveyState != null) { + return surveyState.isSurveying(); + } + return false; + } + + @Override + public boolean isAutoSurveying() { + if (surveyState != null) { + return surveyState.isAutoSurveying(); + } + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + private static final String KEY_TYPE_ANGLE_OR_DISTANCE = "__key_type_angle_or_distance"; + public static final String TAG = ComponentStationSurveyorDataListFragment.class.getName(); + + public static MeasureDefaultFragment newInstance(String stationId, String typeAngleOrDistance) { + MeasureDefaultFragment fragment = new MeasureDefaultFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putString(KEY_TYPE_ANGLE_OR_DISTANCE, typeAngleOrDistance); + fragment.setArguments(bundle); + return fragment; + } +} + + + diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDistanceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDistanceFragment.java new file mode 100644 index 0000000..c1254a1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDistanceFragment.java @@ -0,0 +1,394 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import android.content.Context; +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.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ViewModelProvider; +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.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.RefreshGoBackButtonAloneDistance; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.IMeasureCache; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.data.SurveyorData; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlnetwork.adapter.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.alonedistance.StateManagerAloneDistance; +import com.bingce.controlnetwork.surveyor.state.alonedistance._CheckStationState; +import com.bingce.controlnetwork.surveyor.state.alonedistance._DoCalAdjustState; +import com.bingce.controlnetwork.surveyor.state.alonedistance._IsSingleCycleCompletedState; + +/** + * 单独测距 + */ +public class MeasureDistanceFragment extends BaseFragment + implements IDistanceTypeChangeListener, ISurveyState, IMeasureOperate { + + private MeasureAngleDistanceAdapter adapter = null; + private StateManagerAloneDistance stateManager; //这里的stateManager是克隆StateManager + private RecyclerView recyclerView; + private IMeasureCache cachedData = null; + private ISurveyorData surveyedData = null; + + private String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(KEY_STATION_ID); + } + + private String getWellType() { + if (getArguments() != null) { + return getArguments().getString(KEY_TYPE_ANGLE_OR_DISTANCE); + } + return null; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate( + R.layout.fragment_project_surveyor_station_point_list_layout, + container, + false); + recyclerView = view.findViewById(R.id.recycler_view); + + + collectData(stationId(), + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + index -> { + scrollToPosition(index); + }, + new ICollectCacheCallback() { + @Override + public void onFailure() { + } + + @Override + public void onSuccess(boolean showSlopDistance, IMeasureCache cachedData, SurveyorData surveyorData, StateManagerAloneDistance stateManager) { + onCollectStationData(showSlopDistance, cachedData, surveyorData, stateManager); + } + } + ); + + return view; + } + + @WorkerThread + private void onCollectStationData( + boolean showSlopDistance, + IMeasureCache cachedData, + SurveyorData surveyorData, + StateManagerAloneDistance stateManager) { + this.stateManager = stateManager; + this.cachedData = cachedData; + this.surveyedData = surveyorData; + + //测量数据收集完毕后,就可以更新UI了 + runOnUI(() -> { + //刷新UI + if (adapter == null) { + adapter = new MeasureAngleDistanceAdapter(stationId(), + cachedData, surveyorData, surveyorData, getWellType()); + adapter.onShowSlopDistance(showSlopDistance); + if (recyclerView != null) { + recyclerView.setAdapter(adapter); + //滚动到当前目标点 + int currentItemIndex = surveyorData.currentIndex(); + scrollToPosition(currentItemIndex); + } + + adapter.setOnItemClickListener(position -> { + if (isSurveying() || isAutoSurveying()) { + ToastUtils.showShort(R.string.measuring_please_waite); + return; + } + stateManager.switchCurrentMeasurePosition(position); + scrollToPosition(position); +// adapter.notifyDataSetChanged(); + }); + } + + //监听测站数据,更新界面「平距」「斜距」显示 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + surveyorStationRecord -> { + stateManager.updateStationRecord(surveyorStationRecord); + onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + }); + }); + } + + private void scrollToPosition(int position) { + if (position >= 0 && adapter != null && position < adapter.getItemCount()) { + recyclerView.scrollToPosition(position); + adapter.notifyDataSetChanged(); + } + } + + /** + * 收集测站信息 + */ + private synchronized void collectData( + String stationId, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner runner, + IScrollDelegate scrollDelegate, + ICollectCacheCallback callback) { + + boolean isSupportAutoMode = TotalStation.getInstance().isSupportMotor(); + ThreadPoolUtil.execute(() -> { + //读取当前测站的当前测回--很重要 + SurveyorScheduleRecord scheduleRecord = + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(SurveyorScheduleConstants.getCurrentCycleKey(stationId, SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE)); + int defaultCycle = scheduleRecord == null ? 0 : + DigitalUtil.valueOfIntString(scheduleRecord.getStatue(), 0); + //加载测站信息 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + //加载对应项目 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + callback.onFailure(); + return; + } + //加载对应限差 + ToleranceDetailRecord toleranceRecord = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + if (toleranceRecord == null) { + callback.onFailure(); + return; + } + //创建缓存数据 + CachedDataAloneDistance cachedData = CachedDataAloneDistance.newInstance(stationId); + //是否显示斜距? + cachedData.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + + //创建stateManager实例 + SurveyorData surveyorDataSource = new SurveyorData(ToleranceDetailRecord.ALONE_DISTANCE_MEASURE_COUNT); + surveyorDataSource.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + + StateManagerAloneDistance stateManager = StateManagerAloneDistance.newInstance( + isSupportAutoMode, + surveyorStationRecord, + context, + fragmentManager, + lifecycleOwner, + toleranceRecord, + surveyorDataSource, + surveyorDataSource, + cachedData, + createMeasureVm(), + scrollDelegate, + runner); + //fragment创建后立即计算当前cycle的测量状态 + runner.runOnUI(() -> + stateManager.calScheduleWhenEnterSurveyFragment(defaultCycle)); + callback.onSuccess(surveyorStationRecord.isShowSlopDistance(), cachedData, surveyorDataSource, stateManager); + }); + } + + public interface ICollectCacheCallback { + void onFailure(); + + void onSuccess(boolean showSlopDistance, IMeasureCache cachedData, SurveyorData surveyorData, StateManagerAloneDistance stateManager); + } + + @Override + public void doSurveyor() { + if (stateManager == null) { + return; + } + stateManager.doSurveyor(); + } + + @Override + public void autoSurvey() { + if (stateManager == null) { + return; + } + stateManager.doAutoSurveyor(); + } + + @Override + public void switchCycle(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.switch2Cycle(cycleIndex); + } + + @Override + public void deleteStationAllPeroidRecord() { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(); + } + + @Override + public void deleteStationOnePeriodRecord(int cycleIndex) { +// if (stateManager == null) { +// return; +// } +// stateManager.deleteCurrentStationSurveyorData(cycleIndex); + } + + @Override + public String stationCheck() { + if (stateManager == null) { + return null; + } + return _CheckStationState._stationCheckAloneDistance(stationId(), stateManager.getToleranceRecord(), stateManager.getCachedData()); + } + + @Override + public void stationAdjust() { + if (stateManager == null) { + return; + } + _DoCalAdjustState.doCalAdjust(stationId(), stateManager.getCachedData(), requireContext(), + getChildFragmentManager(), getViewLifecycleOwner()); +// stateManager.stationAdjust(); + } + + @Override + public void goBack() { + if (stateManager == null) { + return; + } + stateManager.moveBack(); + } + + @Override + public void onShowSlopDistance(boolean value) { + if (cachedData != null) { + cachedData.onShowSlopDistance(value); + } + if (surveyedData != null) { + surveyedData.onShowSlopDistance(value); + } + if (adapter != null) { + adapter.onShowSlopDistance(value); + adapter.notifyItemRangeChanged(0, adapter.getItemCount()); + } + } + + @Override + public boolean isSurveying() { + if (stateManager != null) { + return stateManager.isSurveying(); + } + return false; + } + + @Override + public boolean isAutoSurveying() { + if (stateManager != null) { + return stateManager.isAutoSurveying(); + } + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + private static final String KEY_TYPE_ANGLE_OR_DISTANCE = "__key_type_angle_or_distance"; + public static final String TAG = ComponentStationSurveyorDataListFragment.class.getName(); + + public static MeasureDistanceFragment newInstance(String stationId, String typeAngleOrDistance) { + MeasureDistanceFragment fragment = new MeasureDistanceFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putString(KEY_TYPE_ANGLE_OR_DISTANCE, typeAngleOrDistance); + fragment.setArguments(bundle); + return fragment; + } + + @Override + public boolean isCurrentCycleComplete() { + if (stateManager == null) + return false; + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + StateManagerAloneDistance.CYCLE_INDEX_DEFAULT, + stateManager.getCachedData(), ToleranceDetailRecord.ALONE_DISTANCE_MEASURE_COUNT); + return completed; + } + + @Override + public void refreshGoBackBtnEnable() { + if (stateManager == null || stateManager.getCachedData().pointCount() == 0) { + EventBus.getDefault().post(new RefreshGoBackButtonAloneDistance(false)); + return; + } + stateManager.refreshGoBackBtnEnable(); + } + + @Override + public int measureTypePosition() { + return MeasureFragment.POSITION_DISTANCE_MEASURE; + } + + private MeasureVm createMeasureVm() { + return new ViewModelProvider(requireParentFragment()).get(MeasureVm.class); + } + + +} + + + 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 new file mode 100644 index 0000000..53d79e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureFragment.java @@ -0,0 +1,180 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.BundleConstants; +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.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.MethodCheckSetting; +import com.bingce.controlnetwork.fragment.stationsurvey.base.MeasureBaseFragment; +import com.bingce.controlnetwork.newui.stationsetting.StationSettingsActivity; +import com.bingce.controlnetwork.surveyor.surveyor.TestDataSelectFragment; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +/** + * 测站测量页面(开始测量) + */ +public class MeasureFragment extends MeasureBaseFragment { + public static final String TAG = MeasureFragment.class.getName(); + + //方位观测fragment的在adapter的索引 + public static final int POSITION_DIRECTION_MEASURE = 0; + public static final int POSITION_DISTANCE_MEASURE = 1; + + @Override + protected boolean isShowSelectCycle(int position) { + return POSITION_DIRECTION_MEASURE == position; + } + + @Override + protected int defaultPageIndex() { + return POSITION_DIRECTION_MEASURE; + } + + @Override + protected void addFragmentsTabs(Runnable runnable) { + MeasureDefaultFragment fragmentAngle = MeasureDefaultFragment.newInstance(stationId(), MeasureAngleDistanceAdapter.TYPE_ANGLE); + fragments.add(fragmentAngle); + MeasureDistanceFragment fragmentDistance = MeasureDistanceFragment.newInstance(stationId(), MeasureAngleDistanceAdapter.TYPE_DISTANCE); + fragments.add(fragmentDistance); + + tabs.add(Tools.getString(R.string.azimuth_observation)); + tabs.add(Tools.getString(R.string.alone_measure_distance)); + runnable.run(); + } + + @Override + protected boolean isAloneDistancePage(int pageIndex) { + return POSITION_DISTANCE_MEASURE == pageIndex; + } + + @Override + protected String getCurrentPageCycleKey() { + if (mBinding.vp.getCurrentItem() == POSITION_DIRECTION_MEASURE) { + return SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null); + } else { + return SurveyorScheduleConstants.getCurrentCycleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE); + } + } + + @Override + protected String getScheduleIdForAllCycle() { + int currentItem = mBinding.vp.getCurrentItem(); + String scheduleId; + if (!isAloneDistancePage(currentItem)) { + scheduleId = SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null); + } else { + scheduleId = SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE); + } + return scheduleId; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + initObserver(); + return view; + } + + private void initObserver() { + //监听测站变化 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + stationRecord -> { + checkStationSettings(); + }); + +// SurveyorScheduleConstants.getCurrentCycleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE); + monitorCurrentCycle(SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null)); + } + + private void checkStationSettings() { + ThreadPoolUtil.execute(() -> MethodCheckSetting.checkStationSettings(stationId(), this, this::runOnUI)); + } + + @Override + public void onPrepareOptionsMenu(@NonNull Menu menu) { + super.onPrepareOptionsMenu(menu); + //删除当前测回记录 + menu.findItem(R.id.menu_item_delete_current_records).setEnabled(deleteSingleCycleEnable()); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (R.id.menu_item_delete_current_records == item.getItemId()) { + //删除当前测回记录 + if (surveyorStationRecord != null && currentFragment != null) { + //通知fragment + currentFragment.deleteStationOnePeriodRecord(cycleIndex); + } + } else if (R.id.menu_item_delete_all_records == item.getItemId()) { + //删除所有测回记录 + if (surveyorStationRecord != null && currentFragment != null) { + //通知fragment + 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使用 + TestDataSelectFragment.show(getChildFragmentManager()); + } else if (R.id.menu_item_go_back == item.getItemId() && currentFragment != null) { + //回退 + currentFragment.goBack(); + } else if (R.id.menu_item_station_environment_prism_settings == item.getItemId()) { + //环境、棱镜设置 + StationSettingsActivity.start(requireContext(), stationId()); +// StationSettingsFragment.start(getContext(), stationId()); + } else if (R.id.menu_item_surveyor_settings == item.getItemId()) { + //测量设置 设置是否显示平距 + ThreadPoolUtil.execute(() -> { + String name = StationUtil.getStationName(surveyorStationRecord); + runOnUI(() -> SurveyorSettingsFragment.start(getContext(), surveyorStationRecord.getId(), name)); + }); + } else if (R.id.menu_item_check_adjust == item.getItemId() && currentFragment != null) { + //检测平差 + stationCheckAdjustBefore(); + } + return super.onOptionsItemSelected(item); + } + + private boolean deleteSingleCycleEnable() { + return currentFragment != null && currentFragment instanceof MeasureDefaultFragment; + } + + public static void start(Context context, String surveyorStationId, String surveyorStationName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId); + FragmentContainerActivity.start(context, TAG, surveyorStationName, bundle); + } + + public static Fragment newInstance(Bundle args) { + Fragment fragment = new MeasureFragment(); + fragment.setArguments(args); + return fragment; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureVm.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureVm.java new file mode 100644 index 0000000..133f85c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureVm.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import androidx.lifecycle.ViewModel; + +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; + +public class MeasureVm extends ViewModel { + private RequestSurveyorParamAuto requestSurveyorParamAuto; + + + public RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return requestSurveyorParamAuto; + } + + public void setRequestSurveyorParamAuto(RequestSurveyorParamAuto requestSurveyorParamAuto) { + this.requestSurveyorParamAuto = requestSurveyorParamAuto; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/StationCheckBeforeUtil.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/StationCheckBeforeUtil.java new file mode 100644 index 0000000..621e2a2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/StationCheckBeforeUtil.java @@ -0,0 +1,83 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.utils.ThreadPoolUtil; + +import com.bingce.controlnetwork.R; + +public class StationCheckBeforeUtil { + + public static final int STATION_CHECK = 1; + public static final int STATION_ADJUST = 2; + + + private static final String DATA_COMPLETE_NOT = Tools.getString(R.string.station_data_is_incomplete_hint); + + /** + * @param scheduleId 进度id eg:SurveyorScheduleConstants.stationScheduleKeyForAllCycle(stationId(), null) + * @param callBack + */ + public static void stationDetectBefore(String scheduleId, ICallBack callBack) { + ThreadPoolUtil.execute(() -> { + SurveyorScheduleRecord surveyorScheduleRecord = SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(scheduleId); + ThreadPoolUtil.executeInMain(() -> { + if (surveyorScheduleRecord == null) { + callBack.error(DATA_COMPLETE_NOT); + return; + } + String statue = surveyorScheduleRecord.getStatue(); + if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(statue) + || SurveyorScheduleConstants.STATUE_VALUE_COMPLETED.equals(statue)) { + //完成测量或者经过检测后进行测站检测 + callBack.next(STATION_CHECK); + } else { + callBack.error(DATA_COMPLETE_NOT); + } + }); + }); + } + + /** + * 测站平差 + * + * @param scheduleId 进度id eg:SurveyorScheduleConstants.stationScheduleKeyForAllCycle(stationId(), null) + * @param callBack + */ + public static void stationAdjustBefore(String scheduleId, ICallBack callBack) { + ThreadPoolUtil.execute(() -> { + SurveyorScheduleRecord surveyorScheduleRecord = SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(scheduleId); + ThreadPoolUtil.executeInMain(() -> { + if (surveyorScheduleRecord == null) { + callBack.error(DATA_COMPLETE_NOT); + return; + } + String statue = surveyorScheduleRecord.getStatue(); + if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(statue)) { + //测站经过检测->测站平差 + callBack.next(STATION_ADJUST); + } else if (SurveyorScheduleConstants.STATUE_VALUE_COMPLETED.equals(statue)) { + //测站完成测量->测站检测 + callBack.next(STATION_CHECK); + } else { + callBack.error(DATA_COMPLETE_NOT); + } + }); + }); + } + + public interface ICallBack { + void next(int nextType); + + void error(String error); + } + +} 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 new file mode 100644 index 0000000..2bfc492 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/base/MeasureBaseFragment.java @@ -0,0 +1,490 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.base; + +import android.graphics.Color; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.lifecycle.Lifecycle; +import androidx.viewpager.widget.ViewPager; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.event.RefreshGoBackButtonAloneDistance; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.FragmentMeasureBinding; +import com.bingce.controlnetwork.fragment.BottomSheetSelectListFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.StationCheckBeforeUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.flyco.tablayout.SlidingTabLayout; +import com.github.razir.progressbutton.DrawableButtonExtensionsKt; +import com.github.razir.progressbutton.ProgressButtonHolderKt; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import blankj.utilcode.util.ToastUtils; + +public abstract class MeasureBaseFragment extends BaseFragment { + private boolean menuItemRollBackEnable; + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onRefreshGoBack(RefreshGoBackButton event) { + if (mBinding != null) { + int currentItem = mBinding.vp.getCurrentItem(); + if (!isAloneDistancePage(currentItem)) { + menuItemRollBackEnable = event.validate; + } + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onRefreshGoBack(RefreshGoBackButtonAloneDistance event) { + if (mBinding != null) { + int currentItem = mBinding.vp.getCurrentItem(); + if (isAloneDistancePage(currentItem)) { + menuItemRollBackEnable = event.validate; + } + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onSurveyorStateChanged(SurveyStateEvent event) { + if (isInValidEventPosition(event.getPosition())) + return; + + if (event.isIdle() || event.isSuccess() || event.isCompleted()) { + DrawableButtonExtensionsKt.hideProgress(mBinding.surveyor, R.string.start_surveyor); + } else if (event.isSurveying()) { + DrawableButtonExtensionsKt.showProgress(mBinding.surveyor, progressParams -> { + progressParams.setButtonTextRes(R.string.tips_surveying); + progressParams.setProgressColor(Color.WHITE); + return null; + }); + } else if (event.isFailure()) { + DrawableButtonExtensionsKt.hideProgress(mBinding.surveyor, R.string.tips_surveyor_failure_and_retry); + } + + boolean enable = event.isIdle() || event.isFailure() || event.isSuccess(); + setSurveyorEnable(mBinding.surveyor, enable); + setSurveyorEnable(mBinding.autoSurveyor, enable); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onAutoSurveyorChanged(AutoSurveyorButtonVisibleEvent event) { + if (isInValidEventPosition(event.getPosition())) + return; + mBinding.autoSurveyor.setVisibility(event.isReadyAutoSurvey() ? View.VISIBLE : View.GONE); + } + + protected FragmentMeasureBinding mBinding; + + protected IMeasureOperate currentFragment; + + protected SurveyorStationRecord surveyorStationRecord; + protected int cycleIndex = 0; + protected ArrayList cycleList; + + protected abstract boolean isShowSelectCycle(int position); + + protected abstract int defaultPageIndex(); + + protected abstract void addFragmentsTabs(Runnable runnable); + + protected abstract boolean isAloneDistancePage(int pageIndex); + + protected abstract String getCurrentPageCycleKey(); + + protected abstract String getScheduleIdForAllCycle(); + + protected void setSurveyorEnable(View view, boolean enable) { + if (view != null) { + view.setEnabled(enable); + if (enable) { + view.setAlpha(1); + } else { + view.setAlpha(.4f); + } + } + } + + protected List fragments = new ArrayList<>(); + protected List tabs = new ArrayList<>(); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + setHasOptionsMenu(true); + EventBus.getDefault().register(this); + mBinding = FragmentMeasureBinding.inflate(inflater, container, false); + //设置测量按钮 + ProgressButtonHolderKt.bindProgressButton(getViewLifecycleOwner(), mBinding.surveyor); + initClickListener(); + return mBinding.getRoot(); + } + + @Override + public void onResume() { + super.onResume(); + //测量界面保持常亮 + if (getActivity() != null) { + getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + @Override + public void onPause() { + super.onPause(); + //关闭测量界面保持常亮 + if (getActivity() != null) { + getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initStation(); + initView(); + initViewPager(view); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + EventBus.getDefault().unregister(this); + } + + @Override + public void onCreateOptionsMenu(@NonNull @NotNull Menu menu, @NonNull @NotNull MenuInflater inflater) { + if (Test.DEBUG) { + inflater.inflate(R.menu.menu_surveyor_station_record_data_edit_debug, menu); + } else { + inflater.inflate(R.menu.menu_surveyor_station_record_data_edit_release, menu); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public void onPrepareOptionsMenu(@NonNull Menu menu) { + super.onPrepareOptionsMenu(menu); + menu.findItem(R.id.menu_item_go_back).setEnabled(menuItemRollBackEnable); + } + + private void initClickListener() { + mBinding.surveyor.setOnClickListener(view -> { + goSurvey(); + }); + mBinding.autoSurveyor.setOnClickListener(view -> { + goAutoSurvey(); + }); + + //测回点击 + mBinding.cycleLayout.setOnClickListener(view -> { + if (cycleList == null || cycleList.isEmpty()) { + ToastUtils.showShort(R.string.cycle_data_abnormal_toast); + return; + } + BottomSheetSelectListFragment.showSelect( + getChildFragmentManager(), + getViewLifecycleOwner(), + cycleIndex, + cycleList, + null,//不再限制测期 + (index, string) -> { + mBinding.circleText.setText(string); + cycleIndex = index; + refreshCycleForFragment(); + }); + } + ); + } + + private void refreshCycleForFragment() { + if (currentFragment != null) { + //检测当前测回是否完成 + currentFragment.switchCycle(cycleIndex); + } + } + + protected String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(BundleConstants.KEY_SURVEYOR_STATION_ID); + } + + private void initStation() { + ThreadPoolUtil.execute(() -> { + surveyorStationRecord = SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId()); + //监听数据变化 + ToleranceDetailRecord toleranceRecord = getTolerance(surveyorStationRecord); + if (toleranceRecord == null) { + return; + } + AtomicInteger cycleCount = new AtomicInteger(toleranceRecord.getCycleCount()); + cycleList = SurveyorCycleUtil.cycleStrings(cycleCount.get(), + surveyorStationRecord != null && surveyorStationRecord.leftAndRightSurveyor); + + }); + } + + protected void initView() { + + } + + private void initViewPager(View view) { + fragments = new ArrayList<>(); + addFragmentsTabs(() -> { + mBinding.tabLayout.setVisibility(fragments.size() == 1 ? View.GONE : View.VISIBLE); + + mBinding.cycleLayout.setVisibility(isShowSelectCycle(mBinding.vp.getCurrentItem()) ? View.VISIBLE : View.GONE); + + SlidingTabLayout tabLayout = view.findViewById(R.id.tabLayout); + mBinding.vp.setAdapter(new MyPagerAdapter(getChildFragmentManager())); + tabLayout.setViewPager(mBinding.vp); + + mBinding.vp.setCurrentItem(defaultPageIndex()); + currentFragment = fragments.get(defaultPageIndex()); + + mBinding.vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + currentFragment = fragments.get(position); + View pick = view.findViewById(R.id.cycleLayout); +// //是否显示选择测期 + pick.setVisibility(isShowSelectCycle(position) ? View.VISIBLE : View.GONE); + //刷新测量按钮状态 + boolean currentCycleComplete = currentFragment.isCurrentCycleComplete(); + if (currentCycleComplete) { + SurveyStateEvent.postCompleted(position); + } else { + SurveyStateEvent.postIdle(position); + } + + //切换tab测回可能会变刷新当前fragment + refreshCycleAndFragment(); + + currentFragment.refreshGoBackBtnEnable(); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + }); + } + + private void refreshCycleAndFragment() { + ThreadPoolUtil.execute(() -> { + SurveyorScheduleRecord record = SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(getCurrentPageCycleKey()); + + if (record != null) { + refreshCycleUi(record); + refreshCycleForFragment(); + } + }); + } + + protected void monitorCurrentCycle(String currentCycleKey) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findSchedule(currentCycleKey) + .observe(getViewLifecycleOwner(), record -> { + if (!currentCycleKey.equals(getCurrentPageCycleKey())) { + return; + } + refreshCycleUi(record); + }); + } + + private void refreshCycleUi(SurveyorScheduleRecord record) { + int cycleIndex = DigitalUtil.valueOfIntString(record == null ? "0" : record.getStatue(), 0); + //更新测回名称 + boolean showLeftOrRight = true; + if (surveyorStationRecord != null) { + showLeftOrRight = surveyorStationRecord.leftAndRightSurveyor; + } + mBinding.circleText.setText(SurveyorCycleUtil.cycleName(cycleIndex, showLeftOrRight)); + this.cycleIndex = cycleIndex; + } + + + @WorkerThread + private static ToleranceDetailRecord getTolerance(SurveyorStationRecord surveyorStationRecord) { + if (surveyorStationRecord == null) { + return null; + } + //获取project信息 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + return null; + } + //获取限差数据 + return SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + } + + private void goSurvey() { + if (currentFragment != null) { + currentFragment.doSurveyor(); + } + } + + private void goAutoSurvey() { + if (currentFragment != null) { + currentFragment.autoSurvey(); + } + } + + private class MyPagerAdapter extends FragmentPagerAdapter { + public MyPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public int getCount() { + return fragments.size(); + } + + @Override + public CharSequence getPageTitle(int position) { + return tabs.get(position); + } + + @Override + public Fragment getItem(int position) { + return (Fragment) fragments.get(position); + } + } + + protected void stationCheckAdjustBefore() { + StationCheckBeforeUtil.stationAdjustBefore(getScheduleIdForAllCycle(), new StationCheckBeforeUtil.ICallBack() { + + @Override + public void next(int nextType) { + if (currentFragment != null) { + if (nextType == StationCheckBeforeUtil.STATION_ADJUST) { + currentFragment.stationAdjust(); + } else if (nextType == StationCheckBeforeUtil.STATION_CHECK) { + //已经完成测量,开始测站检测 + String error = currentFragment.stationCheck(); + if (TextUtils.isEmpty(error)) { + currentFragment.stationAdjust(); + } else { + TipsFragment.cancelAbleTips(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + error + Tools.getString(R.string.is_adjustment_forced), 0, () -> { + currentFragment.stationAdjust(); + }); + } + } + } + } + + @Override + public void error(String error) { + tipsError(error); + } + }); + + } + + protected void stationCheckBefore() { + StationCheckBeforeUtil.stationDetectBefore(getScheduleIdForAllCycle(), new StationCheckBeforeUtil.ICallBack() { + @Override + public void next(int nextType) { + if (currentFragment != null) { + String error = currentFragment.stationCheck(); + if (TextUtils.isEmpty(error)) { + if (isVisiable()) { + TipsFragment.cancelAbleTips(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + Tools.getString(R.string.station_passed_is_adjust), 0, + () -> currentFragment.stationAdjust()); + } + } else { + tipsError(error); + } + } + } + + @Override + public void error(String error) { + tipsError(error); + } + }); + } + + private void tipsError(String error) { + if (isVisiable() && !TextUtils.isEmpty(error)) { + TipsFragment.tipsOnly(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), error); + } + } + + private boolean isVisiable() { + return getViewLifecycleOwner().getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED); + } + + private int getCurrentPageTypePosition() { + return fragments.get(mBinding.vp.getCurrentItem()).measureTypePosition(); + } + + /** + * 是否是无效的点 + * + * @param position + * @return + */ + private boolean isInValidEventPosition(int position) { + return mBinding == null || position != getCurrentPageTypePosition(); + } +} 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 new file mode 100644 index 0000000..93a0ee1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseFragment.kt @@ -0,0 +1,230 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse + +import android.content.Context +import android.os.Bundle +import android.view.MenuItem +import android.view.View +import androidx.fragment.app.Fragment +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.StationLayout +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.StationUtil.getStationName +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.stationsurvey.base.MeasureBaseFragment +import com.bingce.controlnetwork.newui.stationsettingheighttraverse.StationSettingsHeightTraverseActivity +import com.bingce.controlnetwork.surveyor.state.heighttraverse.__BaseState +import com.bingce.controlnetwork.surveyor.surveyor.TestDataSelectFragment +import com.bingce.utils.ThreadPoolUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class MeasureHeightTraverseFragment : MeasureBaseFragment() { + + private val mainScope = MainScope() + + companion object { + const val POSITION_BACK_PAGE = 0 + const val POSITION_FRONT_PAGE = 1 + + @JvmField + val TAG: String = MeasureHeightTraverseFragment::class.java.name + + @JvmStatic + fun start(context: Context, surveyorStationId: String, surveyorStationName: String?) { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId) + FragmentContainerActivity.start( + context, + TAG, + surveyorStationName, + bundle + ) + } + + @JvmStatic + fun newInstance(args: Bundle?): Fragment { + val fragment: Fragment = MeasureHeightTraverseFragment() + fragment.arguments = args + return fragment + } + } + + override fun isShowSelectCycle(position: Int): Boolean { + return false + } + + override fun defaultPageIndex(): Int { + return POSITION_BACK_PAGE + } + + override fun initView() { + super.initView() + setSurveyorEnable(mBinding.surveyor, false) + } + + override fun addFragmentsTabs(runnable: Runnable) { + mainScope.launch(Dispatchers.IO) { + val stationId = stationId() + + val stationRecord = + SurveyorDatabaseFactory.instance.surveyorStation.getRecordSync(stationId) + val configRecord = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + .getRecordByProjectId(stationRecord.getProjectId()) + + if (configRecord?.stationLayout == StationLayout.SEPARATE) { + fragments.add( + MeasureHeightTraverseSubFragment.newInstance( + stationId, + POSITION_BACK_PAGE + ) + ) + fragments.add( + 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 + ) + ) + tabs.add(Tools.getString(R.string.forward_view)) + } + withContext(Dispatchers.Main) { + runnable.run() + } + } + } + + override fun isAloneDistancePage(pageIndex: Int): Boolean { + return false + } + + override fun getCurrentPageCycleKey(): String { + return SurveyorScheduleConstants.getCurrentCycleKey( + stationId(), + __BaseState.getScheduleKey(mBinding.vp.currentItem) + ) + } + + override fun getScheduleIdForAllCycle(): String { + val positionFragment = getCurrentMeasurePos() + return SurveyorScheduleConstants.getAllCycleScheduleKey( + 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 + ) + ) + monitorCurrentCycle( + SurveyorScheduleConstants.getCurrentCycleKey( + stationId(), + SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_FRONT + ) + ) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.menu_item_delete_current_records == item.itemId) { + //删除当前测回记录 + if (surveyorStationRecord != null && currentFragment != null) { + //通知fragment + currentFragment.deleteStationOnePeriodRecord(getCurrentMeasurePos()) + } + } else if (R.id.menu_item_delete_all_records == item.itemId) { + //删除所有测回记录 + showDeleteStationRecord() + } else if (R.id.menu_item_station_check == item.itemId && currentFragment != null) { + //测站检测 + stationCheckBefore() + } else if (R.id.menu_item_data_source == item.itemId) { + //数据源 debug使用 + TestDataSelectFragment.show(childFragmentManager) + } else if (R.id.menu_item_go_back == item.itemId && currentFragment != null) { + //回退 + currentFragment.goBack() + } else if (R.id.menu_item_station_environment_prism_settings == item.itemId) { + //环境、棱镜设置 +// StationSettingHeightTraverseFragment.start(requireContext(), stationId()) + StationSettingsHeightTraverseActivity.start(requireContext(), stationId()) + } else if (R.id.menu_item_surveyor_settings == item.itemId) { + //测量设置 设置是否显示平距 + ThreadPoolUtil.execute { + val name = getStationName(surveyorStationRecord) + runOnUI { + SurveyorSettingsFragment.start( + context, + surveyorStationRecord.getId(), + name + ) + } + } + } 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 new file mode 100644 index 0000000..89d7499 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseSubFragment.java @@ -0,0 +1,415 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse; + +import android.content.Context; +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.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ViewModelProvider; +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.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataHeightTraverse; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.data.SurveyorData; +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; +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; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +/** + * 测角测距 + */ +public class MeasureHeightTraverseSubFragment extends BaseLazyFragment + implements IDistanceTypeChangeListener, ISurveyState, IMeasureOperate { + private MeasureHeightTraverseAdapter adapter = null; + private StateManagerHeightTraverse stateManager; + private RecyclerView recyclerView; + private ICachedData cachedData = null; + private ISurveyorData surveyedData = null; + private ISurveyState surveyState; + + private String stationId() { + if (getArguments() == null) { + throw new RuntimeException("getArguments()==null"); + } + return getArguments().getString(KEY_STATION_ID); + } + + public int getBackOrFrontPosition() { + if (getArguments() == null) { + throw new RuntimeException("getArguments()==null"); + } + return getArguments().getInt(KEY_TYPE_BACK_OR_FRONT); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate( + R.layout.fragment_project_surveyor_station_point_list_layout, + container, + false); + recyclerView = view.findViewById(R.id.recycler_view); + return view; + } + + @WorkerThread + private void onCollectStationData( + boolean showSlopDistance, + ICachedData cachedData, + SurveyorData surveyorData, + StateManagerHeightTraverse stateManager) { + this.stateManager = stateManager; + this.cachedData = cachedData; + surveyedData = surveyorData; + + //测量数据收集完毕后,就可以更新UI了 + runOnUI(() -> { + //刷新UI + if (adapter == null) { + adapter = new MeasureHeightTraverseAdapter(stationId(), + cachedData, surveyorData, surveyorData, getBackOrFrontPosition()); + adapter.onShowSlopDistance(showSlopDistance); + if (recyclerView != null) { + recyclerView.setAdapter(adapter); + //滚动到当前目标点 + int currentItemIndex = surveyorData.currentIndex(); + if (currentItemIndex >= 0 && currentItemIndex < adapter.getItemCount()) { + recyclerView.scrollToPosition(currentItemIndex); + } + } + } + + //监听测站数据 + //监听「平距」「斜距」切换,更新UI显示 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + surveyorStationRecord -> onShowSlopDistance(surveyorStationRecord.isShowSlopDistance())); + }); + } + + /** + * 收集测站信息 + */ + private void collectData( + String stationId, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner runner, + IScrollDelegate scrollDelegate, + ICollectCacheCallback callback) { + if (callback == null) { + return; + } + boolean isSupportAutoMode = TotalStation.getInstance().isSupportMotor(); + ThreadPoolUtil.execute(() -> { + //加载测站信息 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + //加载对应项目 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + callback.onFailure(); + return; + } + //加载对应限差 + ToleranceDetailRecord toleranceRecord = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + if (toleranceRecord == null) { + callback.onFailure(); + return; + } + //创建缓存数据 + CachedDataHeightTraverse cachedData = + CachedDataHeightTraverse.newInstance(getBackOrFrontPosition(), + stationId, toleranceRecord); + if (cachedData == null) { + callback.onFailure(); + return; + } + + //是否显示斜距? + cachedData.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + if (cachedData.pointCount() <= 0) { + callback.onFailure(); + return; + } + + //创建stateManager实例 + SurveyorData surveyorDataSource = new SurveyorData(toleranceRecord.getSurveyorCount()); + surveyorDataSource.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + + //存入cacheData 用于自动测量时使用 + MeasureVm measureVm = new ViewModelProvider(requireParentFragment()).get(MeasureVm.class); + RequestSurveyorParamAuto requestSurveyorParamAuto = new RequestSurveyorParamAuto(stationId, cachedData); + measureVm.setRequestSurveyorParamAuto(requestSurveyorParamAuto); + + StateManagerHeightTraverse stateManager = StateManagerHeightTraverse.newInstance( + getBackOrFrontPosition(), + isSupportAutoMode, + requestSurveyorParamAuto, + surveyorStationRecord, + context, + fragmentManager, + lifecycleOwner, + toleranceRecord, + surveyorDataSource, + surveyorDataSource, + cachedData, + scrollDelegate, + runner); + //fragment创建后立即计算当前cycle的测量状态 + runner.runOnUI(() -> stateManager.calScheduleWhenEnterSurveyFragment(0)); + callback.onSuccess(surveyorStationRecord.isShowSlopDistance(), cachedData, surveyorDataSource, stateManager); + }); + } + + @Override + public void onResume() { + super.onResume(); + if (stateManager != null) { + stateManager.resume(); + } + } + + @Override + public void onPause() { + super.onPause(); + if (stateManager != null) { + stateManager.quite(); + } + } + + @Override + protected void loadData() { + String stationId = stationId(); + if (stationId != null) { + //收集信息 + collectData(stationId, + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + index -> { + if (index >= 0 && adapter != null && index < adapter.getItemCount()) { + recyclerView.scrollToPosition(index); + } + }, + new ICollectCacheCallback() { + @Override + public void onFailure() { + } + + @Override + public void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManagerHeightTraverse stateManager) { + onCollectStationData(showSlopDistance, cachedData, surveyorData, stateManager); + surveyState = stateManager; + } + } + ); + } + } + + public interface ICollectCacheCallback { + void onFailure(); + + void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManagerHeightTraverse stateManager); + } + + @Override + public void doSurveyor() { + if (stateManager == null) { + return; + } + stateManager.doSurveyor(); + } + + @Override + public void autoSurvey() { + if (stateManager == null) { + return; + } + stateManager.doAutoSurveyor(); + } + + @Override + public void switchCycle(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.switch2Cycle(cycleIndex); + } + + @Override + public void deleteStationAllPeroidRecord() { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(); + } + + @Override + public void deleteStationOnePeriodRecord(int positionFragment) { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(positionFragment); + } + + @Override + public String stationCheck() { + if (stateManager == null) { + return null; + } + return stateManager.stationCheckOnly(); + } + + @Override + public void stationAdjust() { + if (stateManager == null) { + return; + } + stateManager.stationAdjustOnly(StationDataAdjustDialogFragment.TYPE_ANGLE_VER_AND_DISTANCE); + } + + @Override + public void goBack() { + if (stateManager == null) { + return; + } + stateManager.moveBack(); + } + + /** + * 对于高程导线来说 这个方法实现当前目标的所有测回是否完成 + * + * @return + */ + @Override + public boolean isCurrentCycleComplete() { + if (stateManager == null || cachedData == null || cachedData.pointCount() == 0) + return false; + for (int i = 0; i < cachedData.pointCount(); i++) { + String pointId = cachedData.pointId(i, i); + String recordIdLeft = IdUtil.createSurveyorRecordId(stationId(), i, pointId, LeftOrRight.left); + String recordIdRight = IdUtil.createSurveyorRecordId(stationId(), i, pointId, LeftOrRight.right); + DataCategory dataCategoryLeft = cachedData.valueState(recordIdLeft); + DataCategory dataCategoryRight = cachedData.valueState(recordIdRight); + if (dataCategoryLeft.isEmptyData() || dataCategoryRight.isEmptyData()) { + //只要有空数据就是未完成 + return false; + } + } + return true; + } + + @Override + public void refreshGoBackBtnEnable() { + if (stateManager == null || stateManager.getCachedData().pointCount() == 0) { + EventBus.getDefault().post(new RefreshGoBackButton(false)); + return; + } + stateManager.refreshGoBackBtnEnable(); + } + + @Override + public int measureTypePosition() { + return getBackOrFrontPosition(); + } + + @Override + public void onShowSlopDistance(boolean value) { + if (cachedData != null) { + cachedData.onShowSlopDistance(value); + } + if (surveyedData != null) { + surveyedData.onShowSlopDistance(value); + } + if (adapter != null) { + adapter.onShowSlopDistance(value); + adapter.notifyItemRangeChanged(0, adapter.getItemCount()); + } + } + + @Override + public boolean isSurveying() { + if (surveyState != null) { + return surveyState.isSurveying(); + } + return false; + } + + @Override + public boolean isAutoSurveying() { + if (surveyState != null) { + return surveyState.isAutoSurveying(); + } + 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(); + + public static MeasureHeightTraverseSubFragment newInstance(String stationId, int frontOrBack) { + MeasureHeightTraverseSubFragment fragment = new MeasureHeightTraverseSubFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putInt(KEY_TYPE_BACK_OR_FRONT, frontOrBack); + fragment.setArguments(bundle); + return fragment; + } +} + + + 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..5b84f2e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelConstant.kt @@ -0,0 +1,13 @@ +package com.bingce.controlnetwork.func.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..4e58355 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportIDetection.kt @@ -0,0 +1,231 @@ +package com.bingce.controlnetwork.func.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..b4e3056 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportSingalHeight.kt @@ -0,0 +1,220 @@ +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 = LevelingDbFactory.instance.levelDataSource.getByProjectIdSync(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..0c69b8c --- /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 com.bingce.controlnetwork.func.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..2fd7761 --- /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.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.controlnetwork.surveyor.method.ExportUtilsPla; +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 (ExportUtilsPla.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(), ExportUtilsPla.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..1ea0265 --- /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 com.bingce.controlnetwork.func.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..25e9937 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectDetailLevelFragment.java @@ -0,0 +1,163 @@ +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, projectType, getContext())); + } + + private void initKnownPoint(View known) { + ViewUtil.setOnClick( + known, + v -> PointListFragment.go2KnownPointList(projectId, projectType, 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()) { + //i角检测 + 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/func/level/fragment/SelectLevelNextStationTypeFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/SelectLevelNextStationTypeFragment.java new file mode 100644 index 0000000..731d225 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/SelectLevelNextStationTypeFragment.java @@ -0,0 +1,95 @@ +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.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.fragment.SelectProjectAndSurveyorCycleFragment; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import com.bingce.controlnetwork.R; + +/** + * 水准选择下一站观测方式 + */ +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_level_next_station_type, + container, + false); + initClickListener(view); + return view; + } + + 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()); + } + + 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) { + View view = root.findViewById(id); + if (view != null) { + view.setOnClickListener(onClickListener); + } + } + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + IOnSelectCallback callback) { + SelectLevelNextStationTypeFragment fragment = new SelectLevelNextStationTypeFragment(); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected(result.getString(KEY_TYPE)); + } + }); + fragment.show(fragmentManager, TAG); + } + + @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 IOnSelectCallback { + void onSurveyorCycleSelected(String type); + } +} \ No newline at end of file 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..3829c29 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionRecordActivity.kt @@ -0,0 +1,381 @@ +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 androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +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.func.level.idetection.viewmodel.LevelIDetectionRecordVm +import com.bingce.controlnetwork.func.level.sendreceive.ILevelBackData +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequest +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequestRelease +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import com.bingce.controlnetwork.newui.widget.selectitem.BaseSelectItemFragment +import com.bingce.controlnetwork.newui.widget.selectitem.SelectIDetectionStationFragment +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 kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +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 + } + + lifecycleScope.launch { + withContext(Dispatchers.IO) { + //存短长距和测量方式 + viewModel.saveShortLongDistanceMeasureType(d1String, d2String) + } + + //计算结果 + val result = viewModel.startResult(getD(d1String), getD(d2String)) + if (!TextUtils.isEmpty(result)) { + DialogUtil.showAlertDialog( + this@LevelIDetectionRecordActivity, + supportFragmentManager, + this@LevelIDetectionRecordActivity, + 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..6076926 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionRecordVm.kt @@ -0,0 +1,359 @@ +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.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 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 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) { + 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..a8bc98e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequest.kt @@ -0,0 +1,84 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import blankj.utilcode.util.ToastUtils +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..5040e5b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestRelease.kt @@ -0,0 +1,58 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +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..a4eec44 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestState.kt @@ -0,0 +1,8 @@ +package com.bingce.controlnetwork.func.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..61620c2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelExportUtilTj.kt @@ -0,0 +1,708 @@ +package com.bingce.controlnetwork.func.level.util + +import android.text.TextUtils +import androidx.annotation.WorkerThread +import blankj.utilcode.util.Utils + +import com.bingce.controlnetwork.func.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) { + if (item.stationId==null) { + continue + } + val station = + LevelingDbFactory.instance.stationDataSource.getRecordSync(item.stationId) + ?: continue + 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/guide/GuideSequence.java b/app/src/main/java/com/bingce/controlnetwork/guide/GuideSequence.java new file mode 100644 index 0000000..239e38f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/guide/GuideSequence.java @@ -0,0 +1,110 @@ +package com.bingce.controlnetwork.guide; + +import android.app.Activity; +import android.app.Dialog; +import android.view.View; + +import androidx.appcompat.widget.Toolbar; + +import com.getkeepsafe.taptargetview.TapTarget; +import com.getkeepsafe.taptargetview.TapTargetView; + +public class GuideSequence implements ITapTargetProvider { + private int currentIndex = 0; + private final int targetCount; + private final IDelegate delegate; + private final TapTargetView.Listener listener = new TapTargetView.Listener() { +// @Override +// public void onTargetClick(TapTargetView view) { +// super.onTargetClick(view); +// } + + @Override + public void onTargetDismissed(TapTargetView view, boolean userInitiated) { + super.onTargetDismissed(view, userInitiated); + //下一个 + delegate.dismiss(currentIndex); + currentIndex++; + if (currentIndex >= targetCount) { + return; + } + delegate.show(currentIndex, GuideSequence.this); + } + +// @Override +// public void onTargetCancel(TapTargetView view) { +// super.onTargetCancel(view); +// } +// +// @Override +// public void onTargetLongClick(TapTargetView view) { +// super.onTargetLongClick(view); +// } + +// @Override +// public void onOuterCircleClick(TapTargetView view) { +// super.onOuterCircleClick(view); +// } + }; + + public GuideSequence(int targetCount, final IDelegate delegate) { + this.targetCount = targetCount; + this.delegate = delegate; + } + + public void start(int index) { + if (index < 0) { + return; + } + currentIndex = index; + delegate.show(currentIndex, this); + } + + @Override + public void show4View(Activity activity, View target, String msg, String describe) { + if (activity.isFinishing()) { + return; + } + if (activity.isDestroyed()) { + return; + } + TapTargetView.showFor( + activity, + TapTarget.forView(target, msg, describe).transparentTarget(true), + listener + ); + } + + @Override + public void show4View(Dialog dialog, View target, String msg, String describe) { + if (!dialog.isShowing()) { + return; + } + TapTargetView.showFor( + dialog, + TapTarget.forView(target, msg, describe).transparentTarget(true), + listener + ); + } + + @Override + public void show4ToolbarMenu(Activity activity, Toolbar toolbar, int menuItem, String msg, String describe) { + if (activity.isFinishing()) { + return; + } + if (activity.isDestroyed()) { + return; + } + TapTargetView.showFor( + activity, + TapTarget.forToolbarMenuItem(toolbar, menuItem, msg, describe).transparentTarget(true), + listener + ); + } + + public interface IDelegate { + void show(int index, ITapTargetProvider provider); + + void dismiss(int index); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/guide/ITapTargetProvider.java b/app/src/main/java/com/bingce/controlnetwork/guide/ITapTargetProvider.java new file mode 100644 index 0000000..fe4f127 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/guide/ITapTargetProvider.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.guide; + +import android.app.Activity; +import android.app.Dialog; +import android.view.View; + +import androidx.appcompat.widget.Toolbar; + +public interface ITapTargetProvider { + void show4View(Activity activity, View target, String msg, String describe); + + void show4View(Dialog dialog, View target, String msg, String describe); + + void show4ToolbarMenu(Activity activity, Toolbar toolbar, int menuItem, String msg, String describe); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/http/HttpExtend.kt b/app/src/main/java/com/bingce/controlnetwork/http/HttpExtend.kt new file mode 100644 index 0000000..ccee6b3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/http/HttpExtend.kt @@ -0,0 +1,54 @@ +package com.bingce.controlnetwork.http + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +fun CoroutineScope.retrofit(dsl: RetrofitDSL.() -> Unit) { + launch(Dispatchers.IO) { + val retrofitDsl = RetrofitDSL() + retrofitDsl.dsl() + try { + val result = retrofitDsl.api() ?: throw NullPointerException() + retrofitDsl.onSuccess?.invoke(result) + } catch (e: NullPointerException) { + retrofitDsl.onFailed?.invoke(e.message, -1) + } catch (e: Exception) { + retrofitDsl.onFailed?.invoke(e.message, -100) + } + } +} + +class RetrofitDSL { + internal lateinit var api: (suspend () -> T) + private set + internal var onSuccess: ((T) -> Unit)? = null + private set + internal var onFailed: ((msg: String?, code: Int) -> Unit)? = null + private set + + /** + * 获取数据 + * @param block (T) -> Unit + */ + fun api(block: suspend () -> T) { + this.api = block + } + + /** + * 获取数据成功 + * @param block (T) -> Unit + */ + fun onSuccess(block: (T) -> Unit) { + this.onSuccess = block + } + + /** + * 获取数据失败 + * @param block (msg: String, errorCode: Int) -> Unit + */ + fun onFailed(block: (msg: String?, code: Int) -> Unit) { + this.onFailed = block + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/http/RetrofitClient.kt b/app/src/main/java/com/bingce/controlnetwork/http/RetrofitClient.kt new file mode 100644 index 0000000..e1149cc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/http/RetrofitClient.kt @@ -0,0 +1,142 @@ +package com.bingce.controlnetwork.http + +import android.util.Log +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.util.GsonUtil +import com.bingce.controlnetwork.BuildConfig +import com.google.gson.JsonParseException +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import okhttp3.Interceptor +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.OkHttpClient +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.logging.HttpLoggingInterceptor +import org.apache.http.conn.ConnectTimeoutException +import org.json.JSONException +import retrofit2.HttpException +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.io.IOException +import java.net.SocketTimeoutException +import java.net.UnknownHostException +import java.util.concurrent.TimeUnit + +object RetrofitClient { + //根路径 + private const val BASE_URL = "https://www.wanandroid.com/" + + private val mMediaTypeJson = "application/json; charset=utf-8".toMediaTypeOrNull() + + private val retrofit = Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .client(initOkhttpClient()) + .build() + + + private fun initOkhttpClient(): OkHttpClient { + return OkHttpClient.Builder() + .retryOnConnectionFailure(true) //重试 + .connectTimeout(20, TimeUnit.SECONDS) + .readTimeout(20, TimeUnit.SECONDS) + .writeTimeout(20, TimeUnit.SECONDS) +// .addNetworkInterceptor(initTokenInterceptor()) + .addInterceptor(initLogInterceptor()) + .build() + } + + private fun initTokenInterceptor(): Interceptor = Interceptor { chain -> // 为请求添加 Token + val token: String? = null + val originalRequest = chain.request() + if (token.isNullOrEmpty()) { + chain.proceed(originalRequest) + } else { + val updateRequest = originalRequest.newBuilder().header("token", token).build() + chain.proceed(updateRequest) + } + } + + + /* + * 日志拦截器 + * */ + private fun initLogInterceptor(): HttpLoggingInterceptor { + if (!BuildConfig.DEBUG) { //生产环境不打日志 + return HttpLoggingInterceptor() + } + + val interceptor = HttpLoggingInterceptor { message -> Log.d("OkhttpClient", message) } + interceptor.level = HttpLoggingInterceptor.Level.BODY + return interceptor + } + + // 请求数据转 Json 形式; + open fun getJsonBody(data: Any): RequestBody { + val strEntity = GsonUtil.toJson(data) + return strEntity.toRequestBody(mMediaTypeJson) + } + + fun create(serviceClass: Class): T = retrofit.create(serviceClass) + + inline fun createService(): T = create(T::class.java) + + + suspend inline fun apiCall(crossinline call: suspend CoroutineScope.() -> T): T? { + return withContext(Dispatchers.IO) { + var res: T? = null + try { + res = call() + } catch (e: Throwable) { + Log.e("ApiCaller", "request error", e) + // 请求出错,将状态码和消息封装为 ResponseResult +// return@withContext ApiException.build(e).toResponse() + ToastUtils.showShort(ApiException.build(e).toString()) + } + return@withContext res + } + } + + // 网络、数据解析错误处理 + class ApiException(val code: Int, override val message: String?, override val cause: Throwable? = null) : + RuntimeException(message, cause) { + companion object { + // 网络状态码 + const val CODE_NET_ERROR = 4000 + const val CODE_TIMEOUT = 4080 + const val CODE_JSON_PARSE_ERROR = 4010 + const val CODE_SERVER_ERROR = 5000 + + // 业务状态码 + const val CODE_AUTH_INVALID = 401 + + fun build(e: Throwable): ApiException { + return if (e is HttpException) { + ApiException(CODE_NET_ERROR, "网络异常(${e.code()},${e.message()})") + } else if (e is UnknownHostException) { + ApiException(CODE_NET_ERROR, "网络连接失败,请检查后再试") + } else if (e is ConnectTimeoutException || e is SocketTimeoutException) { + ApiException(CODE_TIMEOUT, "请求超时,请稍后再试") + } else if (e is IOException) { + ApiException(CODE_NET_ERROR, "网络异常(${e.message})") + } else if (e is JsonParseException || e is JSONException) { + // Json解析失败 + ApiException(CODE_JSON_PARSE_ERROR, "数据解析错误,请稍后再试") + } else { + ApiException(CODE_SERVER_ERROR, "系统错误(${e.message})") + } + } + } + +// fun toResponse(): ResponseResult { +// return ResponseResult(code, message) +// } + + override + fun toString(): String { + return "code:$code,message:$message" + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/http/sevice/CommonService.kt b/app/src/main/java/com/bingce/controlnetwork/http/sevice/CommonService.kt new file mode 100644 index 0000000..71c7c0b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/http/sevice/CommonService.kt @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.http.sevice + +import com.google.gson.JsonObject +import retrofit2.http.GET + +interface CommonService { + @GET("article/list/0/json") + suspend fun getPassageData(): JsonObject +} \ 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..c69bd4e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/BaseAdapterNew.java @@ -0,0 +1,93 @@ +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 && position < mDataList.size()) { + mItemClickListener.clickItem(mDataList.get(position)); + } + }); + + holder.itemView.setOnCreateContextMenuListener((menu, v, menuInfo) -> { + if (position < mDataList.size()) { + createMenu(menu, mDataList.get(position)); + } + } + ); + + 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/PointListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/PointListAdapter.java new file mode 100644 index 0000000..2c615a1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/PointListAdapter.java @@ -0,0 +1,57 @@ +package com.bingce.controlnetwork.newui.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlnetwork.databinding.NewItemPointListBinding; +import com.bingce.controlnetwork.newui.viewholder.PointListViewHolder; + + +public class PointListAdapter extends BaseAdapterNew { + + private boolean isPlatCoordinate; + private String projectType; + + public PointListAdapter(Context context) { + super(context); + } + + @NonNull + @Override + public PointListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new PointListViewHolder(NewItemPointListBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(PointListViewHolder holder, int position) { + PointRecord pointRecordTj = mDataList.get(position); + //num就是name 因为从天津拷贝过来的 + holder.mBinding.tvPointNum.setText(pointRecordTj.getName()); +// holder.mBinding.tvPointName.setText(""); + + holder.mBinding.tvX.setVisibility(View.VISIBLE); + holder.mBinding.tvY.setVisibility(View.VISIBLE); + if (ProjectType.isLevel(projectType)) { + holder.mBinding.tvX.setVisibility(View.GONE); + holder.mBinding.tvY.setVisibility(View.GONE); + holder.mBinding.tvZ.setText("高程:" + pointRecordTj.getZ()); + } else { + holder.mBinding.tvX.setText("X:" + pointRecordTj.getX()); + holder.mBinding.tvY.setText("Y:" + pointRecordTj.getY()); + holder.mBinding.tvZ.setText("Z:" + pointRecordTj.getZ()); + } + } + + public void setIsPlatCoordinate(boolean isPlatCoordinate) { + this.isPlatCoordinate = isPlatCoordinate; + } + + public void setProjectType(String projectType) { + this.projectType = projectType; + } +} 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/adapter/StationListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/StationListAdapter.java new file mode 100644 index 0000000..e84cf02 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/StationListAdapter.java @@ -0,0 +1,37 @@ +package com.bingce.controlnetwork.newui.adapter; + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlnetwork.databinding.NewItemStationListBinding; +import com.bingce.controlnetwork.newui.model.StationListBean; +import com.bingce.controlnetwork.newui.viewholder.StationListViewHolder; + + +/** + * 测站列表adapter + */ +public class StationListAdapter extends BaseAdapterNew { + + public StationListAdapter(Context context) { + super(context); + } + + @NonNull + @Override + public StationListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new StationListViewHolder(NewItemStationListBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(StationListViewHolder holder, int position) { + StationListBean bean = mDataList.get(position); + holder.mBinding.tvIndex.setText(String.valueOf(position + 1)); + holder.mBinding.tvStationName.setText(bean.getStationName()); + holder.mBinding.tvStationType.setText(bean.getStationType()); + holder.mBinding.tvPointOrder.setText(bean.getStationPiontOrder()); + } + +} 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..24be276 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/ConfigFragment.kt @@ -0,0 +1,114 @@ +package com.bingce.controlnetwork.newui.configfragment + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.os.bundleOf +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 + + +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.total_station_online) + mBinding.ilLevelConnect.iv.setImageResource(R.mipmap.ic_level_connect) + mBinding.ilLevelConnect.tv.text = "水准仪联机" + 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.text = "自定义限差" + //三角导线联系测量 + 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.connectTsActivity() + } + mBinding.ilLevelConnect.root.setOnClickListener { + //水准仪联机 + SelectDeviceTypeUtil.connectLevelActivity() + } + 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 -> + SelectExportSurveyorRecordFragment.start( + context, bundleOf(SelectExportSurveyorRecordFragment.KEY_DATA to beanList) + ) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectExportType.java b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectExportType.java new file mode 100644 index 0000000..ba37586 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectExportType.java @@ -0,0 +1,70 @@ +package com.bingce.controlnetwork.newui.configfragment; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.Keep; + +@Keep +public class SelectExportType implements Parcelable { + public static final String TYPE_CONTROL = "TYPE_CONTROL"; + public static final String TYPE_KE_SHA = "TYPE_KE_SHA"; + public static final String TYPE_NAN_FANG = "TYPE_NAN_FANG"; + public static final String TYPE_QI_FEI = "TYPE_QI_FEI"; + public static final String TYPE_PING_CHA_ZHI_XING = "TYPE_PING_CHA_ZHI_XING"; + + private final String name; + private final String type; + private boolean isSelect; + + public SelectExportType(String name, String type) { + this.name = name; + this.type = type; + } + + protected SelectExportType(Parcel in) { + name = in.readString(); + type = in.readString(); + isSelect = in.readByte() != 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(name); + dest.writeString(type); + dest.writeByte((byte) (isSelect ? 1 : 0)); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public SelectExportType createFromParcel(Parcel in) { + return new SelectExportType(in); + } + + @Override + public SelectExportType[] newArray(int size) { + return new SelectExportType[size]; + } + }; + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectMeasureDataExportTypeFragment.java b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectMeasureDataExportTypeFragment.java new file mode 100644 index 0000000..029653e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectMeasureDataExportTypeFragment.java @@ -0,0 +1,170 @@ +package com.bingce.controlnetwork.newui.configfragment; + +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.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ItemSelectMeasureDataExportTypeBinding; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 选择观测数据导出的文件类型 + */ +public class SelectMeasureDataExportTypeFragment extends BottomSheetDialogFragment { + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_TYPE = "__SELECT_TYPE__"; + + private final List dataList = new ArrayList<>(); + private RecyclerView recyclerView; + private View btnCancel; + private View btnConfirm; + + @Override + public void onStart() { + super.onStart(); +// Dialog dialog = getDialog(); +// if (dialog != null) { +// Window window = dialog.getWindow(); +// if (window != null) { +// window.setLayout( +// WindowManager.LayoutParams.MATCH_PARENT, +// WindowManager.LayoutParams.WRAP_CONTENT); +// } +// } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_select_measure_data_export_type, container, false); + } + + + public static void start(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + IOnSelectCallback callback) { + SelectMeasureDataExportTypeFragment fragment = new SelectMeasureDataExportTypeFragment(); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected(result.getParcelableArrayList(KEY_TYPE)); + } + }); + fragment.show(fragmentManager, null); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + recyclerView = view.findViewById(R.id.recyclerView); + btnCancel = view.findViewById(R.id.btnCancel); + btnConfirm = view.findViewById(R.id.btnConfirm); + initView(); + initData(); + initListener(); + } + + private void initListener() { + btnCancel.setOnClickListener((v) -> { + dismissAllowingStateLoss(); + }); + btnConfirm.setOnClickListener((v) -> { + startConfirm(); + }); + } + + private void startConfirm() { + List exportList = new ArrayList<>(); + for (SelectExportType bean : dataList) { + if (bean.isSelect()) { + exportList.add(bean); + } + } + if (exportList.isEmpty()) { + ToastUtils.showShort("请选择导出格式"); + return; + } + backData(exportList); + } + + private void initView() { + + } + + private void initData() { + dataList.add(new SelectExportType("控制测量电子手簿格式", SelectExportType.TYPE_CONTROL)); + dataList.add(new SelectExportType("科傻格式", SelectExportType.TYPE_KE_SHA)); + dataList.add(new SelectExportType("南方平差易格式", SelectExportType.TYPE_NAN_FANG)); + dataList.add(new SelectExportType("启飞格式", SelectExportType.TYPE_QI_FEI)); + dataList.add(new SelectExportType("平差之星格式", SelectExportType.TYPE_PING_CHA_ZHI_XING)); + recyclerView.setAdapter(new Adapter()); + } + + private void backData(List selectList) { + Bundle args = new Bundle(); + args.putParcelableArrayList(KEY_TYPE, new ArrayList<>(selectList)); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + } + + public interface IOnSelectCallback { + void onSurveyorCycleSelected(ArrayList beanList); + } + + class Adapter extends RecyclerView.Adapter { + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(ItemSelectMeasureDataExportTypeBinding.inflate(getLayoutInflater(), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + + SelectExportType bean = dataList.get(position); + + holder.mBinding.tv.setText(bean.getName()); + holder.mBinding.cb.setChecked(bean.isSelect()); + + holder.itemView.setOnClickListener(v -> { + bean.setSelect(!bean.isSelect()); + notifyItemChanged(holder.getBindingAdapterPosition()); + }); + + } + + @Override + public int getItemCount() { + return dataList.size(); + } + } + + private static class ViewHolder extends RecyclerView.ViewHolder { + @NonNull + private final ItemSelectMeasureDataExportTypeBinding mBinding; + + public ViewHolder(ItemSelectMeasureDataExportTypeBinding binding) { + super(binding.getRoot()); + this.mBinding = binding; + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/createeditpoint/CreateEditPointActvity.kt b/app/src/main/java/com/bingce/controlnetwork/newui/createeditpoint/CreateEditPointActvity.kt new file mode 100644 index 0000000..a5a2eab --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/createeditpoint/CreateEditPointActvity.kt @@ -0,0 +1,379 @@ +package com.bingce.controlnetwork.newui.createeditpoint + +import android.content.Context +import android.content.Intent +import android.text.TextUtils +import android.view.View +import androidx.annotation.StringRes +import androidx.annotation.WorkerThread +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.ProjectType +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityNewUiCreateEditPointBinding +import com.bingce.controlnetwork.fragment.TipsFragment +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 新建或编辑点 + */ +class CreateEditPointActvity : BaseBindingActivity() { + + private var editPoint: PointRecord? = null + + private var isKnown = false + + companion object { + const val KEY_POINT_TYPE = "KEY_POINT_TYPE" + const val KEY_EDIT_POINT = "KEY_EDIT_POINT" + + @JvmStatic + fun launch( + context: Context, + projectId: String, + projectType: String, + pointType: String, + eidtPoint: PointRecord? = null + ) { + context.startActivity(Intent(context, CreateEditPointActvity::class.java).apply { + putExtra(BundleConstants.KEY_PROJECT_ID, projectId) + putExtra(BundleConstants.KEY_PROJECT_TYPE, projectType) + putExtra(KEY_POINT_TYPE, pointType) + putExtra(KEY_EDIT_POINT, eidtPoint) + }) + } + } + + override fun getBinding(): ActivityNewUiCreateEditPointBinding { + return ActivityNewUiCreateEditPointBinding.inflate(layoutInflater) + } + + override fun initView() { + mBinding.ilPointNum.tvTitle.setText(R.string.point_name) + mBinding.ilPointNum.editText.setHint(R.string.please_enter_roll_call) + + setBaseUi() + initListener() + } + + private fun initIntentData() { + val pointType = getPointType() + isKnown = + PointRecord.TYPE_KNOWN_POINT == pointType || PointRecord.TYPE_GLOBAL_POINT == pointType + editPoint = getEditPoint() + } + + private fun initListener() { + mBinding.tvSaveContinue.setOnClickListener { + startSaveContinue() + } + mBinding.tvSaveQuit.setOnClickListener { + startSaveQuite() + } + } + + private fun startSaveQuite() { + checkSave { + if (editPoint == null) { + saveRecordForCreate { + finish() + } + } else { + saveRecordForEdit(editPoint!!) { + finish() + } + } + } + } + + private fun startSaveContinue() { + checkSave { + saveRecordForCreate() + clearContent() + val nextPointNum = getNextPointNum() + mBinding.ilPointNum.editText.setText(nextPointNum) + } + } + + private fun checkSave(success: () -> Unit) { + val pointNum = getPointNumber() + if (TextUtils.isEmpty(pointNum)) { + ToastUtils.showShort(R.string.please_enter_roll_call) + return + } + + if (isKnown) { + if (mBinding.ilPointX.root.visibility == View.VISIBLE) { + val x = getX() + if (TextUtils.isEmpty(x)) { + val hint = R.string.please_input_x +// val hint = +// if (isPlatCood) R.string.please_input_x else R.string.please_input_longitude + ToastUtils.showShort(hint) + return + } + } + if (mBinding.ilPointY.root.visibility == View.VISIBLE) { + val y = getY() + if (TextUtils.isEmpty(y)) { + val hint = R.string.please_input_y +// val hint = +// if (isPlatCood) R.string.please_input_y else R.string.please_input_latitude + ToastUtils.showShort(hint) + return + } + } + val z = getZ() + if (TextUtils.isEmpty(z)) { + val hint = R.string.please_enter_elevation +// val hint = if (isLevelProject()) { +// R.string.please_enter_elevation +// } else { +// if (isPlatCood) R.string.please_input_z else R.string.please_enter_elevation +// } + ToastUtils.showShort(hint) + return + } + } + + if (isNewCreatePoint()) { + checkSameNamePoint(pointNum) { + success() + } + return + } + success() + } + + private fun checkSameNamePoint(pointNum: String, success: () -> Unit) { + lifecycleScope.launch { + val pointRecord = withContext(Dispatchers.IO) { + val pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource() + pointDataSource.findByNameSync(pointNum, getProjectId()) + } + + if (pointRecord != null) { + //点名重复,提示 + TipsFragment.tipsOnly( + supportFragmentManager, + this@CreateEditPointActvity, + this@CreateEditPointActvity, + "同一项目下点号不能重复,请修改后重试操作。" + ) + return@launch + } + success() + } + } + + /** + * 设置平面还是大地坐标 + */ + private fun setBaseUi() { + if (!isNewCreatePoint()) { + mBinding.tvSaveContinue.visibility = View.GONE + } + + val projectType = getProjectType() + if (isLevelProject()) { + mBinding.ilPointX.root.visibility = View.GONE + mBinding.ilPointY.root.visibility = View.GONE + + setBaseTitleHint( + R.string.x_coord, + R.string.y_coord, + R.string.elevation, + R.string.please_input_x, + R.string.please_input_y, + R.string.please_enter_elevation + ) + } else if (ProjectType.isHeightTraverse(projectType)) { + setBaseTitleHint( + R.string.x_coord, + R.string.y_coord, + R.string.elevation, + R.string.please_input_x, + R.string.please_input_y, + R.string.please_enter_elevation + ) + } else { + setBaseTitleHint( + R.string.x_coord, R.string.y_coord, R.string.z_coord, + R.string.please_input_x, R.string.please_input_y, R.string.please_input_z + ) + } + + setEditData() + } + + private fun setBaseTitleHint( + @StringRes xCoord: Int, yCoord: Int, zCoord: Int, + pleaseInputX: Int, pleaseInputY: Int, @StringRes pleaseInputZ: Int + ) { + mBinding.ilPointX.tvTitle.setText(xCoord) + mBinding.ilPointY.tvTitle.setText(yCoord) + mBinding.ilPointZ.tvTitle.setText(zCoord) + mBinding.ilPointX.editText.setHint(pleaseInputX) + mBinding.ilPointY.editText.setHint(pleaseInputY) + mBinding.ilPointZ.editText.setHint(pleaseInputZ) + } + + private fun setEditData() { + editPoint?.let { + mBinding.ilPointNum.editText.setText(it.getName()) + + setCoordData(it.getX(), it.getY(), it.getZ()) +// setCoordData(it.getLongitude(), it.getLatitude(), it.getZ()) + } + } + + private fun setCoordData(x: Double, y: Double, z: Double) { + mBinding.ilPointX.editText.setText(x.toString()) + mBinding.ilPointY.editText.setText(y.toString()) + mBinding.ilPointZ.editText.setText(z.toString()) + } + + override fun initData() { + + + } + + override fun initToolBar() { + initIntentData() + val title = if (editPoint == null) R.string.new_point else R.string.edit_point + setToolbarTitle(title) + super.initToolBar() + } + + private fun getProjectId() = intent.getStringExtra(BundleConstants.KEY_PROJECT_ID)!! + private fun getProjectType() = intent.getStringExtra(BundleConstants.KEY_PROJECT_TYPE)!! + + private fun getPointType() = intent.getStringExtra(KEY_POINT_TYPE)!! + + private fun getEditPoint() = + intent.getParcelableExtra(KEY_EDIT_POINT) + + private fun isNewCreatePoint() = editPoint == null + + private fun getPointNumber() = mBinding.ilPointNum.editText.text.toString().trim() + private fun getX() = mBinding.ilPointX.editText.text.toString().trim() + private fun getY() = mBinding.ilPointY.editText.text.toString().trim() + private fun getZ() = mBinding.ilPointZ.editText.text.toString().trim() + + private fun getXDouble(): Double { + return xToDouble(getX()) + } + + private fun getYDouble(): Double { + return xToDouble(getY()) + } + + private fun getZDouble(): Double { + return xToDouble(getZ()) + } + + private fun xToDouble(value: String): Double { + return if (TextUtils.isEmpty(value)) { + 0.0 + } else { + value.toDouble() + } + } + + private fun clearContent() { + mBinding.ilPointX.editText.setText("") + mBinding.ilPointY.editText.setText("") + mBinding.ilPointZ.editText.setText("") + mBinding.ilPointX.editText.requestFocus() + } + + private fun getNextPointNum(): String { + val pointNumber = getPointNumber() + val index = getIndexForTianjin(pointNumber) + val word = getWordForTianjin(pointNumber) + return "${word}${index + 1}" + } + + private fun getIndexForTianjin(pointName: String): Int { + val pre = "\\D*" + val data = pointName.replace(pre.toRegex(), "") + return try { + data.toInt() + } catch (e: NumberFormatException) { + 0 + } + } + + private fun getWordForTianjin(pointName: String): String { + val pre = "\\d*" + return pointName.replace(pre.toRegex(), "") + } + + private fun saveRecordForEdit(pointRecord: PointRecord, success: () -> Unit) { + lifecycleScope.launch(Dispatchers.IO) { + val projectType = getProjectType() + if (ProjectType.isLevel(projectType)) { + pointRecord.setLongitude(getXDouble()) + pointRecord.setLatitude(getYDouble()) + } else { + pointRecord.setX(getXDouble()) + pointRecord.setY(getYDouble()) + } + pointRecord.setZ(getZDouble()) + pointRecord.setName(getPointNumber()) + pointRecord.setCode("") + pointRecord.setRemarks("") + SurveyorDatabaseFactory.instance + .getPointDataSource() + .saveSync(pointRecord) + success() + } + } + + private fun saveRecordForCreate(success: (() -> Unit)? = null) { + lifecycleScope.launch(Dispatchers.IO) { + val pointRecord = createPointRecord( + getProjectId(), getPointType(), getPointNumber(), "", + getXDouble(), getYDouble(), getZDouble(), "", -1, + ) + SurveyorDatabaseFactory.instance + .getPointDataSource() + .save(pointRecord) + success?.invoke() + } + } + + @WorkerThread + private fun createPointRecord( + projectId: String, + pointType: String, + name: String, + code: String, + x: Double, + y: Double, + z: Double, + remarks: String, + orderIndex: Int, + ): PointRecord { + val projectType = getProjectType() + return if (ProjectType.isLevel(projectType)) { + PointRecord.createLlhPoint(projectId, pointType, name, x, y, z) + } else { + PointRecord.point( + projectId, pointType, name, code, + x, y, z, remarks, + orderIndex.toLong() + ) + } + } + + private fun isLevelProject() = ProjectTypeValue.LEVEL == getProjectType() + +} \ No newline at end of file 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..34eed9f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/mefragment/MeFragment.kt @@ -0,0 +1,118 @@ +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 com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.AboutActivity +import com.bingce.controlnetwork.activity.SettingsActivity +import com.bingce.controlnetwork.activity.ViewRecentCrashActivity +import com.bingce.controlnetwork.activity.backup.BackupExportActivity +import com.bingce.controlnetwork.activity.backup.launch.BackupImportHelper +import com.bingce.controlnetwork.databinding.NewFragmentMeBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.viewmodel.MainActivityViewModel +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.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) +// } + } + + mBinding.llViewException.setOnClickListener { + //查看异常 + startActivity(Intent(requireContext(), ViewRecentCrashActivity::class.java)) + } + } + + 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/model/StationListBean.kt b/app/src/main/java/com/bingce/controlnetwork/newui/model/StationListBean.kt new file mode 100644 index 0000000..5581a82 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/model/StationListBean.kt @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.newui.model + +import androidx.annotation.Keep + +@Keep +data class StationListBean( + val projectType: String?, + val stationId: String, + val stationName: String, + val stationType: String, + val stationPiontOrder: String, + + val lineType: String?, + val lineId: String? +) 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..2912f01 --- /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 com.bingce.controlnetwork.func.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/stationlist/StationListFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListFragment.kt new file mode 100644 index 0000000..c938732 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListFragment.kt @@ -0,0 +1,190 @@ +package com.bingce.controlnetwork.newui.stationlist + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.fragment.app.viewModels +import androidx.lifecycle.LiveData + +import com.bingce.controlapphelper.datasource.database.ProjectType.Companion.isConnection +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.adapter.SurveyorStationListAdapter +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuEdit +import com.bingce.controlnetwork.databinding.FragmentListLayoutBinding +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment +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.controlnetwork.newui.adapter.StationListAdapter +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.newui.model.StationListBean +import com.bingce.controlnetwork.util.SurveyorStationUtil +import com.bingce.utils.ThreadPoolUtil + +/** + * 测站列表仅仅是列表 + */ +class StationListFragment : BaseFragmentBinding() { + + private val viewModel by viewModels(ownerProducer = { requireParentFragment() }) + + private var stationListLiveData: LiveData>? = null + + private var hasSurvey = false + + + private val adapter by lazy { + StationListAdapter(requireContext()) + } + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentListLayoutBinding { + return FragmentListLayoutBinding.inflate(inflater, container, false) + } + + override fun initView() { + initAdapter() + } + + private fun initAdapter() { + mBinding.list.adapter = adapter + + if (viewModel.isCanEditDelete) { + adapter.setAdapterContextMenu(object : ContextMenuEdit() { + override fun edit(item: StationListBean) { + startEdit(item) + } + }) + } else { + //不能编辑和删除是在测量页面中 + adapter.setOnItemClickListener { + clickStationItem(it) + } + } + + } + + /** + * 点击测站 + */ + private fun clickStationItem(bean: StationListBean) { + //StationSurveyorFragment原始测量页 + if (isConnection(bean.projectType)) { + MeasureFragment.start(context, bean.stationId, bean.stationName) + } else { + StationSurveyorFragment.start(context, bean.stationId, bean.stationName) + } + } + + private fun startEdit(item: StationListBean) { + if (SurveyorStationRecord.isLineWell(item.lineType)) { + TipsWith2OptionFragment.tips( + childFragmentManager, viewLifecycleOwner, + getString(R.string.button_edit_station), + getString(R.string.button_delete_station), + getString(R.string.tips_select_default_station_operator_well), + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + SurveyorStationUtil.editLine(context, item.lineId) + } + + override fun onCancel() { + SurveyorStationListAdapter.try2DeleteLine( + item.lineId, + context, + childFragmentManager, + viewLifecycleOwner, + this@StationListFragment + ) + } + }) + return + } + + //检测是否属于导线测量 + if (SurveyorStationRecord.isLineStation(item.lineId)) { + TipsWith2OptionFragment.tips( + childFragmentManager, viewLifecycleOwner, + getString(R.string.button_edit_line), + getString(R.string.button_delete_line), + getString(R.string.tips_forbid_delete_station_because_batch), + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + SurveyorStationListAdapter.try2EditLine( + item.lineId, + context, + childFragmentManager, + viewLifecycleOwner, + this@StationListFragment + ) + } + + override fun onCancel() { + SurveyorStationListAdapter.try2DeleteLine( + item.lineId, + context, + childFragmentManager, + viewLifecycleOwner, + this@StationListFragment + ) + } + }) + } else { + TipsWith2OptionFragment.tips( + childFragmentManager, viewLifecycleOwner, + getString(R.string.button_edit_station), + getString(R.string.button_delete_station), + getString(R.string.tips_select_default_station_operator), + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + ThreadPoolUtil.execute { + SingleStationDetailAndEditFragment.start( + context, + item.stationId, + item.stationName, + viewModel.projectId, + item.lineType + ) + } + } + + override fun onCancel() { + SurveyorStationListAdapter.try2DeleteStation( + item.stationId, + context, + childFragmentManager, + viewLifecycleOwner, + this@StationListFragment + ) + } + }) + } + } + + override fun initData() { + refreshUi() + } + + fun refreshUi() { + if (stationListLiveData != null) { + stationListLiveData!!.removeObservers(this) + } + stationListLiveData = SurveyorDatabaseFactory.instance.surveyorStation.getLiveDataList( + viewModel.projectId, + viewModel.periodId + ) + if (stationListLiveData != null) { + stationListLiveData!!.observe(this) { + viewModel.getStationListData(it) { stationList -> + hasSurvey = stationList.isNotEmpty() + adapter.refreshData(stationList) + } + } + } + } + + fun hasSurvey() = hasSurvey +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListVm.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListVm.kt new file mode 100644 index 0000000..a095fae --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListVm.kt @@ -0,0 +1,102 @@ +package com.bingce.controlnetwork.newui.stationlist + +import android.text.TextUtils +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.line.LineRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint +import com.bingce.controlapphelper.util.StationUtil +import com.bingce.controlnetwork.newui.model.StationListBean +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class StationListVm : ViewModel() { + + var isCanEditDelete = false + + var projectId: String? = null + var periodId: String? = null + + fun getStationListData( + stationList: List, + callBack: (List) -> Unit + ) { + viewModelScope.launch(Dispatchers.IO) { + + val showList = mutableListOf() + for (station in stationList) { + val stationName = StationUtil.getStationPointName(station) + + var lineName = "" + var lineTypeShow = "多测回测角" + var lineType: String? = null + station.lineId?.let { + val lineRecord = SurveyorDatabaseFactory + .instance + .lineRecordDatabase + .findById(station.lineId) + if (lineRecord != null) { + lineName = lineRecord.name ?: "" + lineTypeShow = LineRecord.lineTypeToName(lineRecord.type) + lineType = lineRecord.type + } + } + + val stationTypeSb = StringBuilder() + + stationTypeSb.append(lineTypeShow) + if (!TextUtils.isEmpty(lineName)) { + stationTypeSb.append("-") + stationTypeSb.append(lineName) + } + + val pointOrder = StringBuilder() + for (point in station.items) { + //排除站点 + if (point.type == SurveyorPoint.TYPE_STATION) { + continue + } + val pointRecord = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(point.originalPointId) + + pointOrder.append(pointRecord?.getName()) + pointOrder.append("-") + } + + if (pointOrder.isNotEmpty()) { + pointOrder.deleteCharAt(pointOrder.length - 1) + } + + val stationListBean = + StationListBean( + station.projectType, + station.id, + stationName ?: "", + stationTypeSb.toString(), + pointOrder.toString(), + lineType, + station.lineId + ) + + showList.add(stationListBean) + + } + + withContext(Dispatchers.Main) { + callBack(showList) + } + + } + + } + + fun setArgument(projectId: String?, periodId: String?) { + this.projectId = projectId + this.periodId = periodId + } + + +} \ 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..51155b1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingSettingFragment.kt @@ -0,0 +1,190 @@ +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() + + private var isCanSetAloneDistance = false + + 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) + + isCanSetAloneDistance = viewModel.isCanShowAloneDistance() + + 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) + + if (isCanSetAloneDistance) { + scAloneMeasureDistance.visibility=View.VISIBLE + }else{ + scAloneMeasureDistance.visibility=View.GONE + } + + + 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..4a2e1fc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingVm.kt @@ -0,0 +1,228 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +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.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 isCanShowAloneDistance(): Boolean { + if (stationRecord == null) { + return false + } + return ProjectType.isConnection(stationRecord!!.projectType) + } + +// /** +// * 当测点的状态更新完再调用这个方法 +// */ +// 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..9f1166a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingsActivity.kt @@ -0,0 +1,151 @@ +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 + +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/stationsettingheighttraverse/IStationSettingOperate.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/IStationSettingOperate.kt new file mode 100644 index 0000000..69b5ff1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/IStationSettingOperate.kt @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.newui.stationsettingheighttraverse + +interface IStationSettingOperate { + fun checkSaveNot(): Boolean +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingEnvironmentHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingEnvironmentHeightTraverseFragment.kt new file mode 100644 index 0000000..3682742 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingEnvironmentHeightTraverseFragment.kt @@ -0,0 +1,213 @@ +package com.bingce.controlnetwork.newui.stationsettingheighttraverse + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.EditText +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.heighttraverse.stationsetting.model.StationSettingHeightTraverseRecord +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentStationSettingEnvironmentHeightTraverseBinding +import com.bingce.controlnetwork.fragment.stationsetting.BaseStationSettingFragment.Companion.DEFAULT_AIR_PRESSURE +import com.bingce.controlnetwork.fragment.stationsetting.BaseStationSettingFragment.Companion.DEFAULT_CONSTANT +import com.bingce.controlnetwork.fragment.stationsetting.BaseStationSettingFragment.Companion.DEFAULT_TEMPERATURE +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 测站设置-环境信息 + */ +class StationSettingEnvironmentHeightTraverseFragment : + BaseFragmentBinding(), + IStationSettingOperate { + + private val viewModel by activityViewModels() + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentStationSettingEnvironmentHeightTraverseBinding { + return NewFragmentStationSettingEnvironmentHeightTraverseBinding.inflate( + inflater, + container, + false + ) + } + + override fun initView() { + mBinding.ilDryTemperature.tvName.text = getString(R.string.dry_temperature) + mBinding.ilDryTemperature.etValue.hint = getString(R.string.dry_temperature) + mBinding.ilDryTemperature.tvUnit.text = "℃" + + mBinding.ilHumidityTemperature.tvName.text = getString(R.string.humidity_temperature) + mBinding.ilHumidityTemperature.etValue.hint = getString(R.string.humidity_temperature) + mBinding.ilHumidityTemperature.tvUnit.text = "℃" + + mBinding.ilAirPressure.tvName.text = getString(R.string.hint_air_pressure) + mBinding.ilAirPressure.etValue.hint = getString(R.string.hint_air_pressure) + mBinding.ilAirPressure.tvUnit.text = "hPa" + + mBinding.ilAdditionConstant.tvName.text = getString(R.string.addition_constant) + mBinding.ilAdditionConstant.etValue.hint = getString(R.string.addition_constant) + mBinding.ilAdditionConstant.tvUnit.text = "mm" + + mBinding.ilmultiplicationConstant.tvName.text = getString(R.string.multiplication_constant) + mBinding.ilmultiplicationConstant.etValue.hint = getString(R.string.multiplication_constant) + mBinding.ilmultiplicationConstant.tvUnit.text = "ppm" + + initListener() + } + + private fun initListener() { + mBinding.tvLastData.setOnClickListener { + useLastData() + } + mBinding.tvStandardData.setOnClickListener { + setDataFromRecord(null) + } + } + + private fun useLastData() { + lifecycleScope.launch { + val record = withContext(Dispatchers.IO) { + val dryTemperature = getValueFromLastKey(ConfigConstants.KEY_LAST_DRY_TEMPERATURE) + val humidityTemperature = + getValueFromLastKey(ConfigConstants.KEY_LAST_HUMIDITY_TEMPERATURE) + val airPressure = getValueFromLastKey(ConfigConstants.KEY_LAST_AIR_PRESSURE) + val additionConstant = + getValueFromLastKey(ConfigConstants.KEY_LAST_ADDITION_CONSTANT) + val multiplicationConstant = + getValueFromLastKey(ConfigConstants.KEY_LAST_MULTIPLICATION_CONSTANT) + val instrumentHeightBefore = + getValueFromLastKey(ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_BEFORE) + val instrumentHeightAfter = + getValueFromLastKey(ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_AFTER) + val backPrismHeightBefore = + getValueFromLastKey(ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_BEFORE) + val backPrismHeightAfter = + getValueFromLastKey(ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_AFTER) + val frontPrismHeightBefore = + getValueFromLastKey(ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_BEFORE) + val frontPrismHeightAfter = + getValueFromLastKey(ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_AFTER) + + if (dryTemperature == null + || humidityTemperature == null + || airPressure == null + || additionConstant == null + || multiplicationConstant == null + || instrumentHeightBefore == null + || instrumentHeightAfter == null + || backPrismHeightBefore == null + || backPrismHeightAfter == null + || frontPrismHeightBefore == null + || frontPrismHeightAfter == null + ) { + return@withContext null + } + + StationSettingHeightTraverseRecord.newInstance( + viewModel.stationId, + dryTemperature, + humidityTemperature, + airPressure, + additionConstant, + multiplicationConstant, + instrumentHeightBefore, + instrumentHeightAfter, + backPrismHeightBefore, + backPrismHeightAfter, + frontPrismHeightBefore, + frontPrismHeightAfter + ) + } + + setDataFromRecord(record) + } + } + + private fun getValueFromLastKey(key: String): String? { + val record = + SurveyorDatabaseFactory.instance.configDataSource.getByKeySync(key) + return record?.configValue + } + + override fun initData() { + lifecycleScope.launch { + val record = withContext(Dispatchers.IO) { + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .getRecordByStationId(viewModel.stationId) + } + setDataFromRecord(record) + } + } + + private fun setDataFromRecord(record: StationSettingHeightTraverseRecord?) { + mBinding.ilDryTemperature.etValue.setText( + record?.dryTemperature ?: DEFAULT_TEMPERATURE + ) + mBinding.ilHumidityTemperature.etValue.setText( + record?.humidityTemperature ?: DEFAULT_TEMPERATURE + ) + mBinding.ilAirPressure.etValue.setText(record?.airPressure ?: DEFAULT_AIR_PRESSURE) + mBinding.ilAdditionConstant.etValue.setText( + record?.additionConstant ?: DEFAULT_CONSTANT + ) + mBinding.ilmultiplicationConstant.etValue.setText( + record?.multiplicationConstant ?: DEFAULT_CONSTANT + ) + } + + override fun checkSaveNot(): Boolean { + if (editTextEmpty(mBinding.ilDryTemperature.etValue)) { + ToastUtils.showShort(R.string.please_enter_dry_temperature) + return true + } + if (editTextEmpty(mBinding.ilHumidityTemperature.etValue)) { + ToastUtils.showShort(R.string.please_enter_humidity_temperature) + return true + } + if (editTextEmpty(mBinding.ilAirPressure.etValue)) { + ToastUtils.showShort(Tools.getString(R.string.please_enter_air_pressure)) + return true + } + if (editTextEmpty(mBinding.ilAdditionConstant.etValue)) { + ToastUtils.showShort(R.string.please_enter_addition_constant) + return true + } + if (editTextEmpty(mBinding.ilmultiplicationConstant.etValue)) { + ToastUtils.showShort(R.string.please_enter_multiplication_constant) + return true + } + setDataToViewModel() + return false + } + + private fun setDataToViewModel() { + val dryTemperature = getEtText(mBinding.ilDryTemperature.etValue) + val humidityTemperature = getEtText(mBinding.ilHumidityTemperature.etValue) + val airPressure = getEtText(mBinding.ilAirPressure.etValue) + val additionConstant = getEtText(mBinding.ilAdditionConstant.etValue) + val multiplicationConstant = getEtText(mBinding.ilmultiplicationConstant.etValue) + + viewModel.dryTemperature = dryTemperature + viewModel.humidityTemperature = humidityTemperature + viewModel.airPressure = airPressure + viewModel.additionConstant = additionConstant + viewModel.multiplicationConstant = multiplicationConstant + } + + private fun editTextEmpty(et: EditText): Boolean { + return TextUtils.isEmpty(getEtText(et)) + } + + private fun getEtText(et: EditText) = et.text.toString().trim() + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingHeightHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingHeightHeightTraverseFragment.kt new file mode 100644 index 0000000..d16e812 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingHeightHeightTraverseFragment.kt @@ -0,0 +1,151 @@ +package com.bingce.controlnetwork.newui.stationsettingheighttraverse + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.EditText +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.heighttraverse.stationsetting.model.StationSettingHeightTraverseRecord +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentStationSettingHeightHeightTraverseBinding +import com.bingce.controlnetwork.fragment.stationsetting.BaseStationSettingFragment.Companion.DEFAULT_INSTRUMEN_HEIGHT +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 高程导线-仪高镜高 + */ +class StationSettingHeightHeightTraverseFragment : + BaseFragmentBinding(), + IStationSettingOperate { + + private val viewModel by activityViewModels() + + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentStationSettingHeightHeightTraverseBinding { + return NewFragmentStationSettingHeightHeightTraverseBinding.inflate( + inflater, + container, + false + ) + } + + override fun initView() { + mBinding.ilInstrumentHeight.tvName.text = getString(R.string.instrument_height) + mBinding.ilBackPrismHeight.tvName.text = getString(R.string.back_prism_height) + mBinding.ilFrontPrismHeight.tvName.text = getString(R.string.front_prism_height) + + //仪器高,棱镜高 + mBinding.ilInstrumentHeight.button1.setOnClickListener { + mBinding.ilInstrumentHeight.etValueAfter.setText( + getEtText(mBinding.ilInstrumentHeight.etValueBefore) + ) + } + mBinding.ilBackPrismHeight.button1.setOnClickListener { + mBinding.ilBackPrismHeight.etValueAfter.setText( + getEtText(mBinding.ilBackPrismHeight.etValueBefore) + ) + } + mBinding.ilFrontPrismHeight.button1.setOnClickListener { + mBinding.ilFrontPrismHeight.etValueAfter.setText( + getEtText(mBinding.ilFrontPrismHeight.etValueBefore) + ) + } + + } + + private fun getEtText(et: EditText) = et.text.toString().trim() + + + override fun initData() { + lifecycleScope.launch { + val record = withContext(Dispatchers.IO) { + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .getRecordByStationId(viewModel.stationId) + } + setDataFromRecord(record) + } + } + + private fun setDataFromRecord(record: StationSettingHeightTraverseRecord?) { + mBinding.ilInstrumentHeight.etValueBefore.setText( + record?.instrumentHeightBefore ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilInstrumentHeight.etValueAfter.setText( + record?.instrumentHeightAfter ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilBackPrismHeight.etValueBefore.setText( + record?.backPrismHeightBefore ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilBackPrismHeight.etValueAfter.setText( + record?.backPrismHeightAfter ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilFrontPrismHeight.etValueBefore.setText( + record?.frontPrismHeightBefore ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilFrontPrismHeight.etValueAfter.setText( + record?.frontPrismHeightAfter ?: DEFAULT_INSTRUMEN_HEIGHT + ) + } + + override fun checkSaveNot(): Boolean { + if (editTextEmpty(mBinding.ilInstrumentHeight.etValueBefore)) { + ToastUtils.showShort(R.string.please_enter_instrument_height_before) + return true + } + if (editTextEmpty(mBinding.ilInstrumentHeight.etValueAfter)) { + ToastUtils.showShort(R.string.please_enter_instrument_height_after) + return true + } + if (editTextEmpty(mBinding.ilBackPrismHeight.etValueBefore)) { + ToastUtils.showShort(R.string.please_enter_back_prism_height_before) + return true + } + if (editTextEmpty(mBinding.ilBackPrismHeight.etValueAfter)) { + ToastUtils.showShort(R.string.please_enter_back_prism_height_after) + return true + } + if (editTextEmpty(mBinding.ilFrontPrismHeight.etValueBefore)) { + ToastUtils.showShort(R.string.please_enter_front_prism_height_before) + return true + } + if (editTextEmpty(mBinding.ilFrontPrismHeight.etValueAfter)) { + ToastUtils.showShort(R.string.please_enter_front_prism_height_after) + return true + } + + setDataToViewModel() + + return false + } + + private fun setDataToViewModel() { + val instrumentHeightBefore = getEtText(mBinding.ilInstrumentHeight.etValueBefore) + val instrumentHeightAfter = getEtText(mBinding.ilInstrumentHeight.etValueAfter) + val backPrismHeightBefore = getEtText(mBinding.ilBackPrismHeight.etValueBefore) + val backPrismHeightAfter = getEtText(mBinding.ilBackPrismHeight.etValueAfter) + val frontPrismHeightBefore = getEtText(mBinding.ilFrontPrismHeight.etValueBefore) + val frontPrismHeightAfter = getEtText(mBinding.ilFrontPrismHeight.etValueAfter) + + viewModel.instrumentHeightBefore = instrumentHeightBefore + viewModel.instrumentHeightAfter = instrumentHeightAfter + viewModel.backPrismHeightBefore = backPrismHeightBefore + viewModel.backPrismHeightAfter = backPrismHeightAfter + viewModel.frontPrismHeightBefore = frontPrismHeightBefore + viewModel.frontPrismHeightAfter = frontPrismHeightAfter + } + + private fun editTextEmpty(et: EditText): Boolean { + return TextUtils.isEmpty(getEtText(et)) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingHeightTraverseVm.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingHeightTraverseVm.kt new file mode 100644 index 0000000..860d09e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingHeightTraverseVm.kt @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.newui.stationsettingheighttraverse + +import androidx.lifecycle.ViewModel + +class StationSettingHeightTraverseVm : ViewModel() { + lateinit var stationId: String + + var instrumentHeightBefore: String? = null + var instrumentHeightAfter: String? = null + var backPrismHeightBefore: String? = null + var backPrismHeightAfter: String? = null + var frontPrismHeightBefore: String? = null + var frontPrismHeightAfter: String? = null + + var dryTemperature: String? = null + var humidityTemperature: String? = null + var airPressure: String? = null + var additionConstant: String? = null + var multiplicationConstant: String? = null + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingsHeightTraverseActivity.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingsHeightTraverseActivity.kt new file mode 100644 index 0000000..79b29cb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/StationSettingsHeightTraverseActivity.kt @@ -0,0 +1,317 @@ +package com.bingce.controlnetwork.newui.stationsettingheighttraverse + +import android.content.Context +import android.content.Intent +import android.view.Menu +import android.view.MenuItem +import androidx.activity.viewModels +import androidx.annotation.WorkerThread +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.lifecycle.lifecycleScope +import androidx.viewpager.widget.ViewPager.OnPageChangeListener +import blankj.utilcode.util.ToastUtils +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.heighttraverse.stationsetting.model.StationSettingHeightTraverseRecord +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 kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class StationSettingsHeightTraverseActivity : + 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, + StationSettingsHeightTraverseActivity::class.java + ).apply { + putExtra(BundleConstants.KEY_SURVEYOR_STATION_ID, stationId) + }) + } + } + + override fun getBinding(): NewActivityStationSettingBinding { + return NewActivityStationSettingBinding.inflate(layoutInflater) + } + + override fun initView() { + viewModel.stationId = getStationId() + initViewPager() + } + + override fun initData() { + + } + + private fun initViewPager() { + fragments.add(StationSettingHeightHeightTraverseFragment()) + fragments.add(StationSettingEnvironmentHeightTraverseFragment()) + + 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 + } + } + //保存到数据库 + saveData() + } + + private fun saveData() { + lifecycleScope.launch(Dispatchers.IO) { + val stationId = getStationId() + + val stationSettingHeightTraverseRecord = + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .getRecordByStationId(stationId) + + if (stationSettingHeightTraverseRecord == null) { + val stationSettingHeightTraverseRecordNew = + StationSettingHeightTraverseRecord.newInstance( + stationId, + viewModel.dryTemperature!!, + viewModel.humidityTemperature!!, + viewModel.airPressure!!, + viewModel.additionConstant!!, + viewModel.multiplicationConstant!!, + viewModel.instrumentHeightBefore!!, + viewModel.instrumentHeightAfter!!, + viewModel.backPrismHeightBefore!!, + viewModel.backPrismHeightAfter!!, + viewModel.frontPrismHeightBefore!!, + viewModel.frontPrismHeightAfter!! + ) + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .saveRecord(stationSettingHeightTraverseRecordNew) + } else { + stationSettingHeightTraverseRecord.dryTemperature = viewModel.dryTemperature!! + stationSettingHeightTraverseRecord.humidityTemperature = + viewModel.humidityTemperature!! + stationSettingHeightTraverseRecord.airPressure = viewModel.airPressure!! + stationSettingHeightTraverseRecord.additionConstant = viewModel.additionConstant!! + stationSettingHeightTraverseRecord.multiplicationConstant = + viewModel.multiplicationConstant!! + stationSettingHeightTraverseRecord.instrumentHeightBefore = + viewModel.instrumentHeightBefore!! + stationSettingHeightTraverseRecord.instrumentHeightAfter = + viewModel.instrumentHeightAfter!! + stationSettingHeightTraverseRecord.backPrismHeightBefore = + viewModel.backPrismHeightBefore!! + stationSettingHeightTraverseRecord.backPrismHeightAfter = + viewModel.backPrismHeightAfter!! + stationSettingHeightTraverseRecord.frontPrismHeightBefore = + viewModel.frontPrismHeightBefore!! + stationSettingHeightTraverseRecord.frontPrismHeightAfter = + viewModel.frontPrismHeightAfter!! + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .updateRecord(stationSettingHeightTraverseRecord) + } + + val stationRecord = + SurveyorDatabaseFactory.instance.surveyorStation.getRecordSync(stationId) + if (stationRecord != null) { + stationRecord.instrumentHeight = viewModel.instrumentHeightBefore + if (!stationRecord.items.isNullOrEmpty()) { + stationRecord.items.last().prismHeight = viewModel.frontPrismHeightBefore + if (stationRecord.items.size > 2) { + stationRecord.items[1].prismHeight = viewModel.backPrismHeightBefore + } + } + } + SurveyorDatabaseFactory.instance.surveyorStation.update(stationRecord) + + saveLastData( + viewModel.dryTemperature!!, + viewModel.humidityTemperature!!, + viewModel.airPressure!!, + viewModel.additionConstant!!, + viewModel.multiplicationConstant!!, + viewModel.instrumentHeightBefore!!, + viewModel.instrumentHeightAfter!!, + viewModel.backPrismHeightBefore!!, + viewModel.backPrismHeightAfter!!, + viewModel.frontPrismHeightBefore!!, + viewModel.frontPrismHeightAfter!! + ) + + ToastUtils.showShort(R.string.save_success) + + } + } + + @WorkerThread + private fun saveLastData( + dryTemperature: String, + humidityTemperature: String, + airPressure: String, + additionConstant: String, + multiplicationConstant: String, + instrumentHeightBefore: String, + instrumentHeightAfter: String, + backPrismHeightBefore: String, + backPrismHeightAfter: String, + frontPrismHeightBefore: String, + frontPrismHeightAfter: String + ) { + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_DRY_TEMPERATURE, + dryTemperature + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_HUMIDITY_TEMPERATURE, + humidityTemperature + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_AIR_PRESSURE, + airPressure + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_ADDITION_CONSTANT, + additionConstant + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_MULTIPLICATION_CONSTANT, + multiplicationConstant + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_BEFORE, + instrumentHeightBefore + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_AFTER, + instrumentHeightAfter + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_BEFORE, + backPrismHeightBefore + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_AFTER, + backPrismHeightAfter + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_BEFORE, + frontPrismHeightBefore + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_AFTER, + frontPrismHeightAfter + ) + ) + } + + override fun onBackPressed() { + if (isFinishAtOnce()) { + super.onBackPressed() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/model/StationSettingEnvironmentData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/model/StationSettingEnvironmentData.kt new file mode 100644 index 0000000..c63f2ef --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/model/StationSettingEnvironmentData.kt @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.newui.stationsettingheighttraverse.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/stationsettingheighttraverse/model/StationSettingHeightData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/model/StationSettingHeightData.kt new file mode 100644 index 0000000..6bb05e8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsettingheighttraverse/model/StationSettingHeightData.kt @@ -0,0 +1,58 @@ +package com.bingce.controlnetwork.newui.stationsettingheighttraverse.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/viewholder/PointListViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/PointListViewHolder.java new file mode 100644 index 0000000..9e44d5e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/PointListViewHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.newui.viewholder; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.NewItemPointListBinding; + + +public class PointListViewHolder extends RecyclerView.ViewHolder { + public final NewItemPointListBinding mBinding; + + public PointListViewHolder(NewItemPointListBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} 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/viewholder/StationListViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/StationListViewHolder.java new file mode 100644 index 0000000..aab5c7a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/StationListViewHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.newui.viewholder; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.NewItemStationListBinding; + + +public class StationListViewHolder extends RecyclerView.ViewHolder { + public final NewItemStationListBinding mBinding; + + public StationListViewHolder(NewItemStationListBinding 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..2178344 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectProjectTypeFragment.kt @@ -0,0 +1,37 @@ +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), 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/method/ExportContants.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportContants.java new file mode 100644 index 0000000..dedfe48 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportContants.java @@ -0,0 +1,10 @@ +package com.bingce.controlnetwork.surveyor.method; + +public class ExportContants { + /** + * 天津导出常量 0-已知点 1-未知点 + */ + public static final int TYPE_KNOWN_POINT = 0; + public static final int TYPE_UNKNOWN_POINT = 1; + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportUtilsPla.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportUtilsPla.java new file mode 100644 index 0000000..479e3ad --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportUtilsPla.java @@ -0,0 +1,1586 @@ +package com.bingce.controlnetwork.surveyor.method; + +import android.content.Context; +import android.os.Environment; +import android.text.TextUtils; + +import androidx.annotation.WorkerThread; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.ISurveyorScheduleDataSource; +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.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.surveyor.data.CachedData; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.method.ExportStationMethod; +import com.bingce.controlapphelper.surveyor.method.ExportUtils; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.newui.configfragment.SelectExportType; +import com.bingce.controlnetwork.util.CheckRegUtil; +import com.bingce.utils.DateUtils; +import com.bingce.utils.RegisterUtil; +import com.bingce.utils.Util; +import com.bingce.utils.VipManager; +import com.bingce.zip.ZipUtil; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import blankj.utilcode.util.FileUtils; +import blankj.utilcode.util.ToastUtils; + + +public class ExportUtilsPla { + private final static String NEW_LINE = "\r\n"; + private final static String SPACE = "\t"; + + private final static int ANGLE_DECIMALS = 5; //保留小数位数 + public final static int DISTANCE_DECIMALS = 5; //距离保留小数位数 + public final static int PPM_DECIMALS = 8; //ppm保留小数位数 + + public static String getExportFirstDirectory() { + return App.getApp().getString(R.string.app_name) + "导出文件"; + } + + public static String getExportSecondDirectory() { + return getExportFirstDirectory() + File.separator + "导线文件导出"; + } + + /** + * 收集需要导出的测站、测期、项目相关信息 + */ + @WorkerThread + private static Collection collect(List exportItems) { + Map projectMap = new HashMap<>(); + for (ExportItem exportItem : exportItems) { + Project project; + if (!projectMap.containsKey(exportItem.projectId)) { + project = new Project(exportItem.projectId, exportItem.projectType, exportItem.projectName); + projectMap.put(exportItem.projectId, project); + } else { + project = projectMap.get(exportItem.projectId); + } + if (project == null) { + continue; + } + SurveyorPeriod cycle; + if (!project.surveyorPeriodMap.containsKey(exportItem.cycleId)) { + cycle = new SurveyorPeriod(exportItem.cycleId, exportItem.cycleName); + project.surveyorPeriodMap.put(exportItem.cycleId, cycle); + } else { + cycle = project.surveyorPeriodMap.get(exportItem.cycleId); + } + + if (cycle == null) { + continue; + } + if (!cycle.stationMap.containsKey(exportItem.stationId)) { + Station station = new Station(exportItem.stationId, exportItem.stationPointName); + cycle.stationMap.put(exportItem.stationId, station); + } + } + return projectMap.values(); + } + + protected static List surveyorPointRecordListInAllPeriods(Project project) { + //收集所有测期下所有测站的测量点记录,用于后面导出控制点 + List surveyorPointRecordListInAllPeriods = new ArrayList<>(); + for (Map.Entry surveyorPeriodEntry : project.surveyorPeriodMap.entrySet()) { + //遍历每个测期 + SurveyorPeriod surveyorPeriod = surveyorPeriodEntry.getValue(); + for (Map.Entry stationEntry : surveyorPeriod.stationMap.entrySet()) { + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationEntry.getValue().stationId); + if (stationRecord == null) { + continue; + } + //收集测站中的测点记录 + List surveyorPointListInSingleStation = ExportStationMethod.surveyorPointRecordInSingleStation(stationRecord); + for (PointRecord record : surveyorPointListInSingleStation) { + //去重.检测对应测点是否已经记录到列表中 + boolean hasRecord = false; + for (PointRecord savedRecord : surveyorPointRecordListInAllPeriods) { + if (record.id.equals(savedRecord.id)) { + hasRecord = true; + break; + } + } + if (hasRecord) { + continue; + } + surveyorPointRecordListInAllPeriods.add(record); + } + } + } + return surveyorPointRecordListInAllPeriods; + } + + @WorkerThread + private static List collectPointFromProject(Project project) { + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + List pointList = pointDataSource.findByProjectIdSync(project.projectId); + //按照已知点在前未知点在后排序 + Collections.sort(pointList, (current, Other) -> { + if ((PointRecord.TYPE_KNOWN_POINT.equals(current.pointType) || PointRecord.TYPE_GLOBAL_POINT.equals(current.pointType)) + && PointRecord.TYPE_UNKNOWN_POINT.equals(Other.pointType)) { + //当前是已知点 比较是未知点 + return 1; + } else if (PointRecord.TYPE_UNKNOWN_POINT.equals(current.pointType) + && (PointRecord.TYPE_KNOWN_POINT.equals(Other.pointType) || PointRecord.TYPE_GLOBAL_POINT.equals(Other.pointType))) { + //当前是未知点,比较是已知点 + return -1; + } + return 0; + }); + return pointList; + } + + /** + * 导出冰测数据 + */ + @WorkerThread + private static void exportBingCe(Project project, ToleranceDetailRecord toleranceRecord, File projectCachedDir) { + +// String controlPointTxtPrint = getControlPointTxtPrint(project); +// String projectTxtPrint = getProjectTxtPrint(project); + + //读取「限差」信息 + //二级 + ToleranceLevelRecord toleranceLevelRecord = null; + if (toleranceRecord.levelId != null) { + toleranceLevelRecord = SurveyorDatabaseFactory.instance.getToleranceLevelDataSource().getRecordSync(toleranceRecord.levelId); + } + //一级 + ToleranceGroupRecord toleranceGroupRecord = null; + if (toleranceRecord.groupId != null) { + toleranceGroupRecord = SurveyorDatabaseFactory.instance.getToleranceGroupDataSource().getRecordSync(toleranceRecord.groupId); + } + + //遍历每个测期 + for (Map.Entry surveyorPeriodEntry : project.surveyorPeriodMap.entrySet()) { + //初始化天津水平角,垂直角和距离 + StringBuilder horSbTianjinOne = new StringBuilder(); + StringBuilder verSbTianjinOne = new StringBuilder(); + StringBuilder disSbTianjinOne = new StringBuilder(); + + SurveyorPeriod surveyorPeriod = surveyorPeriodEntry.getValue(); + //测站文件夹和测站文件的名称暂存map + Map stationFileNameMap = new HashMap<>(); + //创建测期文件夹 + File periodFolder = ExportStationMethod.initPeriodFolder(projectCachedDir, surveyorPeriod.periodName); + + for (Map.Entry stationEntry : surveyorPeriod.stationMap.entrySet()) { + String stationName = stationEntry.getValue().stationName; + String stationFileName = getStationFileName(stationFileNameMap, stationName); + + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationEntry.getValue().stationId); + if (stationRecord == null) { + continue; + } + //创建测站文件夹 + File stationFolder = ExportStationMethod.initStationFolder(periodFolder, stationFileName); + + //2.导出单个测站的数据 + ExportStationMethod.exportBingCeSingleStationSurveyorData( + stationFolder, + toleranceRecord, toleranceLevelRecord, toleranceGroupRecord, + stationFileName, stationName, stationRecord); + //天津收集方向值,垂直角,边长文件的数据 + collectCustomTj61365(stationName, stationRecord, toleranceRecord, horSbTianjinOne, verSbTianjinOne, disSbTianjinOne); + } + + //输出文件 + if (horSbTianjinOne.length() > 0) { + horSbTianjinOne.append("END"); + ExportStationMethod.save(horSbTianjinOne.toString(), periodFolder, "方向值.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "方向值.TXT"); + } + if (verSbTianjinOne.length() > 0) { + ExportStationMethod.save(verSbTianjinOne.toString(), periodFolder, "垂直角.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "垂直角.TXT"); + } + if (disSbTianjinOne.length() > 0) { + disSbTianjinOne.append("END"); + ExportStationMethod.save(disSbTianjinOne.toString(), periodFolder, "边长.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "边长.TXT"); + } + + exportProjectAndControlPoint(project,projectCachedDir); + } + + } + + /** + * 导出项目和控制点文件 + * + * @param project + * @param projectDir + */ + private static void exportProjectAndControlPoint(Project project, File projectDir) { + //存储已知点 + List surveyorPointRecordListInAllPeriods = surveyorPointRecordListInAllPeriods(project); + StringBuilder pointStringBuilder = new StringBuilder(); + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + if (PointRecord.TYPE_KNOWN_POINT.equals(pointRecord.pointType) || + PointRecord.TYPE_GLOBAL_POINT.equals(pointRecord.pointType)) { + pointStringBuilder + .append(pointRecord.getName()) + .append(",") + .append(pointRecord.getXFormat(4)) + .append(",") + .append(pointRecord.getYFormat(4)) + .append(",") + .append(pointRecord.getZFormat(4)) + .append("\n"); + } + } + //导出控制点文件 + ExportStationMethod.save(pointStringBuilder.toString(), projectDir, "controlpoint.TXT"); + //导出项目名称和项目类型文件 + ExportStationMethod.save(project.projectName + "," + project.projectType + "\n", projectDir, "project.TXT"); + } + + private static String getControlPointTxtPrint(Project project) { + List surveyorPointRecordListInAllPeriods = collectPointFromProject(project); + StringBuilder pointStringBuilder = new StringBuilder(); + + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + + pointStringBuilder + .append(pointRecord.getName()) + .append(",") + .append("") + .append(",") + .append(ExportStationMethod.getXyzFormat(pointRecord.getX())) + .append(",") + .append(ExportStationMethod.getXyzFormat(pointRecord.getY())) + .append(",") + .append(ExportStationMethod.getXyzFormat(pointRecord.getZ())) + .append(",") + .append(pointRecord.getLongitude()) + .append(",") + .append(pointRecord.getLatitude()) + .append(",") + .append(getPointTypeForTianjin(pointRecord.getPointType())); + + pointStringBuilder.append("\n"); + } + return pointStringBuilder.toString(); + } + + @WorkerThread + private static String getProjectTxtPrint(Project project) { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); +// ProjectRecord projectRecord = projectDataSource.getRecord(project.projectId); + + return project.projectName + + "," + + getProjectTypeForTianjin(project.projectType) + + "\n"; + + } + + + /** + * nameMap主要是为了避免同一测期下测站重复的问题 + * 比如闭合导线,存在某点充当多次站点的情况 + * 通过nameMap为后面的station添加一个'-x'后缀 + * + * @param nameMap + * @param stationName + * @return + */ + private static String getStationFileName(Map nameMap, String stationName) { + if (nameMap.containsKey(stationName)) { + Integer obj = nameMap.get(stationName); + if (obj != null) { + int count = obj + 1; + nameMap.put(stationName, count); + stationName = stationName + "_" + count; + } + } else { + nameMap.put(stationName, 0); + } + return stationName; + } + + /** + * 收集边长,垂直角,方向值文件的数据 + * + * @param stationName + * @param stationRecord + * @param toleranceRecord + * @param horSbTianjinOne + * @param verSbTianjinOne + * @param disSbTianjinOne + */ + @WorkerThread + private static void collectCustomTj61365(String stationName, SurveyorStationRecord stationRecord, ToleranceDetailRecord toleranceRecord, + StringBuilder horSbTianjinOne, StringBuilder verSbTianjinOne, + StringBuilder disSbTianjinOne) { +// if (stationRecord.isSeparateObservation()) { +// collectAloneHorAngleTjUnique(stationName, stationRecord, toleranceRecord, horSbTianjinOne); +// } else { +// collectCombineAngleDistanceTjUnique(stationName, stationRecord, toleranceRecord, horSbTianjinOne, verSbTianjinOne, disSbTianjinOne); +// } + collectCombineAngleDistanceTjUnique(stationName, stationRecord, toleranceRecord, horSbTianjinOne, verSbTianjinOne, disSbTianjinOne); + collectAloneDistanceTjUnique(stationName, stationRecord, toleranceRecord, disSbTianjinOne); + } + + /** + * 收集合并观测的水平角,垂直角和距离 + * 距离可能存在单独测距 + */ + private static void collectCombineAngleDistanceTjUnique(String stationName, SurveyorStationRecord stationRecord, ToleranceDetailRecord toleranceRecord, + StringBuilder horSbTianjinOne, StringBuilder verSbTianjinOne, + StringBuilder disSbTianjinOne) { + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationRecord.getId(), toleranceRecord); + + //测距测角的平差结果 + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (adjustResult.errorString == null || adjustResult.errorString.isEmpty()) { + //水平角 + horSbTianjinOne.append(stationName).append(SPACE).append(formatHeight(Double.parseDouble(stationRecord.getInstrumentHeight()))).append(SPACE); + + StringBuilder verSbTianjinEveryStation = new StringBuilder(); + int verEverySurveyorPoint = 0; + //遍历测站测点 + for (int i = 0; i < adjustResult.result.size(); i++) { + SurveyorAdjustMethod.Item item = adjustResult.result.get(i); + //水平角 + String exportHorAngle = ExportStationMethod.radianToDmsForTj61365(item.getHorAngle(), true); + if (i != 0) { + horSbTianjinOne.append(SPACE).append(SPACE); + } + horSbTianjinOne.append(item.getPointName()).append(SPACE).append(exportHorAngle).append(SPACE).append(formatHeight(item.getPrismHeight())); + horSbTianjinOne.append(NEW_LINE); + + verEverySurveyorPoint++; + String exportVerAngle = ExportStationMethod.radianToDmsForTj61365(item.getVerAngle(), false); + verSbTianjinEveryStation.append(item.getPointName()).append(SPACE).append(exportVerAngle).append(SPACE).append(formatHeight(Double.parseDouble(stationRecord.getInstrumentHeight()))) + .append(SPACE).append(formatHeight(item.getPrismHeight())); + verSbTianjinEveryStation.append(NEW_LINE); + + double distance = item.getDistance(); + if (distance > 0) { + appendAloneDistance(disSbTianjinOne, stationName, item.getPointName(), distance, + Double.parseDouble(stationRecord.getInstrumentHeightDeal()), String.valueOf(item.getPrismHeight())); + } + } + + if (verEverySurveyorPoint > 0) { + verSbTianjinOne.append(stationName).append(SPACE).append(verEverySurveyorPoint).append(NEW_LINE); + verSbTianjinOne.append(verSbTianjinEveryStation); + } + + } + } + + /** + * 收集天津边长数据 + * 合并观测和分开观测的单独测距 + */ + private static void collectAloneDistanceTjUnique(String stationName, SurveyorStationRecord stationRecord, + ToleranceDetailRecord toleranceRecord, StringBuilder disSbTianjinOne) { + SurveyorAdjustMethod.calAloneDistance(stationRecord.getId(), + CachedDataAloneDistance.newInstance(stationRecord.getId()), new SurveyorAdjustMethod.ICallback() { + @Override + public void onGet(ArrayList adjustResult, Boolean isShowSlopDistance) { + if (!adjustResult.isEmpty()) { + for (SurveyorAdjustMethod.Item item : adjustResult) { + appendAloneDistance(disSbTianjinOne, stationName, item.getPointName(), item.getDistance(), + Double.parseDouble(stationRecord.getInstrumentHeightDeal()), String.valueOf(item.getPrismHeight())); + } + } + } + + @Override + public void onFailure(String error) { + + } + }); + } + + private static void appendAloneDistance(StringBuilder disSbTianjinOne, String stationName, String pointName, double distance, + double instrumentHeight, String prismHeight) { + disSbTianjinOne.append(stationName).append(SPACE).append(pointName).append(SPACE) + .append(Tools.formatDouble2String(distance, 4)) + .append(SPACE).append(formatHeight(instrumentHeight)) + .append(SPACE).append(formatHeight(Double.parseDouble(prismHeight))); + disSbTianjinOne.append(NEW_LINE); + } + + /** + * 导出科傻数据 + */ + @WorkerThread + private static void exportKeSha(Project project, + ToleranceDetailRecord toleranceRecord, File projectCachedDir) { + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + StringBuilder ksStringBuilder = new StringBuilder(); + ksStringBuilder.append("3.5,5,5").append(NEW_LINE);//限差使用默认值 + + //存储已知点 + List surveyorPointRecordListInAllPeriods = surveyorPointRecordListInAllPeriods(project); + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + if (PointRecord.TYPE_KNOWN_POINT.equals(pointRecord.pointType) || + PointRecord.TYPE_GLOBAL_POINT.equals(pointRecord.pointType)) { + ksStringBuilder + .append(pointRecord.getName()) + .append(",") + .append(pointRecord.getX()) + .append(",") + .append(pointRecord.getY()) + .append(NEW_LINE); + } + } + //存储其他数据 + for (Map.Entry cycleEntry : project.surveyorPeriodMap.entrySet()) { + SurveyorPeriod cycle = cycleEntry.getValue(); + String cycleName = cycle.periodName.replace(":", "_"); + File cycleDir = new File(projectCachedDir, cycleName); + try { + if (!cycleDir.exists()) { + cycleDir.mkdir(); + } + } catch (Exception ignore) { + continue; + } + for (Map.Entry stationEntry : cycle.stationMap.entrySet()) { + String stationId = stationEntry.getValue().stationId; + String stationName = stationEntry.getValue().stationName; + //读取测站信息 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + continue; + } + cachedData.onShowSlopDistance(false);//平距 + + //计算平差数据 + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (TextUtils.isEmpty(adjustResult.errorString)) { + ksStringBuilder.append(stationName).append(NEW_LINE); + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + ksStringBuilder + .append(item.getPointName()) + .append(",L,") + .append(ExportStationMethod.radianToDmsDouble(item.getHorAngle())) + .append(NEW_LINE); + } + + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + //这里兼容下钢丝测距的距离 + String pointName = item.getPointName(); + + double distance = 0; + + if (!TextUtils.equals(ProjectTypeValue.CONNECTION, stationRecord.projectType)) { + distance = item.getDistance(); + } else { + Map wellAverageDistanceMap = ExportStationMethod.getWellAverageDistanceFromStation(stationRecord); + if (wellAverageDistanceMap != null && wellAverageDistanceMap.containsKey(pointName)) { + distance = wellAverageDistanceMap.get(pointName); + } + if (distance == 0) { + distance = item.getDistance(); + } + } + + ksStringBuilder + .append(pointName) + .append(",S,") + .append(distance) + .append(NEW_LINE); + } + } + + + } + ExportStationMethod.save(ksStringBuilder.toString(), cycleDir, cycleName + ".in2"); + } + } + + /** + * 导出南方平差仪数据 .txt文件 + */ + @WorkerThread + private static void exportSouthAdjustment(Project project, + ToleranceDetailRecord toleranceRecord, File projectCachedDir) { + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + StringBuilder printSb = new StringBuilder(); + + //[NET]部分 + printSb.append(NEW_LINE); + printSb.append("[NET]"); + printSb.append("Name:" + project.projectName); + printSb.append(NEW_LINE); + printSb.append("Organ:SOUTH SURVEY"); + printSb.append(NEW_LINE); + printSb.append("Obser:SOUTH"); + printSb.append(NEW_LINE); + printSb.append("Computer:SOUTH"); + printSb.append(NEW_LINE); + printSb.append("Recorder:SOUTH"); + printSb.append(NEW_LINE); + printSb.append("Remark:" + project.projectName); + printSb.append(NEW_LINE); + printSb.append("Software:南方平差易2002"); + printSb.append(NEW_LINE); + //[PARA]部分 + printSb.append("[PARA]"); + printSb.append(NEW_LINE); + printSb.append("MO:2.5"); + printSb.append(NEW_LINE); + printSb.append("MS:5.0"); + printSb.append(NEW_LINE); + printSb.append("MR:5.0"); + printSb.append(NEW_LINE); + printSb.append("DistanceError:0.0000"); + printSb.append(NEW_LINE); + printSb.append("DistanceMethod:0"); + printSb.append(NEW_LINE); + printSb.append("LevelMethod:0"); + printSb.append(NEW_LINE); + printSb.append("Mothed:1"); + printSb.append(NEW_LINE); + printSb.append("LevelTrigon:0"); + printSb.append(NEW_LINE); + printSb.append("TrigonObser:1"); + printSb.append(NEW_LINE); + printSb.append("Times:1"); + printSb.append(NEW_LINE); + printSb.append("Level:4"); + printSb.append(NEW_LINE); + printSb.append("Level1:2"); + printSb.append(NEW_LINE); + printSb.append("Limit:3"); + printSb.append(NEW_LINE); + printSb.append("Format:1"); + printSb.append(NEW_LINE); + //[STATION]部分 + printSb.append("[STATION]"); + printSb.append(NEW_LINE); + //存储已知点 + List surveyorPointRecordListInAllPeriods = surveyorPointRecordListInAllPeriods(project); + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + + printSb.append(pointRecord.getName() + ","); + + switch (pointRecord.pointType) { + case PointRecord.TYPE_KNOWN_POINT: + printSb.append("10"); + break; + default: + printSb.append("00"); + break; + } + printSb.append(","); + printSb.append(ExportStationMethod.getXyzFormat(pointRecord.getX())); + printSb.append(","); + printSb.append(ExportStationMethod.getXyzFormat(pointRecord.getY())); + printSb.append(",,,,"); + printSb.append(NEW_LINE); + } + //[OBSER]部分 + printSb.append("[OBSER]"); + printSb.append(NEW_LINE); + + for (Map.Entry cycleEntry : project.surveyorPeriodMap.entrySet()) { + SurveyorPeriod cycle = cycleEntry.getValue(); + String cycleName = cycle.periodName.replace(":", "_"); + File cycleDir = new File(projectCachedDir, cycleName); + try { + if (!cycleDir.exists()) { + cycleDir.mkdir(); + } + } catch (Exception ignore) { + continue; + } + + StringBuilder stationSb = new StringBuilder(); + + for (Map.Entry stationEntry : cycle.stationMap.entrySet()) { + String stationId = stationEntry.getValue().stationId; + String stationName = stationEntry.getValue().stationName; + //读取测站信息 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + continue; + } + cachedData.onShowSlopDistance(false); + + //计算平差数据 + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (TextUtils.isEmpty(adjustResult.errorString)) { + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + //这里兼容下钢丝测距的距离 + String pointName = item.getPointName(); + + double distance = 0; + + if (!TextUtils.equals(ProjectTypeValue.CONNECTION, stationRecord.projectType)) { + distance = item.getDistance(); + } else { + Map wellAverageDistanceMap = ExportStationMethod.getWellAverageDistanceFromStation(stationRecord); + if (wellAverageDistanceMap != null && wellAverageDistanceMap.containsKey(pointName)) { + distance = wellAverageDistanceMap.get(pointName); + } + if (distance == 0) { + distance = item.getDistance(); + } + } + + stationSb.append(stationName).append(",") + .append(item.getPointName()).append(",") + .append(ExportStationMethod.radianToDmsDouble(item.getHorAngle())) + .append(",") + .append(distance) + .append(",,,,,,,") + .append(NEW_LINE); + } + } + + } + + printSb.append(stationSb); + + ExportStationMethod.save(printSb.toString(), cycleDir, cycleName + ".txt"); + } + } + + /** + * 导出启飞数据 .kzw文件 + */ + @WorkerThread + private static void exportOpenFly(Project project, + ToleranceDetailRecord toleranceRecord, File projectCachedDir) { + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + StringBuilder printSb = new StringBuilder(); + + printSb.append("控制测量优化设计与平差计算文件"); + printSb.append(NEW_LINE); + printSb.append("300"); + printSb.append(NEW_LINE); + printSb.append("[全网属性]"); + printSb.append(NEW_LINE); + printSb.append("网名:" + project.projectName); + printSb.append(NEW_LINE); + printSb.append("是否优化:0"); + printSb.append(NEW_LINE); + printSb.append("HELMERT定权:0"); + printSb.append(NEW_LINE); + printSb.append("测角中误差:2.500000"); + printSb.append(NEW_LINE); + printSb.append("测距定权方式:0"); + printSb.append(NEW_LINE); + printSb.append("测距A值:50.000000"); + printSb.append(NEW_LINE); + printSb.append("测距B值:0.000000"); + printSb.append(NEW_LINE); + printSb.append("高程类型:0"); + printSb.append(NEW_LINE); + printSb.append("水准定权方式:0"); + printSb.append(NEW_LINE); + printSb.append("三角高程测距形式:0"); + printSb.append(NEW_LINE); + printSb.append("是否由斜距计算平距:1"); + printSb.append(NEW_LINE); + printSb.append("大气折光:0.140000"); + printSb.append(NEW_LINE); + printSb.append("高程单位权:10.000000"); + printSb.append(NEW_LINE); + printSb.append("坐标系:0"); + printSb.append(NEW_LINE); + printSb.append("是否含500:0"); + printSb.append(NEW_LINE); + printSb.append("是否高程归化:0"); + printSb.append(NEW_LINE); + printSb.append("归算高程面:0.000000"); + printSb.append(NEW_LINE); + printSb.append("图数更新方式:0"); + printSb.append(NEW_LINE); + printSb.append("平面网等级:2"); + printSb.append(NEW_LINE); + printSb.append("高程网等级:2"); + printSb.append(NEW_LINE); + printSb.append("三角形限差:9.000000"); + printSb.append(NEW_LINE); + printSb.append("方位角限差:5.000000"); + printSb.append(NEW_LINE); + printSb.append("导线段相对闭合差限差:35000"); + printSb.append(NEW_LINE); + printSb.append("高差闭合差限差:20.000000"); + printSb.append(NEW_LINE); + printSb.append("角度取位:1"); + printSb.append(NEW_LINE); + printSb.append("边长取位:3"); + printSb.append(NEW_LINE); + printSb.append("高差取位:3"); + printSb.append(NEW_LINE); + printSb.append("坐标取位:3"); + printSb.append(NEW_LINE); + printSb.append("高程取位:3"); + printSb.append(NEW_LINE); + printSb.append("已知点类型:0"); + printSb.append(NEW_LINE); + printSb.append("未知点类型:3"); + printSb.append(NEW_LINE); + printSb.append("图形比例:1000.000000"); + printSb.append(NEW_LINE); + printSb.append("椭圆比例:5.000000"); + printSb.append(NEW_LINE); + printSb.append("END"); + printSb.append(NEW_LINE); + //获取点记录 + List surveyorPointRecordListInAllPeriods = surveyorPointRecordListInAllPeriods(project); + //已知点 + printSb.append("[已知点]"); + printSb.append(NEW_LINE); + StringBuilder sbKnow = new StringBuilder(); + int knowCount = 0; + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null || !TextUtils.equals(pointRecord.pointType, PointRecord.TYPE_KNOWN_POINT)) { + continue; + } + ++knowCount; + sbKnow.append(pointRecord.getName() + ","); + sbKnow.append(ExportStationMethod.getXyzFormat(pointRecord.getX())); + sbKnow.append(","); + sbKnow.append(ExportStationMethod.getXyzFormat(pointRecord.getY())); + sbKnow.append(",,"); + sbKnow.append(NEW_LINE); + } + printSb.append(knowCount); + printSb.append(NEW_LINE); + printSb.append(sbKnow); + printSb.append("END"); + printSb.append(NEW_LINE); + //固定条件 + printSb.append("[固定条件]"); + printSb.append(NEW_LINE); + printSb.append("0"); + printSb.append(NEW_LINE); + printSb.append("END"); + printSb.append(NEW_LINE); + //控制点 + printSb.append("[控制点]"); + printSb.append(NEW_LINE); + StringBuilder sbControl = new StringBuilder(); + int controlCount = 0; + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + ++controlCount; + sbControl.append(pointRecord.getName() + ","); + sbControl.append(ExportStationMethod.getXyzFormat(pointRecord.getX())); + sbControl.append(","); + sbControl.append(ExportStationMethod.getXyzFormat(pointRecord.getY())); + sbControl.append(","); + sbControl.append(NEW_LINE); + } + printSb.append(controlCount); + printSb.append(NEW_LINE); + printSb.append(sbControl); + printSb.append("END"); + printSb.append(NEW_LINE); + //[测站数据] + printSb.append("[测站数据]"); + printSb.append(NEW_LINE); + + for (Map.Entry cycleEntry : project.surveyorPeriodMap.entrySet()) { + SurveyorPeriod cycle = cycleEntry.getValue(); + String cycleName = cycle.periodName.replace(":", "_"); + File cycleDir = new File(projectCachedDir, cycleName); + try { + if (!cycleDir.exists()) { + cycleDir.mkdir(); + } + } catch (Exception ignore) { + continue; + } + + StringBuilder stationSb = new StringBuilder(); + Map> tempDataMap = new LinkedHashMap<>(); + + for (Map.Entry stationEntry : cycle.stationMap.entrySet()) { + String stationId = stationEntry.getValue().stationId; + String stationName = stationEntry.getValue().stationName; + //读取测站信息 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + continue; + } + cachedData.onShowSlopDistance(false); + + //计算平差数据 + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (TextUtils.isEmpty(adjustResult.errorString)) { + stationSb.append(cycle.stationMap.keySet().size()); + stationSb.append(NEW_LINE); + + stationSb.append(stationName).append(",").append(adjustResult.result.size()).append(",").append(NEW_LINE); + stationSb.append("照准点").append(NEW_LINE); + + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + //这里兼容下钢丝测距的距离 + String pointName = item.getPointName(); + + double distance = 0; + + if (!TextUtils.equals(ProjectTypeValue.CONNECTION, stationRecord.projectType)) { + distance = item.getDistance(); + } else { + Map wellAverageDistanceMap = ExportStationMethod.getWellAverageDistanceFromStation(stationRecord); + if (wellAverageDistanceMap != null && wellAverageDistanceMap.containsKey(pointName)) { + distance = wellAverageDistanceMap.get(pointName); + } + if (distance == 0) { + distance = item.getDistance(); + } + } + + stationSb + .append(item.getPointName()).append(",") + .append(Tools.radianToDmsString(item.getHorAngle(), 2, true)) + .append(",") + .append(distance) + .append(",,,,") + .append(NEW_LINE); + + } + + stationSb.append("照准点结束").append(NEW_LINE); + } + } + + stationSb.append("END").append(NEW_LINE); + printSb.append(stationSb); + + printSb.append("[点间数据]"); + printSb.append(NEW_LINE); + printSb.append("0"); + printSb.append(NEW_LINE); + printSb.append("END"); + printSb.append(NEW_LINE); + printSb.append("[导线段数据]"); + printSb.append(NEW_LINE); + printSb.append("0"); + printSb.append(NEW_LINE); + printSb.append("END"); + + ExportStationMethod.save(printSb.toString(), cycleDir, cycleName + ".kzw"); + } + } + + + @WorkerThread + private static File exportSingleProject(Context context, Project project, ArrayList selectExportTypeList) { + //读取项目信息 + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + ProjectRecord projectRecord = projectDataSource.getRecord(project.projectId); + if (projectRecord == null) { + return null; + } + //读取限差信息 + String toleranceId = projectRecord.getToleranceId(); + IToleranceDetailDataSource toleranceDataSource = SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + ToleranceDetailRecord toleranceRecord = toleranceDataSource.getRecordSync(toleranceId); + if (toleranceRecord == null) { + return null; + } + + //需要导出的project目录 + File projectDir = new File(context.getExternalCacheDir(), projectRecord.getProjectName()); + if (!projectDir.exists()) { + if (!projectDir.mkdir()) { + return null; + } + } + + if (selectExportTypeList == null) { + return null; + } + + for (SelectExportType exportType : selectExportTypeList) { + if (SelectExportType.TYPE_CONTROL.equals(exportType.getType())) { + exportBingCe(project, toleranceRecord, projectDir); + } else if (SelectExportType.TYPE_KE_SHA.equals(exportType.getType())) { + exportKeSha(project, toleranceRecord, projectDir); + } else if (SelectExportType.TYPE_NAN_FANG.equals(exportType.getType())) { + exportSouthAdjustment(project, toleranceRecord, projectDir); + } else if (SelectExportType.TYPE_QI_FEI.equals(exportType.getType())) { + exportOpenFly(project, toleranceRecord, projectDir); + } else if (SelectExportType.TYPE_PING_CHA_ZHI_XING.equals(exportType.getType())) { + exportPingChaZhiXing(project, toleranceRecord, projectDir); + } + } + + ExportStationMethod.save( + DateUtils.toFull(new Date()) + "\n" + Tools.getVersionName(), + projectDir, + ".bc"); + + return projectDir; + } + + @WorkerThread + private static File exportSingleHeightTraverseProject(Context context, Project project) { + //读取项目信息 + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + ProjectRecord projectRecord = projectDataSource.getRecord(project.projectId); + if (projectRecord == null) { + return null; + } + //读取限差信息 + String toleranceId = projectRecord.getToleranceId(); + IToleranceDetailDataSource toleranceDataSource = SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + ToleranceDetailRecord toleranceRecord = toleranceDataSource.getRecordSync(toleranceId); + if (toleranceRecord == null) { + return null; + } + + //需要导出的project目录 + File projectDir = new File(context.getExternalCacheDir(), projectRecord.getProjectName()); + if (!projectDir.exists()) { + if (!projectDir.mkdirs()) { + return null; + } + } + + //高程导线 + exportBingceHeightTraverse(project, toleranceRecord, projectDir); + return projectDir; + } + + @WorkerThread + private static void exportBingceHeightTraverse(Project project, ToleranceDetailRecord toleranceRecord, File projectDir) { + try { + StringBuilder dxrBuilder = new StringBuilder(); + //遍历每个路线 + for (Map.Entry surveyorPeriodEntry : project.surveyorPeriodMap.entrySet()) { + ExportUtilsPla.SurveyorPeriod surveyorPeriod = surveyorPeriodEntry.getValue(); + ExportStationMethod.exportBingCeSingleStationSurveyorDataHeightTraverse( + projectDir, + toleranceRecord, + project.projectId, + surveyorPeriod.periodId, surveyorPeriod.periodName); + + StringBuilder dxrBuilderEveryRoute = ExportStationMethod.exportRouteDxrData(toleranceRecord, project.projectId, surveyorPeriod.periodId); + dxrBuilder.append(dxrBuilderEveryRoute).append(NEW_LINE); + } + //存储dxr + ExportStationMethod.save(dxrBuilder.toString(), projectDir, project.projectName + ".dxr"); + exportProjectAndControlPoint(project, projectDir); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 导出平差之星 + */ + private static void exportPingChaZhiXing(Project project, ToleranceDetailRecord toleranceRecord, File projectDir) { + //读取「限差」信息 + //二级 + ToleranceLevelRecord toleranceLevelRecord = null; + if (toleranceRecord.levelId != null) { + toleranceLevelRecord = SurveyorDatabaseFactory.instance.getToleranceLevelDataSource().getRecordSync(toleranceRecord.levelId); + } + //一级 + ToleranceGroupRecord toleranceGroupRecord = null; + if (toleranceRecord.groupId != null) { + toleranceGroupRecord = SurveyorDatabaseFactory.instance.getToleranceGroupDataSource().getRecordSync(toleranceRecord.groupId); + } + + //遍历每个测期 + for (Map.Entry surveyorPeriodEntry : project.surveyorPeriodMap.entrySet()) { + //初始化天津水平角,垂直角和距离 + StringBuilder horSbTianjinOne = new StringBuilder(); + StringBuilder verSbTianjinOne = new StringBuilder(); + StringBuilder disSbTianjinOne = new StringBuilder(); + + SurveyorPeriod surveyorPeriod = surveyorPeriodEntry.getValue(); + //测站文件夹和测站文件的名称暂存map + Map stationFileNameMap = new HashMap<>(); + //创建测期文件夹 + File periodFolder = ExportStationMethod.initPeriodFolder(projectDir, surveyorPeriod.periodName); + + for (Map.Entry stationEntry : surveyorPeriod.stationMap.entrySet()) { + String stationName = stationEntry.getValue().stationName; + String stationFileName = getStationFileName(stationFileNameMap, stationName); + + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationEntry.getValue().stationId); + if (stationRecord == null) { + continue; + } + //创建测站文件夹 + File stationFolder = ExportStationMethod.initStationFolder(periodFolder, stationFileName); + + //2.导出单个测站的数据 + ExportStationMethod.exportBingCeSingleStationSurveyorData( + stationFolder, + toleranceRecord, toleranceLevelRecord, toleranceGroupRecord, + stationFileName, stationName, stationRecord); + //天津收集方向值,垂直角,边长文件的数据 + collectCustomTj61365(stationName, stationRecord, toleranceRecord, horSbTianjinOne, verSbTianjinOne, disSbTianjinOne); + } + + //输出文件 + if (horSbTianjinOne.length() > 0) { + horSbTianjinOne.append("END"); + ExportStationMethod.save(horSbTianjinOne.toString(), periodFolder, "方向值.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "方向值.TXT"); + } + if (verSbTianjinOne.length() > 0) { + ExportStationMethod.save(verSbTianjinOne.toString(), periodFolder, "垂直角.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "垂直角.TXT"); + } + if (disSbTianjinOne.length() > 0) { + disSbTianjinOne.append("END"); + ExportStationMethod.save(disSbTianjinOne.toString(), periodFolder, "边长.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "边长.TXT"); + } + } + } + + /** + * 根据项目列表导出测量数据,所有文件导出到一个zip文件中 + */ + @WorkerThread + private static File exportAllProject(Context context, Collection projects, ArrayList selectExportTypeList) { + List zipList = new ArrayList<>(); + for (Project project : projects) { + File zip = exportSingleProject(context, project, selectExportTypeList); + if (zip == null) { + continue; + } + zipList.add(zip); + } + //将文件存储到一个zip中 + File fileParent = Environment.getExternalStorageDirectory(); + File fileOutput = new File(fileParent, getExportFirstDirectory()); + if (!fileOutput.exists()) { + fileOutput.mkdir(); + } +// File fileOutput = PathManager.shareFolder(); + 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(fileOutput, dateString + ".zip"); + if (!ZipUtil.zip(zip, zipList)) { + ToastUtils.showShort(R.string.export_failure); + zip = null; + } + //存储成功,删除被压缩的文件 + for (File file : zipList) { + if (file == null) { + continue; + } + try { + if (file.isDirectory()) { + FileUtils.delete(file); + } else if (file.isFile()) { + file.delete(); + } + } catch (Exception ignored) { + } + } + return zip; + } + + /** + * 根据项目列表导出测量数据,所有文件导出到一个zip文件中 + */ + @WorkerThread + private static File exportAllHeightTraverseProject(Context context, Collection projects) { + List zipList = new ArrayList<>(); + for (Project project : projects) { + File zip = exportSingleHeightTraverseProject(context, project); + if (zip == null) { + continue; + } + zipList.add(zip); + } + //将文件存储到一个zip中 + File fileParent = Environment.getExternalStorageDirectory(); + File fileOutput = new File(fileParent, getExportFirstDirectory()); + if (!fileOutput.exists()) { + fileOutput.mkdir(); + } +// File fileOutput = PathManager.shareFolder(); + 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(fileOutput, dateString + ".zip"); + if (!ZipUtil.zip(zip, zipList)) { + ToastUtils.showShort(R.string.export_failure); + zip = null; + } + //存储成功,删除被压缩的文件 + for (File file : zipList) { + if (file == null) { + continue; + } + try { + if (file.isDirectory()) { + FileUtils.delete(file); + } else if (file.isFile()) { + file.delete(); + } + } catch (Exception ignored) { + } + } + return zip; + } + + /** + * 根据从UI收集的数据,执行导出操作,所有数据导出到一个zip文件中 + */ + @WorkerThread + public static File doExport(Context context, List exportItems, ArrayList selectExportTypeList) { + Collection projects = collect(exportItems); + return exportAllProject(context, projects, selectExportTypeList); + } + + /** + * 根据从UI收集的数据,执行导出操作,所有数据导出到一个zip文件中 + */ + @WorkerThread + public static File doExportHeightTraverse(Context context, List exportItems) { + Collection projects = collect(exportItems); + return exportAllHeightTraverseProject(context, projects); + } + + /** + * 导线文件导出 + * 一个项目测期的导线对应一个文件 + */ + @WorkerThread + public static List doExportWire(Context context, List exportItems, String exportFolder) { + List exportList = new ArrayList<>(); + if (exportItems == null || exportItems.isEmpty()) { + return exportList; + } + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + IToleranceDetailDataSource toleranceDetailDataSource = SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + ISurveyorStationDataSource surveyorStationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + ISurveyorScheduleDataSource surveyorScheduleDataSource = SurveyorDatabaseFactory.instance.getScheduleDataSource(); + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + ILineRecordDataSource lineRecordDatabase = SurveyorDatabaseFactory.instance.getLineRecordDatabase(); + + + //一个导线一个文件 + boolean isExportSuccess = false; + + for (ExportItem exportItem : exportItems) { + + //校验只能导出导线 + LineRecord lineRecord = lineRecordDatabase.findById(exportItem.stationId);//exportItem.stationId指的的线id + if (TextUtils.equals(lineRecord.type, LineRecord.TYPE_MUL_ANGLE)) { + continue; + } + + //exportItem.stationId这里的id是导线的id 为了复用之前的数据模型 + List stationRecordList = surveyorStationDataSource.getDataListByLine(exportItem.stationId); + + List unknowPointList = pointDataSource.getListByProjectId(exportItem.projectId, PointRecord.TYPE_UNKNOWN_POINT); + List knowPointList = pointDataSource.getListByProjectId(exportItem.projectId, PointRecord.TYPE_KNOWN_POINT); + + StringBuilder printSb = new StringBuilder(); + printSb.append("[PARA]"); + printSb.append(NEW_LINE); + + switch (lineRecord.type) { + case LineRecord.TYPE_LINE_SINGLE: + printSb.append("支导线,0,"); + break; + case LineRecord.TYPE_LINE_ATTACH: + printSb.append("附合导线,2,"); + break; + case LineRecord.TYPE_LINE_CLOSE: + printSb.append("闭合导线,1,"); + break; + case LineRecord.TYPE_LINE_RANDOM: + printSb.append("无定向导线,3,"); + break; + default: + break; + } + printSb.append(unknowPointList.size()); + printSb.append(NEW_LINE); + printSb.append("[CONTROL]"); + printSb.append(NEW_LINE); + + for (int i = 0; i < knowPointList.size(); i++) { + PointRecord knowPoint = knowPointList.get(i); + printSb.append(knowPoint.name + "," + + ExportStationMethod.getXyzFormat(knowPoint.getX()) + "," + + ExportStationMethod.getXyzFormat(knowPoint.getY()) + "," + + ExportStationMethod.getXyzFormat(knowPoint.getZ())); + printSb.append(NEW_LINE); + } + + printSb.append("[OBSER]"); + printSb.append(NEW_LINE); + + //遍历测站 + for (int i = 0; i < stationRecordList.size(); i++) { + SurveyorStationRecord stationRecord = stationRecordList.get(i); + + List items = stationRecord.getItems(); + + double stationDeviceHeight = SurveyorPoint.getDoubleValueFromString(stationRecord.instrumentHeight); + SurveyorPoint lookPoint = items.get(items.size() - 1); + double prismHeight = SurveyorPoint.getDoubleValueFromString(lookPoint.getPrismHeight()); + + PointRecord pointRecord = pointDataSource.findByIdSync(items.get(0).getPointId()); + + + ProjectRecord projectRecord = projectDataSource.getRecord(exportItem.projectId); + ToleranceDetailRecord toleranceRecord = toleranceDetailDataSource.getRecordSync(projectRecord.getToleranceId()); + + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationRecord.getId(), toleranceRecord); + + + final double[] horAngle = new double[1]; + final double[] verAngle = new double[1]; + final double[] distance = new double[1]; + + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (TextUtils.isEmpty(adjustResult.errorString)) { + //展示结果数据 + //检测归零值是否为负,如果是需要+2PI + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + if (item.getHorAngle() < 0) { + item.setHorAngle(Math.PI * 2 + item.getHorAngle()); + } + } + SurveyorAdjustMethod.Item item = adjustResult.result.get(adjustResult.result.size() - 1); + horAngle[0] = item.getHorAngle(); + verAngle[0] = item.getVerAngle(); + distance[0] = item.getDistance(); + } + + //水平角 保留5位小数 + String horAngleOutPut = Util.formatDouble2String(Util.radianToDmsDouble(horAngle[0]), ANGLE_DECIMALS); + + printSb + .append(pointRecord.getName()) + .append(","); + + + if (i == 0 || i != stationRecordList.size() - 1) { + //平距 + double horDistance = getHorDistance(verAngle[0], distance[0]); + String horDistanceOutput = Util.formatDouble2String(horDistance, ANGLE_DECIMALS); + //高差 + double altitudeDifference = getAltitudeDifference(verAngle[0], distance[0], stationDeviceHeight, prismHeight); + String altitudeDifferenceOutput = Util.formatDouble2String(altitudeDifference, ANGLE_DECIMALS); + + appendHorAngle(printSb, horAngleOutPut); + printSb + .append(",") + .append(horDistanceOutput) //斜距distance[0] 改为平距 + .append(",") + .append(altitudeDifferenceOutput) //高差 + .append(",") + .append(horDistanceOutput); //平距 + } else { + //最后一个 + if (TextUtils.equals(lineRecord.type, LineRecord.TYPE_LINE_CLOSE) + || TextUtils.equals(lineRecord.type, LineRecord.TYPE_LINE_ATTACH)) { + appendHorAngle(printSb, horAngleOutPut); + } + printSb.append(",,,"); + } + + printSb.append(NEW_LINE); + + if (TextUtils.equals(lineRecord.type, LineRecord.TYPE_LINE_SINGLE)) { + PointRecord pointRecordLast = pointDataSource.findByIdSync(items.get(2).getPointId()); + printSb.append(pointRecordLast.getName()) + .append(",,,,"); + printSb.append(NEW_LINE); + } + + + } + + printSb.append("[END]"); + + String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath(); + File fileDir = new File(absolutePath, exportFolder); + + String exportFirstName = exportItem.projectName + "_" + exportItem.cycleName + "_" + exportItem.stationName; + + String fileName = exportFirstName + ".dxp"; + fileName = fileName.replaceAll(":", "_"); +// FileUtil.writeString(printSb.toString(), new File(FileUtil.getSDPath()+"/234/"+fileName)); + + ExportStationMethod.save(printSb.toString(), fileDir, fileName); + + File fileHint = new File(fileDir, fileName); + if (fileHint.exists() && fileHint.length() > 0) { + //一个文件导出成功就算成功了 + exportList.add(fileHint); + isExportSuccess = true; + } + } + + return exportList; + + } + + /** + * 添加水平角 + * + * @param sb + * @param horAngleOutPut + */ + private static void appendHorAngle(StringBuilder sb, String horAngleOutPut) { + if (!TextUtils.isEmpty(horAngleOutPut) && !TextUtils.equals("0.00000", horAngleOutPut)) { + sb.append(horAngleOutPut); + } + } + + /** + * 返回平距 + * + * @param verAngle + * @param distance + * @return + */ + private static double getHorDistance(double verAngle, double distance) { + return Math.abs(distance * Math.cos(Math.PI / 2 - verAngle)); + } + + /** + * 返回高差 + * + * @param verAngle + * @param distance + * @param stationDeviceHeight + * @param prismHeight + * @return + */ + private static double getAltitudeDifference(double verAngle, double distance, double stationDeviceHeight, double prismHeight) { + return distance * Math.sin(Math.PI / 2 - verAngle) - prismHeight + stationDeviceHeight; + } + + static class Station { + final String stationId; + final String stationName; + + Station(String id, String name) { + stationId = id; + stationName = name; + } + } + + static class SurveyorPeriod { + final String periodId; + final String periodName; + final Map stationMap = new LinkedHashMap<>();//key stationId + + public SurveyorPeriod(String id, String name) { + periodId = id; + periodName = name; + } + } + + static class Project { + final String projectId; + final String projectType; + final String projectName; + final Map surveyorPeriodMap = new LinkedHashMap<>();//key 测期id + + public Project(String id, String projectType, String name) { + projectId = id; + this.projectType = projectType; + projectName = name; + } + } + + public static class ExportItem { + final String projectName; + final String projectId; + final String projectType; + final String cycleId; + final String cycleName; + final String stationId; + final String stationName; + final String stationPointName; + + public ExportItem(String projectName, String projectId, String projectType, + String cycleId, String cycleName, + String stationId, String stationName, String stationPointName) { + this.projectName = projectName; + this.projectId = projectId; + this.projectType = projectType; + this.cycleId = cycleId; + this.cycleName = cycleName; + this.stationId = stationId; + this.stationName = stationName; + this.stationPointName = stationPointName; + } + + @Override + public @NotNull String toString() { + return stationName; + } + } + + /** + * 获取天津导出的项目类型 + * + * @param projectType + * @return 0 三角 1 联系 3 高程 4 水准 + */ + public static int getProjectTypeForTianjin(String projectType) { + switch (projectType) { + case ProjectTypeValue.TRIANGLE: + return 0; + case ProjectTypeValue.CONNECTION: + return 1; + case ProjectTypeValue.HEIGHT_TRAVERSE: + return 2; + case ProjectTypeValue.LEVEL: + return 3; + default: + break; + } + return -1; + } + + /** + * 获取天津导出的点类型 + * + * @param pointType + * @return 0 已知点 1 未知点 + */ + public static int getPointTypeForTianjin(String pointType) { + switch (pointType) { + case PointRecord.TYPE_KNOWN_POINT: + case PointRecord.TYPE_GLOBAL_POINT: + return ExportContants.TYPE_KNOWN_POINT; + case PointRecord.TYPE_UNKNOWN_POINT: + return ExportContants.TYPE_UNKNOWN_POINT; + default: + break; + } + return -1; + } + + /** + * 格式化仪器高或者棱镜高 + * + * @param height + * @return + */ + private static String formatHeight(double height) { + return Tools.formatDouble2String(height, 3); + } + + public static boolean isCanExport() { + if (CheckRegUtil.checkReg(App.getApp().registerCodeV2)) { + return true; + } + ToastUtils.showShort("您暂无使用权限,请联系客服"); + return false; + } + + /** + * 格式化仪器高或者棱镜高 + * + * @param distance + * @return + */ + public static String formatDistance(double distance) { + return Tools.formatDouble2String(distance, DISTANCE_DECIMALS); + } + + /** + * 格式化ppm + * + * @param distance + * @return + */ + public static String formatPPM(double distance) { + return Tools.formatDouble2String(distance, PPM_DECIMALS); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/method/SingleCycleTipsMethod.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/SingleCycleTipsMethod.java new file mode 100644 index 0000000..6d87248 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/SingleCycleTipsMethod.java @@ -0,0 +1,102 @@ +package com.bingce.controlnetwork.surveyor.method; + +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +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.surveyor.method.model.IStateDelegate; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.fragment.SelectReSurveyorPointFragment; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; + +public class SingleCycleTipsMethod { + /* + * todo 如果没有对单测回内错误处理,后面该怎么办?? + * */ + public static void showTips(String msg, String stationId, + int currentCycleIndex, IStateDelegate delegate, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + //取消 + delegate.onOptionTips(msg, + Tools.getString(R.string.retest_direction), + Tools.getString(R.string.retest_cycle), + () -> {//选择重测方向 + ThreadPoolUtil.execute(() -> reSurveyorPoint(stationId, delegate, + fragmentManager, lifecycleOwner)); + }, + () -> {//选择重测测回 + reSurveyorCycle(msg, stationId, currentCycleIndex, + delegate, fragmentManager, lifecycleOwner); + }, + delegate::resetSurveyorStateAndKeepPosition); + } + + @WorkerThread + private static void reSurveyorPoint(String stationId, IStateDelegate delegate, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + //弹框提示选择重测数据 + ISurveyorStationDataSource dataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord instance = dataSource.getRecordSync(stationId); + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + List stationItems = instance.getItems(); + ArrayList ids = new ArrayList<>(); + ArrayList names = new ArrayList<>(); + for (SurveyorPoint item : stationItems) { + if (item.isAbandon()) { + continue; + } + + if (!SurveyorPoint.TYPE_POINT.equals(item.getType())) { + continue; + } + PointRecord pointRecord = pointDataSource.findByIdSync(item.getPointId()); + if (pointRecord == null) { + continue; + } + ids.add(pointRecord.id); + names.add(pointRecord.name); + } + ThreadPoolUtil.executeInMain(() -> SelectReSurveyorPointFragment.pick( + fragmentManager, + lifecycleOwner, + instance.leftAndRightSurveyor, + ids, + names, + (cycleIndex, pointIds) -> { + if (pointIds == null || pointIds.isEmpty()) { + //没有选择,退出 + delegate.resetSurveyorStateAndKeepPosition(); + } else { + delegate.resurveyPoints(cycleIndex, pointIds); + } + } + )); + } + + private static void reSurveyorCycle(String msg, String stationId, + int currentCycleIndex, IStateDelegate delegate, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + delegate.onOptionTips(Tools.getString(R.string.tips_delete_current_cycle_surveyor_record), + null, null, + () -> { + delegate.deleteSingleCycleData(currentCycleIndex); + }, + () -> { + //循环显示 + showTips(msg, stationId, currentCycleIndex, delegate, + fragmentManager, lifecycleOwner); + }, + delegate::resetSurveyorStateAndKeepPosition); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/AutoModeType.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/AutoModeType.java new file mode 100644 index 0000000..9dc0e26 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/AutoModeType.java @@ -0,0 +1,10 @@ +package com.bingce.controlnetwork.surveyor.state; + +/** + * 自动测量相关的状态 + */ +public enum AutoModeType { + unknown,//未指定是否开启自动测量 + start,//开启了自动测量 + stop,//主动关闭了自动测量 +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/IScrollDelegate.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/IScrollDelegate.java new file mode 100644 index 0000000..907a77c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/IScrollDelegate.java @@ -0,0 +1,10 @@ +package com.bingce.controlnetwork.surveyor.state; + +/** + * 测量过程中,将跳转到当前item处 + *

+ * 这个委托就是做这项任务 + */ +public interface IScrollDelegate { + void onScrollTo(int index); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/StateConstants.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/StateConstants.java new file mode 100644 index 0000000..a1e1604 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/StateConstants.java @@ -0,0 +1,18 @@ +package com.bingce.controlnetwork.surveyor.state; + +public class StateConstants { + + /** + * measureWhat + */ + public static final int VALUE_MEASURE_WHAT_ANGLE_DISTANCE = 0;// 测角测距 + public static final int VALUE_MEASURE_WHAT_DISTANCE = 1;//单独测距 + + /** + * key 当前是否是旋转到位状态 + */ + public static final String KEY_IS_ROTATION_READY_STATE = "KEY_IS_ROTATION_READY_STATE"; + public static final String KEY_ROTATION_STATE_FROM_WHERE = "KEY_ROTATION_STATE_FROM_WHERE"; + public static final String ROTATION_STATE_FROM_WHERE_MEASURE = "1"; + +} 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 new file mode 100644 index 0000000..1d05490 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/StateManagerAloneDistance.java @@ -0,0 +1,498 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +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.event.RefreshGoBackButtonAloneDistance; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.AutoSurveyorMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.IStateType; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorAutoImpl; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorMock; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorMockAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorSingleImpl; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureVm; +import com.bingce.controlnetwork.surveyor.state.AutoModeType; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.StateConstants; +import com.bingce.coordlib.model.Coordinate; +import com.bingce.totalstation.ControlSurveyData; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.VipManager; + +import org.greenrobot.eventbus.EventBus; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import blankj.utilcode.util.ToastUtils; + +public class StateManagerAloneDistance implements IAutoModeSwitcher, ISurveyState, IStateType { + + //单独测距代码里的cycleIndex只有一个测回 + public static final int CYCLE_INDEX_DEFAULT = 0; + + private final Map stateMap = new HashMap<>(); + private StateType currentStateType = StateType.idle; + private final FragmentManager fragmentManager; + private final LifecycleOwner lifecycleOwner; + private final IUIRunner iuiRunner; + final IScrollDelegate scrollDelegate; + + @NonNull + SurveyorStationRecord stationRecord; + @NonNull + final CachedDataAloneDistance cachedData; + final @NonNull + ToleranceDetailRecord toleranceRecord; + final @NonNull + ISurveyorData surveyorData; + final @NonNull + MeasureVm measureVm; + final @NonNull + ICycleRecorder cycleRecorder; + final @NonNull + Context context; + private AutoModeType autoMode = AutoModeType.unknown; + @NonNull + final ISurveyor surveyor; + final PointRecord stationPointRecord; + + final boolean supportAutoSurvey; + + + private StateManagerAloneDistance(final boolean supportAutoSurvey,//是否支持自动测量 + final @NonNull SurveyorStationRecord stationRecord, + final @NonNull PointRecord stationPointRecord, + final @NonNull ToleranceDetailRecord toleranceRecord, + final @NonNull Context context, + final @NonNull ISurveyorData surveyorData, + final @NonNull ICycleRecorder cycleRecorder, + final @NonNull CachedDataAloneDistance cachedData, + final @NonNull MeasureVm measureVm, + final @NonNull IScrollDelegate scrollDelegate, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner iuiRunner) { + this.supportAutoSurvey = supportAutoSurvey; + + this.stationRecord = stationRecord; + this.stationPointRecord = stationPointRecord; + this.fragmentManager = fragmentManager; + this.lifecycleOwner = lifecycleOwner; + this.iuiRunner = iuiRunner; + this.scrollDelegate = scrollDelegate; + + this.context = context; + this.toleranceRecord = toleranceRecord; + this.surveyorData = surveyorData; + this.cachedData = cachedData; + this.measureVm = measureVm; + this.cycleRecorder = cycleRecorder; + + if (Test.DEBUG) { + surveyor = new SurveyorMockAuto(StateConstants.VALUE_MEASURE_WHAT_DISTANCE, + this.stationRecord.getId(), + this.stationRecord.isAutoClose(), + toleranceRecord.getCycleCount(), + cachedData, surveyorData, cycleRecorder, this, this); + } else { + if (supportAutoSurvey) { + surveyor = new SurveyorAutoImpl(StateConstants.VALUE_MEASURE_WHAT_DISTANCE, this); + } else { + surveyor = new SurveyorSingleImpl(StateConstants.VALUE_MEASURE_WHAT_DISTANCE); + } + } + _DoSurveyorState doSurveyorState = new _DoSurveyorState(this, this); + surveyor.register((ISurveyorListener) doSurveyorState); + surveyor.register((ISurveyorRemindListener) doSurveyorState); + + stateMap.put(StateType.doSurveyor, doSurveyorState); + stateMap.put(StateType.doAutoSurveyor, new _DoAutoSurveyorState(this, this)); + stateMap.put(StateType.SurveyorFailure, new _SurveyorFailureState(this)); + stateMap.put(StateType.doMove2NextValidate, new _DoMove2NextValidateState(this)); + stateMap.put(StateType.doMoveBack, new _DoMoveBackState(this)); + stateMap.put(StateType.checkReadData, new _CheckReadDataState(this, this)); + stateMap.put(StateType.isSingleCycleCompleted, new _IsSingleCycleCompletedState(this)); + stateMap.put(StateType.isAllCycleCompleted, new _IsAllCycleCompletedState(this, this)); + stateMap.put(StateType.checkSingleCycle, new _CheckSingleCycleState(this)); + stateMap.put(StateType.checkStation, new _CheckStationState(this)); + stateMap.put(StateType.stationCheckedSuccess, new _CheckStationSuccessState(this)); + + stateMap.put(StateType.doDeleteAllCycle, new _DoDeleteAllCycleState(this)); + stateMap.put(StateType.doDeleteCurrentCycle, new _DoDeleteCurrentCycleState(this)); + + stateMap.put(StateType.doCalScheduleSingleCycle, new _DoCalScheduleInSingleCycleState(this, this)); + stateMap.put(StateType.doCalAdjust, new _DoCalAdjustState(this)); + stateMap.put(StateType.idle, new _IdleState(this, this)); + stateMap.put(StateType.doWellMeasureRotationReady, new _DoWellMeasureRotationReadyState(this)); + + } + + public void updateStationRecord(SurveyorStationRecord stationRecord) { + this.stationRecord = stationRecord; + ThreadPoolUtil.execute(() -> { + cachedData.updateDataSouce(stationRecord); + if (Test.DEBUG && surveyor instanceof SurveyorMock) { + ((SurveyorMock) surveyor).updateData(); + } + _DoCalScheduleInSingleCycleState.enter(this, CYCLE_INDEX_DEFAULT); + + //最后刷新下页面 + runOnUI(cachedData::notifyDateChange); + }); + +// //更新测点棱镜信息 +// if (stationRecord.getItems() != null) { +// for (SurveyorPoint item : stationRecord.getItems()) { +// if (item == null || !SurveyorPoint.TYPE_POINT.equals(item.getType())) { +// continue; +// } +// cachedData.updateSurveyPointParams(item); +// } +// } + } + + String stationId() { + return stationRecord.getId(); + } + + @Override + public void enter(StateType type, Bundle args) { + __BaseState baseState = stateMap.get(type); + if (baseState != null) { + this.currentStateType = type; + runOnUI(() -> baseState.enter(args)); + } + } + + @Override + public void enter(StateType type) { + enter(type, null); + } + + void runOnUI(Runnable action) { + if (iuiRunner != null) { + iuiRunner.runOnUI(action); + } + } + + public void doSurveyor() { + boolean inValidate = isInValidate(); + + if (inValidate) { + return; + } + + int pointCount = cachedData.pointCount(); + if (pointCount == 0) { + ToastUtils.showShort(R.string.no_data_available_yet); + return; + } + + Bundle bundle = null; + if (isRotationReadyState()) { + //当前是旋转到位状态 + bundle = new Bundle(); + bundle.putBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE, true); + } + + enter(StateType.doSurveyor, bundle); + + } + + private boolean isRotationReadyState() { + return currentStateType == StateType.doWellMeasureRotationReady; + } + + public void doAutoSurveyor() { + if (isInValidate()) { + return; + } + enter(StateType.doAutoSurveyor); + } + + /** + * 删除站的所有测回记录 + */ + public void deleteCurrentStationSurveyorData() { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteAllCycle, _DoDeleteAllCycleState.args(stationId())); + } + + public void deleteCurrentStationSurveyorData(int cycleIndex) { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteCurrentCycle, _DoDeleteCurrentCycleState.args(stationId(), cycleIndex)); + } + + public void stationCheck() { + if (isInValidate()) { + return; + } + enter(StateType.checkStation); + } + + public void stationAdjust() { + if (isInValidate()) { + return; + } + enter(StateType.doCalAdjust); + } + + /** + * 切换测回时触发 + * + * @param cycleIndex + */ + public void switch2Cycle(int cycleIndex) { + //由于井定向的距离测量是不用切换测回的,在一个页面展示了两个测回 +// if (isInValidate()) { +// return; +// } +// _DoCalScheduleInSingleCycleState.enter(this, cycleIndex); + } + + /** + * 进入开始测量的时候触发 + * + * @param cycleIndex + */ + public void calScheduleWhenEnterSurveyFragment(int cycleIndex) { + if (isInValidate()) { + return; + } + _DoCalScheduleInSingleCycleState.enter(this, cycleIndex); + } + + public void moveBack() { + if (isInValidate()) { + return; + } + enter(StateType.doMoveBack); + } + + //检测当前状态是否支持从外界主动改变状态 + //如果是空闲或者是测站通过检测是有效的状态 + private boolean isInValidate() { + return currentStateType != StateType.idle + && StateType.stationCheckedSuccess != currentStateType + && !isRotationReadyState(); + } + + + FragmentManager fragmentManager() { + return this.fragmentManager; + } + + LifecycleOwner lifecycleOwner() { + return this.lifecycleOwner; + } + + final boolean isStationAutoClosed() { + return stationRecord.isAutoClose(); + } + + @WorkerThread + public static StateManagerAloneDistance newInstance( + boolean isSupportAutoMode, + @NonNull SurveyorStationRecord stationRecord, + @NonNull Context context, + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull ToleranceDetailRecord toleranceRecord, + @NonNull ISurveyorData surveyorData, + @NonNull ICycleRecorder cycleRecorder, + @NonNull CachedDataAloneDistance cachedData, + @NonNull MeasureVm measureVm, + IScrollDelegate scrollDelegate, + IUIRunner runner) { + //读取测点record + String stationPointId = null; + if (stationRecord.getItems() != null) { + for (SurveyorPoint stationItem : stationRecord.getItems()) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + stationPointId = stationItem.getPointId(); + break; + } + } + } + PointRecord stationPointRecord = null; + if (stationPointId != null) { + stationPointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationPointId); + } + if (stationPointRecord == null) { + return null; + } + boolean supportAuto = Test.DEBUG; + //App.isDebug() + if (isSupportAutoMode && + (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProLevel())) { + supportAuto = true; + } + StateManagerAloneDistance manager = new StateManagerAloneDistance(supportAuto, + stationRecord, + stationPointRecord, + toleranceRecord, + context, + surveyorData, + cycleRecorder, + cachedData, + measureVm, + scrollDelegate, + fragmentManager, lifecycleOwner, runner); + return manager; + } + + @Override + public boolean isAutoModeOpen() { + return autoMode == AutoModeType.start; + } + + @Override + public boolean isAutoModeClose() { + return autoMode == AutoModeType.stop; + } + + @Override + public boolean isAutoModeNotSpecial() { + return autoMode == AutoModeType.unknown; + } + + @Override + public void openAutoMode() { + autoMode = AutoModeType.start; + } + + @Override + public void closeAutoMode() { + autoMode = AutoModeType.stop; + } + + @Override + public void resetAutoMode() { + autoMode = AutoModeType.unknown; + } + + @Override + public int isReadyAutoSurvey() { + if (!supportAutoSurvey) { + return ControlSurveyResult.CODE_ERROR; + } + if (!surveyor.isReady()) { + return ControlSurveyResult.CODE_ERROR; + } + if (getRequestSurveyorParamAuto() == null) { + return ControlSurveyResult.CODE_ERROR; + } + + double instrumentHeight = getInsturmentHeight(); + Coordinate stationBasePoint = getStationCoord(); + + return getRequestSurveyorParamAuto().checkAutoCondition(getCachedData(), stationBasePoint, instrumentHeight); + } + + @Override + public String isMeasuredValueMatchDesign() { + if (!supportAutoSurvey) return null; + + double instrumentHeight = getInsturmentHeight(); + Coordinate stationBasePoint = getStationCoord(); + + List originMeasureList = getRequestSurveyorParamAuto().getOriginMeasureList(getCachedData()); + + return AutoSurveyorMethod.checkAutoSurveyorMeasuredValue(stationBasePoint, instrumentHeight, originMeasureList); + } + + @Override + public boolean isSurveying() { + return currentStateType == StateType.doSurveyor || currentStateType == StateType.doAutoSurveyor; + } + + @Override + public boolean isAutoSurveying() { + return isAutoModeOpen(); + } + + public void switchCurrentMeasurePosition(int position) { + if (currentStateType == StateType.idle) { + __BaseState baseState = stateMap.get(currentStateType); + if (baseState != null) { + baseState.setSurveyPosition(position, LeftOrRight.left); + } + } + } + + public CachedDataAloneDistance getCachedData() { + return cachedData; + } + + @NonNull + public ToleranceDetailRecord getToleranceRecord() { + return toleranceRecord; + } + + + private Coordinate getStationCoord() { + if (PointRecord.TYPE_KNOWN_POINT.equals(stationPointRecord.getPointType())) { + return new Coordinate( + stationPointRecord.getX(), + stationPointRecord.getY(), + stationPointRecord.getZ()); + } + return null; + } + + public double getInsturmentHeight() { + return DigitalUtil.valueOfDoubleString(stationRecord.getInstrumentHeight(), 0); + } + + public RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return measureVm.getRequestSurveyorParamAuto(); + } + + + public void refreshGoBackBtnEnable() { + CachedDataAloneDistance cachedData = getCachedData(); + int currentCycle = cycleRecorder.currentCycleIndex(); + String pointId = getCachedData().pointId(currentCycle, 0); + String cacheKey = IdUtil.createSurveyorRecordId(stationId(), currentCycle, pointId, LeftOrRight.left); + AloneDistanceRecord aloneDistanceRecord = cachedData.getAloneDistanceRecord(cacheKey); + boolean isRollBackBtnEnable = aloneDistanceRecord != null && !aloneDistanceRecord.distanceValues.isEmpty(); + EventBus.getDefault().post(new RefreshGoBackButtonAloneDistance(isRollBackBtnEnable)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckReadDataState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckReadDataState.java new file mode 100644 index 0000000..6ab37f0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckReadDataState.java @@ -0,0 +1,75 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 检测当前测量数据读数互差 + */ +class _CheckReadDataState extends __BaseState { + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_HOR = 1; + private static final int RESULT_FAILURE_VER = 2; + private static final int RESULT_FAILURE_DISTANCE = 3; + private final IAutoModeSwitcher autoModeSwitcher; + + public _CheckReadDataState(StateManagerAloneDistance stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.checkReadData, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + //先检测测量值和设计值是否匹配(仅在自动测量打开下检测) + String error = autoModeSwitcher.isMeasuredValueMatchDesign(); + if (error != null) { + failureTipsWithAutoStandStill(error); + return; + } + + onCompleted(RESULT_SUCCESS); + } + + private void onCompleted(int result) { + if (RESULT_SUCCESS == result) { + navigation2(StateType.checkSingleCycle); + } else { + String msg = ""; + switch (result) { + case RESULT_FAILURE_HOR: + msg = Tools.getString(R.string.hor_angle_read_data_limit); + break; + case RESULT_FAILURE_VER: + msg = Tools.getString(R.string.ver_angle_read_data_limit); + break; + case RESULT_FAILURE_DISTANCE: + msg = Tools.getString(R.string.distance_read_data_limit); + break; + default: + navigation2(StateType.idle); + return; + } + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(msg); + } + failureTipsWithAutoStandStill(msg); + } + } + + /** + * 斜距两次读数差 + * + * @param distance1 读数1 + * @param distance2 读数2 + * @return 读数差(单位毫米) + */ + public static double distanceReadDiff(double distance1, double distance2) { + return Math.abs(distance1 - distance2) * 1000; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckSingleCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckSingleCycleState.java new file mode 100644 index 0000000..6e3d607 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckSingleCycleState.java @@ -0,0 +1,90 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import java.util.List; + +/** + * 测回内不同方向2c、方向i互差检测 + */ +class _CheckSingleCycleState extends __BaseState { + + public _CheckSingleCycleState(StateManagerAloneDistance stateManager) { + super(StateType.checkSingleCycle, stateManager); + } + + @Override + public void enter(Bundle args) { + doCheck(); + } + + private void doCheck() { + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + CachedDataAloneDistance cachedData = getCachedData(); + int surveyorCount = getSurveyorCount(); + int cycleIndex = getCycleRecorder().currentCycleIndex(); + int currentIndex = getCurrentIndex(); + double distCyclesDifference = toleranceRecord.getSlopeCycleDistanceDifference()/*slopeCycleDistanceDifference*/; + AloneDistanceRecord aloneDistanceRecord = getAloneDistanceRecord(currentIndex); + if (aloneDistanceRecord == null || aloneDistanceRecord.distanceValues.size() < surveyorCount * 2) { + //进入旋转到位状态等待点击继续测量 + navigation2(StateType.doWellMeasureRotationReady); + return; + } + + List valuesFirst = aloneDistanceRecord.distanceValues.subList(0, surveyorCount); + List valuesSecond = aloneDistanceRecord.distanceValues.subList(surveyorCount, surveyorCount * 2); + + + Double averageFirst = Tools.calculateCollectionDoubleAverage(valuesFirst); + Double averageSecond = Tools.calculateCollectionDoubleAverage(valuesSecond); + + double compareValue = Math.abs(averageFirst - averageSecond); + + if (compareValue * 1000 > distCyclesDifference) { + optionTips(Tools.getString(R.string.cycle_between_distance_limit) + distCyclesDifference, + Tools.getString(R.string.retest_cycle), + Tools.getString(R.string.retest_point), + () -> { + cachedData.deleteAloneDistanceRecord(stationId(), cycleIndex, currentIndex, LeftOrRight.left, true); + //更新进度 + setCurrentCycle(cycleIndex); + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + findTargetFromBeginInCurrentCycle(false); + }, + () -> { + //重测目标 + cachedData.deleteAloneDistanceRecord(stationId(), cycleIndex, currentIndex, LeftOrRight.left, false); + //更新进度 + setCurrentCycle(cycleIndex); + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + findTargetFromBeginInCurrentCycle(false); + }, + () -> { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + }); + + } else { + onSuccess(); + } + } + + private void onSuccess() { + //更新测量进度 + setSingleCycleSchedule(getCycleRecorder().currentCycleIndex(), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + //跳转 + navigation2(StateType.isSingleCycleCompleted); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationState.java new file mode 100644 index 0000000..983335c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationState.java @@ -0,0 +1,195 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * 执行「测站检测」 + *

+ * 前置条件: + * 所有测回都完成测量,并且通过「测回内检测」 + */ +public class _CheckStationState extends __BaseState { + + public _CheckStationState(StateManagerAloneDistance stateManager) { + super(StateType.checkStation, stateManager); + } + + @Override + public void enter(Bundle args) { + //执行测站检测 + String error = _stationCheckAloneDistance(stationId(), getToleranceRecord(), getCachedData()); + if (error == null || error.isEmpty()) { + //进入finish状态 + navigation2(StateType.stationCheckedSuccess); + } else { + failureTipsWithAutoStandStill(error); + } + } + + public static String _stationCheckAloneDistance(final String stationId, + final ToleranceDetailRecord toleranceRecord, + final CachedDataAloneDistance cachedDataSource) { + + final int cycleCount = ToleranceDetailRecord.ALONE_DISTANCE_CYCLE_COUNT; + final int surveyorCount = toleranceRecord.getSurveyorCount(); + + + //测回间斜距互差 + double distCyclesDifference = toleranceRecord.getSlopeCycleDistanceDifference()/*slopeCycleDistanceDifference*/; + List<_ErrorItem> distError = new ArrayList<>(); + + List<_Point> pointArrayList = new ArrayList<>(); + //遍历第一测回,收集所有待测点id + for (int index = 0; index < cachedDataSource.pointCount(); index++) { + pointArrayList.add(new _Point(cachedDataSource.pointId(0, index), cachedDataSource.pointName(0, index))); + } + // if (!distError.isEmpty()) { +// stringBuilder.append("测回间距离较差超限(限差:") +// .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 ""; + } + + /** + * 根据超限信息生成错误描述 + * + * @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; + + _Point(String pointId, String pointName) { + this.pointId = pointId; + this.pointName = pointName; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationSuccessState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationSuccessState.java new file mode 100644 index 0000000..f120c55 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationSuccessState.java @@ -0,0 +1,33 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import com.bingce.controlnetwork.R; + +class _CheckStationSuccessState extends __BaseState { + + public _CheckStationSuccessState(StateManagerAloneDistance stateManager) { + super(StateType.stationCheckedSuccess, stateManager); + } + + @Override + public void enter(Bundle args) { + ISurveyorData surveyorData = getSurveyorData(); + surveyorData.clearSurveyStateAndPosition(); + //设置测量进度(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + //通知刷新 + tips(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked), null); + if (isAutoSurveyOpen()) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked))); + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoAutoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoAutoSurveyorState.java new file mode 100644 index 0000000..2ca12da --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoAutoSurveyorState.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoAutoSurveyorState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoAutoSurveyorState(StateManagerAloneDistance stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doAutoSurveyor, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + if (autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS) { + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doMove2NextValidate); + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalAdjustState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalAdjustState.java new file mode 100644 index 0000000..e62f793 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalAdjustState.java @@ -0,0 +1,74 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.content.Context; +import android.os.Bundle; + +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; + +/** + * 平差计算 + */ +public class _DoCalAdjustState extends __BaseState { + + public _DoCalAdjustState(StateManagerAloneDistance stateManager) { + super(StateType.doCalAdjust, stateManager); + } + + @Override + public void enter(Bundle args) { + + } + + public static void doCalAdjust(String stationId, CachedDataAloneDistance cachedData, Context context, FragmentManager fragmentManager + , LifecycleOwner lifecycleOwner) { + ThreadPoolUtil.execute(() -> { + SurveyorAdjustMethod.calAloneDistance( + stationId, cachedData, new SurveyorAdjustMethod.ICallback() { + @Override + public void onGet(ArrayList finalItemList, Boolean isShowSlopDistance) { +// //清除测量状态,进入idle,停止自动测量 +// enterIdleAndClearSurveyStateAndResetAutoMode(true); + //展示结果数据 + //检测归零值是否为负,如果是需要+2PI + for (SurveyorAdjustMethod.Item item : finalItemList) { + if (item.getHorAngle() < 0) { + item.setHorAngle(Math.PI * 2 + item.getHorAngle()); + } + } + StationDataAdjustDialogFragment.showDialog(StationDataAdjustDialogFragment.TYPE_ALONE_DISTANCE, finalItemList, isShowSlopDistance, fragmentManager); + } + + @Override + public void onFailure(String error) { + ThreadPoolUtil.executeInMain(() -> { + TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, error); + }); + } + }); + + //伴随平差 设置进度为通过检测 + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId, SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED)); + + }); + + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalScheduleInSingleCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalScheduleInSingleCycleState.java new file mode 100644 index 0000000..ff1e497 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalScheduleInSingleCycleState.java @@ -0,0 +1,108 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; + +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; + +/** + * 在单个测回内计算当前测量进度。 + *

+ * 1.如果有没有完成测量,则跳转到相应位置。 + * 2.如果测量完成,检测数据限差 + * 3.进入idle + */ +class _DoCalScheduleInSingleCycleState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoCalScheduleInSingleCycleState(StateManagerAloneDistance stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doCalScheduleSingleCycle, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + final public void enter(Bundle args) { + + int pointCount = getCachedData().pointCount(); + if (pointCount == 0) { + postBtnEvent(); + return; + } + + //重置自动测量状态 + if (autoModeSwitcher.isAutoModeClose()) { + autoModeSwitcher.resetAutoMode(); + } + //计算状态之前,重置测量状态 + getSurveyorData().clearSurveyStateAndPosition(); + + ICycleRecorder cycleRecorder = getCycleRecorder(); + cycleRecorder.changeCycleIndex(args.getInt(KEY_CYCLE_INDEX, 0)); + setCurrentCycle(cycleRecorder.currentCycleIndex()); + + //1.检测当前cycle是否完成测量 + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData(), getSurveyorCount()); + //2.如果当前测回还有待测数据,则执行测量 + if (!completed) { + //从当前测回开始处查找目标并执行测量 + findTargetFromBeginInCurrentCycle(false); + return; + } + //3.如果当前测回结束测量,判断是否通过检测 +// ToleranceDetailRecord toleranceDetailRecord = getToleranceRecord(); +// double horCycle2CDiff = toleranceDetailRecord.getHorCycleDirect2CDifference(); +// double verCycle2CDiff = toleranceDetailRecord.getVerCycleDirectIDifference(); +// String error = SingleCycleCheckMethod.check( +// horCycle2CDiff, +// verCycle2CDiff, +// stationId(), +// getCycleRecorder().currentCycleIndex(), +// getSurveyorData(), +// getCachedData()); +// if (error != null && !error.isEmpty()) { +// SingleCycleTipsMethod.showTips(error, +// stationId(), +// getCycleRecorder().currentCycleIndex(), +// stateDelegate(), +// fragmentManager(), +// lifecycleOwner()); +// return; +// } + //4.更新测站状态,在当前测回经过检测 + setSingleCycleSchedule(getCycleRecorder().currentCycleIndex(), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + //6.清空测量状态 + onCompletedCheck(); + } + + protected void onCompletedCheck() { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + + protected static final String KEY_CYCLE_INDEX = "___cycle__index__"; + + static void enter(StateManagerAloneDistance stateManager, int cycleIndex) { + Bundle args = new Bundle(); + args.putInt(KEY_CYCLE_INDEX, cycleIndex); + stateManager.enter(StateType.doCalScheduleSingleCycle, args); + } + + private void postBtnEvent() { + int pointCount = getCachedData().pointCount(); + if (pointCount == 0) { + SurveyStateEvent.postCompleted(MeasureFragment.POSITION_DISTANCE_MEASURE); + } else { + SurveyStateEvent.postIdle(MeasureFragment.POSITION_DISTANCE_MEASURE); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteAllCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteAllCycleState.java new file mode 100644 index 0000000..1e49e92 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteAllCycleState.java @@ -0,0 +1,63 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +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.surveyor.state.StateType; +import com.bingce.utils.ThreadPoolUtil; + +import com.bingce.controlnetwork.R; + +/** + * 删除本测站所有测回数据 + * 对于钢丝测距 所有两测回数据都在一个view里显示了,不用切换 + */ +class _DoDeleteAllCycleState extends __BaseState { + + private static final String KEY_STATION_ID = "__station_id"; + + static Bundle args(String stationId) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + return args; + } + + public _DoDeleteAllCycleState(StateManagerAloneDistance stateManager) { + super(StateType.doDeleteAllCycle, stateManager); + } + + @Override + 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)); + } + + private void deleteAllCycleData(String stationId) { + ThreadPoolUtil.execute(() -> { + //删除数据 + getCachedData().deleteAloneDistanceRecord(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); + setSingleCycleScheduleSync(cycleIndexDefault, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + //从第一测回开始 + setCurrentCycle(cycleIndexDefault); + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true); + }); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteCurrentCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteCurrentCycleState.java new file mode 100644 index 0000000..0c07e34 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteCurrentCycleState.java @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +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.surveyor.state.StateType; + +import com.bingce.controlnetwork.R; + +class _DoDeleteCurrentCycleState extends __BaseState { + public _DoDeleteCurrentCycleState(StateManagerAloneDistance stateManager) { + super(StateType.doDeleteCurrentCycle, stateManager); + } + + @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), + () -> { + //删除数据 + getCachedData().deleteAloneDistanceRecord(stationId, cycleIndex); + + //清除已经提示测站可以检测标识 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; + configDataSource.set(key, ConfigConstants.VALUE_NO); + + //重置进度 + //当前测回 + setCurrentCycle(cycleIndex); + //所有测回未完成 + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + //单个测回未完成 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true); + }); + } + + private static final String KEY_STATION_ID = "__station_id"; + private static final String KEY_PERIOD_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); + return args; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMove2NextValidateState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMove2NextValidateState.java new file mode 100644 index 0000000..c0cff3c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMove2NextValidateState.java @@ -0,0 +1,72 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; + +/** + * 移动到一个待测量位置 + *

+ * 不会跳转到其他测期 + *

+ * 可能涉及转向(盘左->盘右) + */ +class _DoMove2NextValidateState extends __BaseState { + + public _DoMove2NextValidateState(StateManagerAloneDistance stateManager) { + super(StateType.doMove2NextValidate, stateManager); + } + + @Override + public void enter(Bundle args) { + CachedDataAloneDistance cachedData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + + int pointCount = cachedData.pointCount(); + int currentIndex = surveyorData.currentIndex(); + if (currentIndex < 0) { + currentIndex = 0; + } + final int currentCycleIndex = cycleRecorder.currentCycleIndex(); + final LeftOrRight currentSurveyorState = surveyorData.leftOrRight(); + + + FindTargetMethod.Target needMeasureForAloneDistanceTarget = FindTargetMethod.findNeedMeasureTargetInSingleCycleForAloneDistance(stationId(), currentCycleIndex, + currentIndex, + currentSurveyorState, + pointCount, + true, + cachedData); + + if (needMeasureForAloneDistanceTarget != null) { + navigation2(needMeasureForAloneDistanceTarget.itemIndex, needMeasureForAloneDistanceTarget.leftOrRight); + return; + } + + + //3.当前测回完成测量,停留状态 + //重置标识 + enterIdleAndClearSurveyorStatePosition(); + } + + /** + * 跳转到下一目标点 + * + * @param targetIndex 目标点索引 + * @param targetSurveyorState 测量状态(盘左or盘右) + */ + private void navigation2(int targetIndex, LeftOrRight targetSurveyorState) { + //更新测量进度 + setSurveyPosition(targetIndex, targetSurveyorState); + //清除测量状态,进入idle,但是不停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(false); + //滚动 + scroll2(targetIndex); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMoveBackState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMoveBackState.java new file mode 100644 index 0000000..0f87315 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMoveBackState.java @@ -0,0 +1,85 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import blankj.utilcode.util.ToastUtils; + +/** + * 移动到上一测量结点,伴随删除上次测量数据 + */ +public class _DoMoveBackState extends __BaseState { + + public _DoMoveBackState(StateManagerAloneDistance stateManager) { + super(StateType.doMoveBack, stateManager); + } + + @Override + public void enter(Bundle args) { + CachedDataAloneDistance cachedDataSource = getCachedData(); + ISurveyorData surveyorDataSource = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + + final int pointCount = cachedDataSource.pointCount(); + final int currentCycle = cycleRecorder.currentCycleIndex(); + final int currentIndex = surveyorDataSource.currentIndex(); + final LeftOrRight leftOrRight = surveyorDataSource.leftOrRight(); + + int targetIndex = currentIndex; + if (targetIndex < 0) { + //如果测量结束,直接使用0号点盘右 + targetIndex = pointCount - 1; + } + warningWithStandStill(cachedDataSource, currentCycle, targetIndex, LeftOrRight.left); + } + + private void warningWithStandStill( + CachedDataAloneDistance cachedDataSource, + int currentCycle, int itemIndex, LeftOrRight leftOrRight) { + optionTipsWithStandStill(Tools.getString(R.string.roll_back_node_data), + () -> { + //删除当前数据 + int nextSurveyorPointIndex = cachedDataSource.deleteAloneDistanceRecord(stationId(), + currentCycle, itemIndex, leftOrRight, true); + + if (nextSurveyorPointIndex == -1) { + ToastUtils.showShort(R.string.roll_back_failed); + navigation2(StateType.idle); + return; + } + + AloneDistanceRecord aloneDistanceRecord = getAloneDistanceRecord(nextSurveyorPointIndex); + if (aloneDistanceRecord != null && aloneDistanceRecord.distanceValues.size() == getSurveyorCount()) { + navigation2(StateType.doWellMeasureRotationReady); + } else { + navigation2(StateType.idle); + } + + //重置进度 + setCurrentCycle(nextSurveyorPointIndex); + setSingleCycleSchedule(currentCycle, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + resetSchedule(this, nextSurveyorPointIndex, leftOrRight); + }); + } + + private void resetSchedule(__BaseState state, + int targetIndex, + LeftOrRight leftOrRight) { + //设置测量目标点 + state.setSurveyPosition(targetIndex, leftOrRight); + + state.scroll2(targetIndex); + } + +} 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 new file mode 100644 index 0000000..d02be7c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoSurveyorState.java @@ -0,0 +1,181 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +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; +import com.bingce.device.Device; +import com.bingce.totalstation.TotalStation; +import com.bingce.totalstation.protocol.south.SouthAndroidBtInterface; +import com.bingce.totalstation.protocol.topcon.TopconInterface; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoSurveyorState extends __BaseState implements ISurveyorListener, ISurveyorRemindListener { + private final ISurveyState surveyState; + //最多测量次数,如果5次测量都没有获取正常数据,则跳过 + private static final int MAX_SURVEYOR_COUNT = 3; + private static int failureCount = 0; + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_EXCEED_MAX = 1;//测量失败次数超出最大限制 + private static final int RESULT_FAILURE_ERROR = 2;//测量失败,又没有允许重复尝试 + private static final boolean allowTryWhenFailure = true;//在测量失败的时候,是否允许重新测量 + + private int measureTimeIndex = 0; + private boolean isAlreadyRemindUserAimingAtWire = false; + + private final Handler handler; + + public _DoSurveyorState(StateManagerAloneDistance stateManager, ISurveyState surveyState) { + super(StateType.doSurveyor, stateManager); + this.surveyState = surveyState; + handler = new Handler(Looper.getMainLooper()); + } + + @Override + public void enter(Bundle args) { + measureTimeIndex = 0; + + isAlreadyRemindUserAimingAtWire = false; + if (args != null) { + isAlreadyRemindUserAimingAtWire = args.getBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE); + } + + //3.其他测回没有正在测量数据,则在当前测回执行测量 + doSurveyor(); + } + + private void doSurveyor() { + failureCount = 0; + //判断设备是否连接 + if (surveyorImpl().isReady()) { + //发送测量信号 + SurveyStateEvent.postSurveying(positionFragment); + //注册接收测量数据 + surveyorImpl().prepareSurveyor(); + sendSurveyRequest(); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + Device.getInstance().remindConnectDevice(); + } + } + + @Override + public void onReceive(double originalHa, double originalVa, double sd, double clockwiseHa, double topVa, double hd, double vd) { + //重置错误读数 + failureCount = 0; + AloneDistanceRecord aloneDistanceRecord + = getCachedData().cacheAloneDistance(stationId(), StateManagerAloneDistance.CYCLE_INDEX_DEFAULT, getCurrentIndex(), sd, hd); + + //刷新页面 + refreshUI(); + int surveyorCount = getCachedData().getSurveyorCount(); + if (aloneDistanceRecord.distanceValues.size() == surveyorCount) { + ToastUtils.showShort(Utils.getApp().getString(R.string.alone_distance_first_round_measure_finish)); + onSuccess(); + } else if (aloneDistanceRecord.distanceValues.size() >= surveyorCount * 2) { + onSuccess(); + } else { + //当数据不够的时候 继续发送指令 + measureTimeIndex++; + if (TotalStation.getInstance() instanceof TopconInterface) { + //这个仪器需要延迟500毫秒发送指令 + handler.postDelayed(this::sendSurveyRequest, 500); + } else if (TotalStation.getInstance() instanceof SouthAndroidBtInterface) { + handler.postDelayed(this::sendSurveyRequest, 100); + } else { + sendSurveyRequest(); + } + } + } + + @Override + public void onError(String errorMsg) { + TtsManager.getInstance().speak(errorMsg); + if (allowTryWhenFailure) {//允许重新测量 + //测量出现异常,需要处理 + failureCount++; + if (failureCount >= MAX_SURVEYOR_COUNT) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.many_measure_failed)); + } + 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); + } + } else { + onCompleted(RESULT_FAILURE_ERROR, errorMsg); + } + } + + private void sendSurveyRequest() { + SurveyorPoint surveyorPoint = getCachedData().getSurveyorPoint(getCycleRecorder().currentCycleIndex(), getCurrentIndex()); + + ISurveyorData surveyorData = getSurveyorData(); + int measureTimeIndex = 0; + surveyorImpl().requestSurveyor(new RequestSurveyorParam(getRequestSurveyorParamAuto(), getInsturmentHeight(), surveyorPoint, measureTimeIndex, + surveyorData.currentIndex(), surveyorData.leftOrRight(), isAlreadyRemindUserAimingAtWire)); + } + + private void onSuccess() { + onCompleted(RESULT_SUCCESS, ""); + } + + private void onCompleted(int result, String msg) { + //退出测量 + surveyorImpl().exitSurveyor(); + switch (result) { + case RESULT_SUCCESS://进入读数检测状态 + //检测是否处于「自动测量」 + if (!surveyState.isAutoSurveying()) { + SurveyStateEvent.postSuccess(positionFragment); + } + navigation2(StateType.checkReadData); + break; + case RESULT_FAILURE_EXCEED_MAX: + case RESULT_FAILURE_ERROR: { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg); + navigation2(StateType.SurveyorFailure, args); + } + break; + default: + throw new RuntimeException("un reached state -- surveyor"); + } + } + + @Override + public void remindUserAimingAtWire() { + //退出测量 + surveyorImpl().exitSurveyor(); + + Bundle bundle = new Bundle(); + bundle.putString(StateConstants.KEY_ROTATION_STATE_FROM_WHERE, StateConstants.ROTATION_STATE_FROM_WHERE_MEASURE); + navigation2(StateType.doWellMeasureRotationReady, bundle); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoWellMeasureRotationReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoWellMeasureRotationReadyState.java new file mode 100644 index 0000000..be6c86a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoWellMeasureRotationReadyState.java @@ -0,0 +1,41 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; +import android.text.TextUtils; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.surveyor.state.StateConstants; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +import com.bingce.controlnetwork.surveyor.state.StateConstants; + +/** + * 钢丝测量旋转到位状态 + */ +class _DoWellMeasureRotationReadyState extends __BaseState { + + public _DoWellMeasureRotationReadyState(StateManagerAloneDistance stateManager) { + super(StateType.doWellMeasureRotationReady, stateManager); + } + + @Override + public void enter(Bundle args) { + if (args != null) { + String fromWhere = args.getString(StateConstants.KEY_ROTATION_STATE_FROM_WHERE); + if (TextUtils.equals(fromWhere, StateConstants.ROTATION_STATE_FROM_WHERE_MEASURE)) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.please_aiming_at_alone_distance_point_then_measure))); + } + } + //更新回退按钮状态 + refreshGoBack(); + SurveyStateEvent.postIdle(positionFragment); + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, false, true)); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IdleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IdleState.java new file mode 100644 index 0000000..4fa88a0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IdleState.java @@ -0,0 +1,64 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +/** + * 空闲状态 + *

+ * 将刷新界面 + */ +class _IdleState extends __BaseState { + private final @NonNull + IAutoModeSwitcher autoModeSwitcher; + + public _IdleState(StateManagerAloneDistance stateManager, @NonNull IAutoModeSwitcher autoModeSwitcher) { + super(StateType.idle, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + + refreshGoBack(); + + ThreadPoolUtil.execute(() -> { + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + StateManagerAloneDistance.CYCLE_INDEX_DEFAULT, + getCachedData(), ToleranceDetailRecord.ALONE_DISTANCE_MEASURE_COUNT); + + //判断当前条件是否满足自动测量 + boolean haveAutoCondition = autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS; + + //自动测量是否显示 + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, haveAutoCondition, autoModeSwitcher.isAutoModeOpen())); + + if (haveAutoCondition && autoModeSwitcher.isAutoModeOpen()) { + //继续自动测量 + navigation2(StateType.doSurveyor); + } else { + if (autoModeSwitcher.isAutoModeOpen()) { + autoModeSwitcher.resetAutoMode(); + } + if (completed) { + SurveyStateEvent.postCompleted(positionFragment); + } else { + SurveyStateEvent.postIdle(positionFragment); + } + } + }); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsAllCycleCompletedState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsAllCycleCompletedState.java new file mode 100644 index 0000000..701fae1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsAllCycleCompletedState.java @@ -0,0 +1,54 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +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.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/* + * 检测是否所有 测期都完成了测量 + * + * 只有在当前测期完成测量之后,才会进入当前状态 + * */ +public class _IsAllCycleCompletedState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _IsAllCycleCompletedState(@NonNull StateManagerAloneDistance stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.isAllCycleCompleted, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + if (isAutoSurveyOpen()) { + //检测是否已经提示 + //检测是否需要提示测站检测 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + ThreadPoolUtil.execute(() -> { + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId(); + ConfigRecord record = configDataSource.getByKeySync(key); + if (record == null || ConfigConstants.VALUE_NO.equals(record.getConfigValue())) { + runOnUI(() -> TtsManager.getInstance().speak(Tools.getString(R.string.all_cycle_completed))); + } + }); + } + //标识测站完成测量(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //进入idle状态 + //清除测量状态,进入测站检测,停止自动测量 + enterStationCheckAndClearSurveyStateAndResetAutoMode(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsSingleCycleCompletedState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsSingleCycleCompletedState.java new file mode 100644 index 0000000..ca23390 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsSingleCycleCompletedState.java @@ -0,0 +1,61 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + +public class _IsSingleCycleCompletedState extends __BaseState { + private static final int RESULT_YES = 0;//测回结束 + private static final int RESULT_NO = 1;//测回未结束 + + public _IsSingleCycleCompletedState(StateManagerAloneDistance stateManager) { + super(StateType.isSingleCycleCompleted, stateManager); + } + + @Override + public void enter(Bundle args) { + onCompleted( + isSingleCycleCompleted(stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData(), getSurveyorCount())); + } + + private void onCompleted(boolean completed) { + if (completed) { + //这里先刷新下UI,不然弹窗后面的list不显示最后一条数据 + getSurveyorData().clearSurveyStateAndPosition(); + refreshUI(); + + int cycleIndex = getCycleRecorder().currentCycleIndex(); + //更新单测回测量进度 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //状态切换 + navigation2(StateType.isAllCycleCompleted); + } else { + findTargetFromBeginInCurrentCycle(false); + } + } + + /** + * 判断单个测回是否测量完成(不要求通过检测) + */ + public static boolean isSingleCycleCompleted(String stationId, int cycleIndex, CachedDataAloneDistance cachedData, int surveyCount) { + int result = RESULT_YES; + for (int index = 0; index < cachedData.pointCount(); index++) { + String pointId = cachedData.pointId(cycleIndex, index); + String leftOrRightKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.left); + AloneDistanceRecord aloneDistanceRecord = cachedData.getAloneDistanceRecord(leftOrRightKey); + if (aloneDistanceRecord == null || aloneDistanceRecord.distanceValues == null || + aloneDistanceRecord.distanceValues.size() < surveyCount * 2) { + result = RESULT_NO; + break; + } + } + return RESULT_YES == result; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_SurveyorFailureState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_SurveyorFailureState.java new file mode 100644 index 0000000..0d532bb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_SurveyorFailureState.java @@ -0,0 +1,36 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +/* + * 仪器导致的测量失败 + * + * 全站仪多次测量失败,进入该状态 + * */ +class _SurveyorFailureState extends __BaseState { + + public _SurveyorFailureState(StateManagerAloneDistance stateManager) { + super(StateType.SurveyorFailure, stateManager); + } + + @Override + public void enter(Bundle args) { + String error = ""; + if (args != null) { + error = args.getString(KEY); + } + failureTipsWithAutoStandStill(error + Tools.getString(R.string.please_observe_target)); + } + + private static final String KEY = "error"; + + public static Bundle args(String error) { + Bundle args = new Bundle(); + args.putString(KEY, error); + return args; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/__BaseState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/__BaseState.java new file mode 100644 index 0000000..2c94cf3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/__BaseState.java @@ -0,0 +1,395 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; + +abstract class __BaseState { + private final StateType type; + private final StateManagerAloneDistance stateManager; + + protected final int positionFragment = MeasureFragment.POSITION_DISTANCE_MEASURE; + + /** + * 判断常量 + */ + private final int DEFAULT_AUTO_MODE = 0; + private final int RESET_AUTO_MODE = 1; + private final int CLOSE_AUTO_MODE = 2; + + protected final int cycleIndexDefault = StateManagerAloneDistance.CYCLE_INDEX_DEFAULT; + + public __BaseState(final StateType stateType, final StateManagerAloneDistance stateManager) { + this.type = stateType; + this.stateManager = stateManager; + } + + final protected StateType getType() { + return type; + } + + final protected @NonNull + ToleranceDetailRecord getToleranceRecord() { + return stateManager.toleranceRecord; + } + + final protected @NonNull + ISurveyorData getSurveyorData() { + return stateManager.surveyorData; + } + + private @NonNull + IAutoModeSwitcher autoModeRecorder() { + return stateManager; + } + + /** + * 设置测量位置 + */ + final protected void setSurveyPosition(int index, LeftOrRight leftOrRight) { + stateManager.surveyorData.setCurrentIndex(index); + stateManager.surveyorData.setLeftOrRight(leftOrRight); + } + + protected int getCurrentIndex() { + return stateManager.surveyorData.currentIndex(); + } + + protected AloneDistanceRecord getAloneDistanceRecord(int surveyorPointIndex) { + int cycleIndex = getCycleRecorder().currentCycleIndex(); + String pointId = getCachedData().pointId(cycleIndex, surveyorPointIndex); + String cacheKey = IdUtil.createSurveyorRecordId(stationId(), cycleIndex, pointId, LeftOrRight.left); + return getCachedData().getAloneDistanceRecord(cacheKey); + } + + final protected ISurveyor surveyorImpl() { + return stateManager.surveyor; + } + + + @NonNull + final protected CachedDataAloneDistance getCachedData() { + return stateManager.cachedData; + } + + @NonNull + final protected ICycleRecorder getCycleRecorder() { + return stateManager.cycleRecorder; + } + + @NonNull + final protected Context getContext() { + return stateManager.context; + } + + final protected void scroll2(int itemIndex) { + stateManager.scrollDelegate.onScrollTo(itemIndex); + } + + + final protected void toast(String warning) { + ToastUtils.showShort(warning); + } + + final protected void toast(@StringRes int warning) { + ToastUtils.showShort(warning); + } + + public abstract void enter(Bundle args);//进入状态 + + final protected void navigation2(StateType stateType) { + stateManager.enter(stateType); + } + + final protected void navigation2(StateType stateType, Bundle args) { + stateManager.enter(stateType, args); + } + + final protected String stationId() { + return stateManager.stationId(); + } + + protected int getSurveyorCount() { + return stateManager.surveyorData.surveyorCount(); + } + + final protected FragmentManager fragmentManager() { + return stateManager.fragmentManager(); + } + + final protected LifecycleOwner lifecycleOwner() { + return stateManager.lifecycleOwner(); + } + + final protected void tips(String msg, Runnable runnable) { + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + if (runnable != null) { + runnable.run(); + } + }); + } + + /** + * 错误提示 + *

+ * 用户不能忽略,点击确定后自动「停留原地」 + */ + final protected void failureTipsWithAutoStandStill(String msg) { + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void failureTipsWithAutoStandStill(String msg, Runnable runnable) { + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + runnable.run(); + enterIdleAndClearSurveyStateAndResetAutoMode(true); + }); + } + + final protected void optionTipsWithStandStill(String msg, Runnable confirmCallback) { + optionTips(msg, null, null, + confirmCallback, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void optionTips(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + TipsWith2OptionFragment.tips( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + final protected void runOnUI(Runnable runnable) { + stateManager.runOnUI(runnable); + } + + final protected void setCurrentCycle(int cycle) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + String.valueOf(cycle))); + } + + final protected void setCurrentCycleSync(int cycle) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + String.valueOf(cycle))); + } + + final protected void setSingleCycleSchedule(int cycleIndex, String statue) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE, cycleIndex), + statue)); + } + + final protected void setSingleCycleScheduleSync(int cycleIndex, String statue) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE, cycleIndex), + statue)); + } + + final protected void setAllCycleSchedule(String statue) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + statue)); + } + + final protected void setAllCycleScheduleSync(String statue) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + statue)); + } + + /** + * 如果resetAutoSurveyState为true,将重置autoSurvey状态为unknown + */ + final protected void findTargetFromBeginInCurrentCycle(boolean resetAutoSurveyState) { + getSurveyorData().clearSurveyStateAndPosition(); + if (resetAutoSurveyState) { + autoModeRecorder().resetAutoMode(); + } + navigation2(StateType.doMove2NextValidate); + } + + final protected void enterIdleAndClearSurveyState() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + final protected void enterIdleAndClearSurveyorStatePosition() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + true, StateType.idle); + } + + /** + * 取消测量,会停在当前位置(索引+盘左or盘右),并进入idle + */ + final protected void enterIdleAndClearSurveyStateAndResetAutoMode(boolean resetAutoMode) { + clearSurveyStateAndCloseAutoModeAndStandStill(resetAutoMode ? RESET_AUTO_MODE : DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + + final protected void enterStationCheckAndClearSurveyStateAndResetAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(RESET_AUTO_MODE, + false, StateType.checkStation); + } + + /** + * 原_Check2CState 使用这个方法 + */ + final protected void enterIdleAndClearSurveyStateAndCloseAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(CLOSE_AUTO_MODE, false, StateType.idle); + } + + /** + * @param autoMode + * @param clearPosition + * @param stateType + */ + private void clearSurveyStateAndCloseAutoModeAndStandStill(int autoMode, boolean clearPosition, StateType stateType) { + //重置或者关闭自动模式 + if (autoMode == RESET_AUTO_MODE) { + autoModeRecorder().resetAutoMode(); + } else if (autoMode == CLOSE_AUTO_MODE) { + autoModeRecorder().closeAutoMode(); + } + //更新测量进度标识 + if (clearPosition) { + getSurveyorData().clearSurveyStateAndPosition(); + } else { + getSurveyorData().clearSurveyState(); + } + //进入某个状态 + navigation2(stateType); + } + + + /** + * 更新UI + */ + final protected void refreshUI() { + runOnUI(() -> getCachedData().notifyDateChange()); + } + + protected boolean isAutoSurveyOpen() { + return stateManager.isAutoModeOpen(); + } + + protected boolean isAutoSurveyClosed() { + return stateManager.isAutoModeClose(); + } + + double getInsturmentHeight() { + return stateManager.getInsturmentHeight(); + } + + RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return stateManager.getRequestSurveyorParamAuto(); + } + + protected void refreshGoBack() { + stateManager.refreshGoBackBtnEnable(); + } + +} 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 new file mode 100644 index 0000000..4ecd238 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/StateManager.java @@ -0,0 +1,539 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +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.event.RefreshGoBackButton; +import com.bingce.controlapphelper.model.DataCategory; +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.AutoSurveyorMethod; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.IStateType; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorAutoImpl; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorMockAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorSingleImpl; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +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; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.VipManager; + +import org.greenrobot.eventbus.EventBus; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import blankj.utilcode.util.ToastUtils; + +public class StateManager implements IAutoModeSwitcher, ISurveyState, IStateType { + private final Map stateMap = new HashMap<>(); + private StateType currentStateType = StateType.idle; + private final FragmentManager fragmentManager; + private final LifecycleOwner lifecycleOwner; + private final IUIRunner iuiRunner; + final IScrollDelegate scrollDelegate; + + @NonNull + SurveyorStationRecord stationRecord; + final @NonNull + RequestSurveyorParamAuto requestSurveyorParamAuto; + final @NonNull + ToleranceDetailRecord toleranceRecord; + final @NonNull + ISurveyorData surveyorData; + final @NonNull + ICachedData cachedData; + final @NonNull + ICycleRecorder cycleRecorder; + final @NonNull + Context context; + private AutoModeType autoMode = AutoModeType.unknown; + @NonNull + final ISurveyor surveyor; + 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, + final @NonNull PointRecord stationPointRecord, + final @NonNull ToleranceDetailRecord toleranceRecord, + final @NonNull Context context, + final @NonNull ISurveyorData surveyorData, + final @NonNull ICycleRecorder cycleRecorder, + final @NonNull ICachedData cachedData, + final @NonNull IScrollDelegate scrollDelegate, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner iuiRunner) { + this.supportAutoSurvey = supportAutoSurvey; + + this.requestSurveyorParamAuto = requestSurveyorParamAuto; + this.stationRecord = stationRecord; + this.fragmentManager = fragmentManager; + this.lifecycleOwner = lifecycleOwner; + this.iuiRunner = iuiRunner; + this.scrollDelegate = scrollDelegate; + + this.context = context; + this.toleranceRecord = toleranceRecord; + this.surveyorData = surveyorData; + this.cachedData = cachedData; + this.cycleRecorder = cycleRecorder; + + this.stationPointRecord = stationPointRecord; + + if (Test.DEBUG) { + surveyor = new SurveyorMockAuto(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE, this.stationRecord.getId(), + this.stationRecord.isAutoClose(), + toleranceRecord.getCycleCount(), + cachedData, surveyorData, cycleRecorder, this, this); + } else { + if (supportAutoSurvey) { + surveyor = new SurveyorAutoImpl(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE, this); + } else { + surveyor = new SurveyorSingleImpl(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE); + } + } + _DoSurveyorState doSurveyorState = new _DoSurveyorState(this, this); + //注册接收数据的状态 + surveyor.register((ISurveyorListener) doSurveyorState); + surveyor.register((ISurveyorRemindListener) doSurveyorState); + + stateMap.put(StateType.doSurveyor, doSurveyorState); + stateMap.put(StateType.doAutoSurveyor, new _DoAutoSurveyorState(this, this)); + stateMap.put(StateType.SurveyorFailure, new _SurveyorFailureState(this)); + stateMap.put(StateType.doMove2NextValidate, new _DoMove2NextValidateState(this)); + stateMap.put(StateType.doMoveBack, new _DoMoveBackState(this)); + stateMap.put(StateType.doRecordClean, new _DoRecordCleanState(this)); + stateMap.put(StateType.checkReadData, new _CheckReadDataState(this, this)); + stateMap.put(StateType.isHalfCycleZeroCheckReady, new _IsHalfCycleZeroCheckReadyState(this)); + stateMap.put(StateType.checkHalfCycleZero, new _CheckHalfCycleZeroState(this)); + stateMap.put(StateType.isReady2CCheck, new _Is2CCheckReadyState(this)); + stateMap.put(StateType.check2C, new _Check2CState(this)); + stateMap.put(StateType.isSingleCycleCompleted, new _IsSingleCycleCompletedState(this)); + stateMap.put(StateType.isAllCycleCompleted, new _IsAllCycleCompletedState(this, this)); + stateMap.put(StateType.checkSingleCycle, new _CheckSingleCycleState(this)); + stateMap.put(StateType.checkStation, new _CheckStationState(this)); + stateMap.put(StateType.stationCheckedSuccess, new _CheckStationSuccessState(this)); + + stateMap.put(StateType.doDeleteAllCycle, new _DoDeleteAllCycleState(this)); + stateMap.put(StateType.doDeleteCurrentCycle, new _DoDeleteCurrentCycleState(this)); + + stateMap.put(StateType.doCalScheduleSingleCycle, new _DoCalScheduleInSingleCycleState(this, this)); + stateMap.put(StateType.doCalScheduleAllCycle, new _DoCalScheduleInAllCycleState(this, this)); + stateMap.put(StateType.doCalAdjust, new _DoCalAdjustState(this)); + stateMap.put(StateType.idle, new _IdleState(this, this)); + stateMap.put(StateType.doWellMeasureRotationReady, new _DoWellMeasureRotationReadyState(this)); + + //监听测站数据变化 + runOnUI(() -> SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationRecord.getId()) + .observe(lifecycleOwner, record -> { + if (record == null || !stationRecord.getId().equals(record.getId())) { + return; + } + updateSurveyorStationRecord(record); + })); + } + + private void updateSurveyorStationRecord(SurveyorStationRecord record) { + this.stationRecord = record; + //更新测点信息 + if (stationRecord.getItems() != null) { + for (SurveyorPoint item : stationRecord.getItems()) { + if (item == null || !SurveyorPoint.TYPE_POINT.equals(item.getType())) { + //排除非测点 + continue; + } + cachedData.updateSurveyPointParams(item); + } + } + cachedData.notifyDateChange(); + } + + String stationId() { + return stationRecord.getId(); + } + + + @Override + public void enter(StateType type, Bundle args) { + if (isDead()) { + return; + } + __BaseState baseState = stateMap.get(type); + if (baseState != null) { + this.currentStateType = type; + runOnUI(() -> baseState.enter(args)); + } + } + + @Override + public void enter(StateType type) { + enter(type, null); + } + + void runOnUI(Runnable action) { + if (iuiRunner != null) { + iuiRunner.runOnUI(action); + } + } + + public void doSurveyor() { + boolean inValidate = isInValidate(); + + if (inValidate) { + return; + } + + int pointCount = cachedData.pointCount(); + if (pointCount == 0) { + ToastUtils.showShort(R.string.no_data_available_yet); + return; + } + + Bundle bundle = null; + if (isRotationReadyState()) { + //当前是旋转到位状态 + bundle = new Bundle(); + bundle.putBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE, true); + } + + enter(StateType.doSurveyor, bundle); + } + + public void doAutoSurveyor() { + if (isInValidate()) { + return; + } + enter(StateType.doAutoSurveyor); + } + + public void deleteCurrentStationSurveyorData() { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteAllCycle, _DoDeleteAllCycleState.args(stationId())); + } + + public void deleteCurrentStationSurveyorData(int cycleIndex) { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteCurrentCycle, _DoDeleteCurrentCycleState.args(stationId(), cycleIndex)); + } + + public void stationCheck() { + if (isInValidate()) { + return; + } + enter(StateType.checkStation); + } + + public String stationCheckOnly() { + return stationCheck.check(stationId(), toleranceRecord, cachedData); + } + + public void stationAdjustOnly(String showType) { + ThreadPoolUtil.execute(() -> { + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (adjustResult.isError()) { + runOnUI(() -> TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, adjustResult.errorString)); + return; + } + //显示平差结果 + StationDataAdjustDialogFragment.showDialog(showType, adjustResult.result, adjustResult.showSlopDistance, fragmentManager()); + + //伴随平差 设置进度为通过检测 + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED)); + }); + } + + public void stationAdjust(String type) { + if (isInValidate()) { + return; + } + Bundle bundle = new Bundle(); + bundle.putString(StationDataAdjustDialogFragment.KEY_SHOW_TYPE, type); + enter(StateType.doCalAdjust, bundle); + } + + public void switch2Cycle(int cycleIndex) { + if (isInValidate()) { + return; + } + _DoCalScheduleInSingleCycleState.enter(this, cycleIndex); + } + + public void calScheduleWhenEnterSurveyFragment(int cycleIndex) { + if (isInValidate()) { + return; + } + _DoCalScheduleInAllCycleState.enter(this, cycleIndex); + } + + public void moveBack() { + if (isInValidate()) { + return; + } + enter(StateType.doMoveBack); + } + + //检测当前状态是否支持从外界主动改变状态 + //如果是空闲或者是测站通过检测是有效的状态 + private boolean isInValidate() { + return currentStateType != StateType.idle + && StateType.stationCheckedSuccess != currentStateType + && !isRotationReadyState(); + } + + private boolean isRotationReadyState() { + return currentStateType == StateType.doWellMeasureRotationReady; + } + + public void quite() { + _live = false; + for (Map.Entry entry : stateMap.entrySet()) { + entry.getValue().quite(); + } + //进入idle状态 + this.currentStateType = StateType.idle; + } + + private boolean _live = true; + + boolean isDead() { + return !_live; + } + + public void resume() { + _live = true; + for (Map.Entry entry : stateMap.entrySet()) { + entry.getValue().resume(); + } + } + + FragmentManager fragmentManager() { + return this.fragmentManager; + } + + LifecycleOwner lifecycleOwner() { + return this.lifecycleOwner; + } + + final boolean isStationAutoClosed() { + return stationRecord.isAutoClose(); + } + + @WorkerThread + public static StateManager newInstance( + boolean isSupportAutoMode, + @NonNull RequestSurveyorParamAuto requestSurveyorParamAuto, + @NonNull SurveyorStationRecord stationRecord, + @NonNull Context context, + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull ToleranceDetailRecord toleranceRecord, + @NonNull ISurveyorData surveyorData, + @NonNull ICycleRecorder cycleRecorder, + @NonNull ICachedData cachedData, + IScrollDelegate scrollDelegate, + IUIRunner runner) { + //读取测点record + String stationPointId = null; + if (stationRecord.getItems() != null) { + for (SurveyorPoint stationItem : stationRecord.getItems()) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + stationPointId = stationItem.getPointId(); + break; + } + } + } + PointRecord stationPointRecord = null; + if (stationPointId != null) { + stationPointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationPointId); + } + if (stationPointRecord == null) { + return null; + } + boolean supportAuto = Test.DEBUG; + //AppUtils.isAppDebug() + if (isSupportAutoMode && + (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProLevel())) { + supportAuto = true; + } + StateManager manager = new StateManager(supportAuto, + requestSurveyorParamAuto, + stationRecord, + stationPointRecord, + toleranceRecord, + context, + surveyorData, + cycleRecorder, + cachedData, + scrollDelegate, + fragmentManager, lifecycleOwner, runner); + return manager; + } + + @Override + public boolean isAutoModeOpen() { + return autoMode == AutoModeType.start; + } + + @Override + public boolean isAutoModeClose() { + return autoMode == AutoModeType.stop; + } + + @Override + public boolean isAutoModeNotSpecial() { + return autoMode == AutoModeType.unknown; + } + + @Override + public void openAutoMode() { + autoMode = AutoModeType.start; + } + + @Override + public void closeAutoMode() { + autoMode = AutoModeType.stop; + } + + @Override + public void resetAutoMode() { + autoMode = AutoModeType.unknown; + } + + + @Override + public int isReadyAutoSurvey() { + if (!supportAutoSurvey) { + return ControlSurveyResult.CODE_ERROR; + } + if (!surveyor.isReady()) {//仪器连接上才算ready + return ControlSurveyResult.CODE_ERROR; + } + + Coordinate stationBasePoint = getStationCoord(); + double instrumentHeight = getInsturmentHeight(); + + return requestSurveyorParamAuto.checkAutoCondition(getCachedData(), stationBasePoint, instrumentHeight); + } + + @Override + public String isMeasuredValueMatchDesign() { + if (!supportAutoSurvey) { + return null; + } + Coordinate stationBasePoint = getStationCoord(); + double instrumentHeight = getInsturmentHeight(); + List originMeasureList = requestSurveyorParamAuto.getOriginMeasureList(getCachedData()); + return AutoSurveyorMethod.checkAutoSurveyorMeasuredValue(stationBasePoint, instrumentHeight, originMeasureList); + } + + @Override + public boolean isSurveying() { + return currentStateType == StateType.doSurveyor || currentStateType == StateType.doAutoSurveyor; + } + + @Override + public boolean isAutoSurveying() { + return isAutoModeOpen(); + } + + + public ICachedData getCachedData() { + return cachedData; + } + + /** + * 获取当前测回 + * + * @return + */ + public int getCurrentCycle() { + return cycleRecorder.currentCycleIndex(); + } + + public int getCurrentIndex() { + return surveyorData.currentIndex(); + } + + private Coordinate getStationCoord() { + if (PointRecord.TYPE_KNOWN_POINT.equals(stationPointRecord.getPointType())) { + return new Coordinate( + stationPointRecord.getX(), + stationPointRecord.getY(), + stationPointRecord.getZ()); + } + return null; + } + + public double getInsturmentHeight() { + return DigitalUtil.valueOfDoubleString(stationRecord.getInstrumentHeight(), 0); + } + + @NonNull + public RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return requestSurveyorParamAuto; + } + + public void refreshGoBackBtnEnable() { + int currentCycle = cycleRecorder.currentCycleIndex(); + String pointId = getCachedData().pointId(currentCycle, 0); + DataCategory dataCategory = getCachedData().valueState( + IdUtil.createSurveyorRecordId(stationId(), currentCycle, pointId, LeftOrRight.left), 0); + EventBus.getDefault().post(new RefreshGoBackButton(!dataCategory.isEmptyData())); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Check2CState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Check2CState.java new file mode 100644 index 0000000..a1d2566 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Check2CState.java @@ -0,0 +1,113 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +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.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/* + * 检测2c + * */ +class _Check2CState extends __BaseState { + + public _Check2CState(StateManager stateManager) { + super(StateType.check2C, stateManager); + } + + @Override + public void enter(Bundle args) { + String error = _check2C(stationId(), getToleranceRecord(), + getSurveyorData(), + getCycleRecorder().currentCycleIndex(), + getCachedData()); + if (error.isEmpty()) { + navigation2(StateType.doRecordClean); + } else { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.erxi_is_over_limit_please_check)); + } + optionTips(error, + Tools.getString(R.string.retest_cycle), + Tools.getString(R.string.retest_point), + () -> optionTipsWithStandStill(Tools.getString(R.string.tips_delete_current_cycle_surveyor_record), + () -> { + String stationId = stationId(); + int currentCycleIndex = getCycleRecorder().currentCycleIndex(); + //删除数据 + ICachedData cachedData = getCachedData(); + cachedData.deleteSurveyorRecord(stationId, currentCycleIndex); + //更新进度 + setSingleCycleSchedule(currentCycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + //重新查找目标开启测量 + findTargetFromBeginInCurrentCycle(true); + }), + this::enterIdleAndClearSurveyState, + this::enterIdleAndClearSurveyStateAndCloseAutoMode); + } + } + + private static String _check2C(String stationId, + ToleranceDetailRecord toleranceRecord, + ISurveyorData surveyorData, + int cycleIndex, + ICachedData cachedData) { + StringBuilder stringBuilder = new StringBuilder(); + + int currentIndex = surveyorData.currentIndex(); + + CacheResult value2C = ValueOf2cMethod.valueOf2C(SdAngleValueType.horAngle, currentIndex, stationId, + surveyorData, cycleIndex, cachedData); + + if (!value2C.validate || toleranceRecord.getHor2C() < Math.abs(value2C.value)) { + stringBuilder.append(Tools.getString(R.string.hor_angle_2c_limit)) + .append(toleranceRecord.getHor2C()) + .append("'')\n") + .append(" ") + .append(Tools.getString(R.string.measurements)) + .append(Util.formatDouble2String(Math.abs(value2C.value), 1)) + .append("''"); + } + + value2C = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, currentIndex, stationId, + surveyorData, cycleIndex, cachedData); + if (!value2C.validate || toleranceRecord.getVerI() < Math.abs(value2C.value)) { + stringBuilder.append("\n") + .append(Tools.getString(R.string.ver_angle_i_limit)) + .append(toleranceRecord.getVerI()) + .append("'')\n") + .append(" ") + .append(Tools.getString(R.string.measurements)) + .append(Util.formatDouble2String(Math.abs(value2C.value), 1)) + .append("''"); + } + + if (!cachedData.isAloneDistance(cycleIndex, surveyorData.currentIndex())) { + value2C = ValueOf2cMethod.valueOf2C(SdAngleValueType.distance, currentIndex, stationId, + surveyorData, cycleIndex, cachedData); + if (!value2C.validate || toleranceRecord.getSlopeLensDistanceDifference() < Math.abs(value2C.value)) { + stringBuilder.append("\n") + .append(Tools.getString(R.string.distance_positive_and_negative_mirror_limit)) + .append(toleranceRecord.getSlopeLensDistanceDifference()) + .append("mm)\n") + .append(" ") + .append(Tools.getString(R.string.measurements)) + .append(Util.formatDouble2String(Math.abs(value2C.value), 1)) + .append("mm"); + } + } + + return stringBuilder.toString(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckHalfCycleZeroState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckHalfCycleZeroState.java new file mode 100644 index 0000000..156a56b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckHalfCycleZeroState.java @@ -0,0 +1,81 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +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.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.AverageValueMethod; +import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod; +import com.bingce.controlapphelper.surveyor.method.model.CacheResult; +import com.bingce.controlapphelper.surveyor.method.model.SdAngleValueType; +import com.bingce.controlapphelper.surveyor.state.StateType; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import com.bingce.controlnetwork.R; + +/* + * 半测回归零检测 --- 只检测水平角 + * */ +class _CheckHalfCycleZeroState extends __BaseState { + private final static int RESULT_SUCCESS = 0; + private final static int RESULT_FAILURE = 1; + + public _CheckHalfCycleZeroState(StateManager stateManager) { + super(StateType.checkHalfCycleZero, stateManager); + } + + @Override + public void enter(Bundle args) { + if (isStationClosed()) { + ISurveyorData surveyorDataSource = getSurveyorData(); + int cycleIndex = getCycleRecorder().currentCycleIndex(); + ICachedData stationSurveyorDataSource = getCachedData(); + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + int pointCount = stationSurveyorDataSource.pointCount(); + LeftOrRight leftOrRight = surveyorDataSource.leftOrRight(); + + CacheResult angleHorFirst = AverageValueMethod.leftOrRightValue(SdAngleValueType.horAngle, + stationId(), + 0, + leftOrRight, + surveyorDataSource, + cycleIndex, + stationSurveyorDataSource); + CacheResult angleHorEnd = AverageValueMethod.leftOrRightValue(SdAngleValueType.horAngle, + stationId(), + pointCount - 1, + leftOrRight, + surveyorDataSource, + cycleIndex, + stationSurveyorDataSource); + if (!angleHorFirst.validate || !angleHorEnd.validate) { + onCompleted(RESULT_FAILURE); + } else { + double diff = DeviationValueOfRadianMethod.similarRadianDiff(angleHorFirst.value, angleHorEnd.value); + if (toleranceRecord.getHorHalfReturnZeroDifference() < Math.toDegrees(diff) * 3600) { + onCompleted(RESULT_FAILURE); + } else { + onCompleted(RESULT_SUCCESS); + } + } + } else { + onCompleted(RESULT_SUCCESS); + } + } + + private void onCompleted(int result) { + if (RESULT_SUCCESS == result) { + navigation2(StateType.isReady2CCheck); + } else if (RESULT_FAILURE == result) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(getContext().getString(R.string.tips_error_half_cycle_zero_stop_survey)); + } + failureTipsWithAutoStandStill(getContext().getString(R.string.tips_error_half_cycle_zero_stop_survey)); + } else { + throw new RuntimeException("半测回归零差 failure"); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckReadDataState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckReadDataState.java new file mode 100644 index 0000000..4d64557 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckReadDataState.java @@ -0,0 +1,126 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod; +import com.bingce.controlapphelper.surveyor.method.RadianMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.TotalStation; + +import net.tatans.tensorflowtts.tts.TtsManager; + + +/* + * 检测当前测量数据读数互差 + * */ +class _CheckReadDataState extends __BaseState { + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_HOR = 1; + private static final int RESULT_FAILURE_VER = 2; + private static final int RESULT_FAILURE_DISTANCE = 3; + private final IAutoModeSwitcher autoModeSwitcher; + + public _CheckReadDataState(StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.checkReadData, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + //先检测测量值和设计值是否匹配(仅在自动测量打开下检测) + String error = autoModeSwitcher.isMeasuredValueMatchDesign(); + if (error != null) { + failureTipsWithAutoStandStill(error); + return; + } + int surveyorCount = getToleranceRecord().getSurveyorCount(); + if (surveyorCount <= 1) {//单次测量,直接通过检测 + onCompleted(RESULT_SUCCESS); + } else {//多次测量,执行检测 + ISurveyorData surveyorDataSource = getSurveyorData(); + double horDifference = getToleranceRecord().getHorReadDifference(); + double verDifference = getToleranceRecord().getVerReadDifference(); + double distanceDifference = getToleranceRecord().getSlopeReadDifference(); + double horDiffRadian = DeviationValueOfRadianMethod.similarRadianDiff(surveyorDataSource.getAngleHor1(), surveyorDataSource.getAngleHor2()); + double verDiffRadian = DeviationValueOfRadianMethod.similarRadianDiff(surveyorDataSource.getAngleVer1(), surveyorDataSource.getAngleVer2()); + + int resultCode = RESULT_SUCCESS; + if (horDifference < RadianMethod.radian2S(horDiffRadian)) { + resultCode = RESULT_FAILURE_HOR; + } else if (verDifference < RadianMethod.radian2S(verDiffRadian)) { + resultCode = RESULT_FAILURE_VER; + } else if (!isAloneDistance()//增加单独测距判断 + && distanceDifference < distanceReadDiff(surveyorDataSource.getDistance1(), surveyorDataSource.getDistance2())) { + resultCode = RESULT_FAILURE_DISTANCE; + } + onCompleted(resultCode); + } + } + + private void onCompleted(int result) { + if (RESULT_SUCCESS == result) { + checkLeft(); + } else { + String msg = ""; + switch (result) { + case RESULT_FAILURE_HOR: + msg = Tools.getString(R.string.hor_angle_read_data_limit); + break; + case RESULT_FAILURE_VER: + msg = Tools.getString(R.string.ver_angle_read_data_limit); + break; + case RESULT_FAILURE_DISTANCE: + msg = Tools.getString(R.string.distance_read_data_limit); + break; + default: + navigation2(StateType.idle); + return; + } + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(msg); + } + failureTipsWithAutoStandStill(msg); + } + } + + /** + * 如果是测回内首次测量,需要判断是否是盘左 + */ + private void checkLeft() { + int currentItem = getSurveyorData().currentIndex(); + LeftOrRight leftOrRight = getSurveyorData().leftOrRight(); + if (leftOrRight == LeftOrRight.left) { + //如果是首次测量,强制要求使用盘左 + double vAngle = getSurveyorData().getAngleVer(); + if (!isFirstValidate(vAngle)) { + failureTipsWithAutoStandStill( + getContext().getString(R.string.error_tips_please_start_from_left), + () -> { + TotalStation.getInstance().requestChangeFace(); + }); + return; + } + } + navigation2(StateType.isHalfCycleZeroCheckReady); + } + + private boolean isFirstValidate(double vAngle) { + return vAngle >= 0 && vAngle <= Math.PI; + } + + /** + * 斜距两次读数差 + * + * @param distance1 读数1 + * @param distance2 读数2 + * @return 读数差(单位毫米) + */ + public static double distanceReadDiff(double distance1, double distance2) { + return Math.abs(distance1 - distance2) * 1000; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckSingleCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckSingleCycleState.java new file mode 100644 index 0000000..d1f154a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckSingleCycleState.java @@ -0,0 +1,102 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.SurveyorRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.DataCategory; +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.SingleCycleCheckMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.surveyor.method.SingleCycleTipsMethod; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 测回内不同方向2c、方向i互差检测 + */ +class _CheckSingleCycleState extends __BaseState { + + public _CheckSingleCycleState(StateManager stateManager) { + super(StateType.checkSingleCycle, stateManager); + } + + @Override + public void enter(Bundle args) { + //1.先将该测回内所有补测数据设置为正常数据,再进行检测 + ICachedData cachedDataSource = getCachedData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + int pointCount = cachedDataSource.pointCount(); + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + String stationId = stationId(); + + for (int index = 0; index < pointCount; index++) { + String pointId = cachedDataSource.pointId(currentCycleIndex, index); + String keyLeft = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + SurveyorRecord left = cachedDataSource.getSurveyorRecord(keyLeft); + _changeDirtyRecord2NormalBeforeCheck(left, cachedDataSource); + String keyRight = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.right); + SurveyorRecord right = cachedDataSource.getSurveyorRecord(keyRight); + _changeDirtyRecord2NormalBeforeCheck(right, cachedDataSource); + } + //2.执行检测 + doCheck(); + } + + private static void _changeDirtyRecord2NormalBeforeCheck( + SurveyorRecord record, ICachedData cachedDataSource) { + if (record == null) { + return; + } + if (record.value1Status.isResurveyed() || record.value2Status.isResurveyed()) { + if (record.value1Status.isResurveyed()) { + record.value1Status = DataCategory.normalCategory(); + } + if (record.value2Status.isResurveyed()) { + record.value2Status = DataCategory.normalCategory(); + } + + cachedDataSource.updateCache(record); + } + } + + private void doCheck() { + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + ISurveyorData surveyorDataSource = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + ICachedData stationSurveyorDataSource = getCachedData(); + + //1.执行单测回内检测 + String error = SingleCycleCheckMethod.check( + toleranceRecord.getHorCycleDirect2CDifference(), toleranceRecord.getVerCycleDirectIDifference(), + stationId(), cycleRecorder.currentCycleIndex(), surveyorDataSource, stationSurveyorDataSource); + if (error != null) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.check_cycle_inner_failed)); + } + //TODO 这里可能存在不对测回内错误处理的情况,后面应该兼容处理下 + SingleCycleTipsMethod.showTips(error, stationId(), cycleRecorder.currentCycleIndex(), + stateDelegate(), + fragmentManager(), + lifecycleOwner()); + } else { + onSuccess(); + } + } + + private void onSuccess() { + //更新测量进度 + setSingleCycleSchedule(getCycleRecorder().currentCycleIndex(), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + //跳转 + navigation2(StateType.isAllCycleCompleted); + } +} 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 new file mode 100644 index 0000000..75e2aaa --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationState.java @@ -0,0 +1,173 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +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.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; +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 java.util.ArrayList; +import java.util.List; + +/** + * 执行「测站检测」 + *

+ * 前置条件: + * 所有测回都完成测量,并且通过「测回内检测」 + */ +class _CheckStationState extends __BaseState { + + private final IStationCheck stationCheck = new AngleDistanceCheckAdjust(); + + public _CheckStationState(StateManager stateManager) { + super(StateType.checkStation, stateManager); + } + + @Override + public void enter(Bundle args) { + //执行测站检测 + String error = stationCheck.check(stationId(), getToleranceRecord(), getCachedData()); + if (error == null || error.isEmpty()) { + //进入finish状态 + navigation2(StateType.stationCheckedSuccess); + } else { + showErrorTips(error, stationId(), getToleranceRecord().getCycleCount(), + getSurveyorData(), getCycleRecorder(), getCachedData(), + this, + fragmentManager(), + lifecycleOwner()); + } + } + + /** + * 提示错误信息,并让用户选择下一步操作 + */ + static void showErrorTips(String msg, String stationId, int cycleCount, + ISurveyorData surveyorDataSource, + ICycleRecorder cycleRecorder, + ICachedData stationSurveyorDataSource, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + state.optionTips(msg, + Tools.getString(R.string.retest_direction), + Tools.getString(R.string.retest_station), + () -> state.runOnBackground(() -> reSurveyorPoint(stationId, cycleCount, + cycleRecorder, stationSurveyorDataSource, + state, fragmentManager, lifecycleOwner)), + () -> reSurveyorStation(msg, stationId, cycleCount, + surveyorDataSource, cycleRecorder, stationSurveyorDataSource, + state, fragmentManager, lifecycleOwner), + () -> state.enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + @WorkerThread + static void reSurveyorPoint(String stationId, int cycleCount, + ICycleRecorder cycleRecorder, + ICachedData cachedData, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + //弹框提示选择重测数据 + ISurveyorStationDataSource dataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord instance = dataSource.getRecordSync(stationId); + if (instance == null) { + state.enterIdleAndClearSurveyStateAndResetAutoMode(true); + return; + } + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + List stationItems = instance.getItems(); + ArrayList ids = new ArrayList<>(); + ArrayList names = new ArrayList<>(); + for (SurveyorPoint item : stationItems) { + if (item.isAbandon()) { + continue; + } + + if (!SurveyorPoint.TYPE_POINT.equals(item.getType())) { + continue; + } + PointRecord pointRecord = pointDataSource.findByIdSync(item.getPointId()); + if (pointRecord == null) { + continue; + } + ids.add(pointRecord.id); + names.add(pointRecord.name); + } + state.runOnUI(() -> SelectReSurveyorPointFragment.pick( + fragmentManager, + lifecycleOwner, + cycleCount, + instance.leftAndRightSurveyor, + ids, + names, + (cycleIndex, pointIds) -> { + if (pointIds == null || pointIds.isEmpty()) { + state.enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + //记录补测数据类型,切换测回 + cachedData.markReSurveyor(stationId, cycleIndex, pointIds); + cycleRecorder.changeCycleIndex(cycleIndex); + + //更新测量状态 + state.setCurrentCycle(cycleIndex); + state.setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + state.setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + //查找新测量目标 + state.findTargetFromBeginInCurrentCycle(true); + } + } + )); + } + + static void reSurveyorStation(String msg, String stationId, int cycleCount, + ISurveyorData surveyorData, + ICycleRecorder cycleRecorder, + ICachedData cachedData, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + state.optionTips(Tools.getString(R.string.is_delete_all_station_data), null, null, + () -> {//1.选择删除测站所有数据,则执行相应逻辑 + ThreadPoolUtil.execute(() -> { + //删除数据 + cachedData.deleteSurveyorRecord(stationId); + + //更新测量进度 + state.setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + for (int index = 0; index < cycleCount; index++) { + state.setSingleCycleSchedule(index, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + + state.resetLearnDataTag(); + + //重新测量 + state.findTargetFromBeginInCurrentCycle(true); + }); + }, + () -> {//2.如果用户不选择删除,则循环提示,让他重新在重测和删除做选择 + //循环显示 + showErrorTips(msg, stationId, cycleCount, + surveyorData, cycleRecorder, cachedData, state, + fragmentManager, lifecycleOwner); + }, + () -> state.enterIdleAndClearSurveyStateAndResetAutoMode(true));//3.如果用户忽略,则停留在当前位置 + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationSuccessState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationSuccessState.java new file mode 100644 index 0000000..ffe951f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationSuccessState.java @@ -0,0 +1,33 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import com.bingce.controlnetwork.R; + +class _CheckStationSuccessState extends __BaseState { + + public _CheckStationSuccessState(StateManager stateManager) { + super(StateType.stationCheckedSuccess, stateManager); + } + + @Override + public void enter(Bundle args) { + ISurveyorData surveyorData = getSurveyorData(); + surveyorData.clearSurveyStateAndPosition(); + //设置测量进度(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + //通知刷新 + tips(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked), null); + if (isAutoSurveyOpen()) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked))); + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoAutoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoAutoSurveyorState.java new file mode 100644 index 0000000..499830a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoAutoSurveyorState.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoAutoSurveyorState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoAutoSurveyorState(StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doAutoSurveyor, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + if (autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS) { + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doMove2NextValidate); + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalAdjustState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalAdjustState.java new file mode 100644 index 0000000..bbbabf6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalAdjustState.java @@ -0,0 +1,44 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; + +/** + * 平差计算 + */ +public class _DoCalAdjustState extends __BaseState { + + public _DoCalAdjustState(StateManager stateManager) { + super(StateType.doCalAdjust, stateManager); + } + + @Override + public void enter(Bundle args) { + String showType = null; + if (args != null) { + showType = args.getString(StationDataAdjustDialogFragment.KEY_SHOW_TYPE); + } + startCalAdjust(showType); + } + + private void startCalAdjust(String showType) { + runOnBackground(() -> { + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(getStation(), getCachedData()); + if (adjustResult.isError()) { + runOnUI(() -> _CheckStationState.showErrorTips(adjustResult.errorString, stationId(), getToleranceRecord().getCycleCount(), + getSurveyorData(), getCycleRecorder(), getCachedData(), + _DoCalAdjustState.this, + fragmentManager(), + lifecycleOwner())); + return; + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + StationDataAdjustDialogFragment.showDialog(showType, adjustResult.result, adjustResult.showSlopDistance, fragmentManager()); + } + ); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInAllCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInAllCycleState.java new file mode 100644 index 0000000..a28e35e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInAllCycleState.java @@ -0,0 +1,134 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.ISurveyorScheduleDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.DataCategory; +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.method.SingleCycleCheckMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.surveyor.method.SingleCycleTipsMethod; +import com.bingce.utils.ThreadPoolUtil; + +/** + * 在所有测回范围计算测量进度。 + *

+ * 1.检测当前测回,如果有没有完成测量,则跳转到相应位置。 + * 2.如果测量完成,检测数据限差。 + * 3.检测其他测回是否有待测数据 + * A.优先考虑dirty数据 + * B.其次考虑empty数据 + * 发现目标,执行跳转 + * 4.如果其他测回也完成测量,检测其限差 + * 发现超限,则立即返回true + * 5.如果其他测回限差通过检测,设置标识测站可以执行检测 + */ +class _DoCalScheduleInAllCycleState extends _DoCalScheduleInSingleCycleState { + + public _DoCalScheduleInAllCycleState(StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doCalScheduleAllCycle, stateManager, autoModeSwitcher); + } + + @Override + protected boolean isNeedCancelEnterIdle(int currentCycle) { + ICachedData cachedData = getCachedData(); + int pointCount = cachedData.pointCount(); + ToleranceDetailRecord toleranceDetailRecord = getToleranceRecord(); + //5.当前测回完成且通过检测,则对其他测回执行检测 + FindTargetMethod.Target resurveyTarget = null; + int emptyCycleIndex = -1; + for (int cycleIndex = 0; cycleIndex < toleranceDetailRecord.getCycleCount(); cycleIndex++) { + if (cycleIndex == getCycleRecorder().currentCycleIndex()) { + continue; + } + + if (_IsSingleCycleCompletedState.isSingleCycleCompleted(stationId(), cycleIndex, getCachedData())) { + //更新该测回进度 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + continue; + } + //从0号位置盘左开始向后查询,找到需要补测位置 + resurveyTarget = FindTargetMethod.findTargetInSingleCycle( + stationId(), cycleIndex, 0, LeftOrRight.left, pointCount, true, + DataCategory.needResurvey(), cachedData); + if (resurveyTarget != null) { + break; + } + //测量没有完成,且没有补测数据,说明有空数据 + if (emptyCycleIndex < 0) { + emptyCycleIndex = cycleIndex; + } + } + + //6.如果有需要补测数据,优先处理 + if (resurveyTarget != null) { + option4Jump2OtherCycle4Resurvey(resurveyTarget.cycleIndex); + return true; + } + //7.如果其他测回有empty数据,提示 + if (emptyCycleIndex >= 0) { + option4Jump2OtherEmptyCycle(emptyCycleIndex); + return true; + } + //8.所有测回都完成测量(当前测回完成检测),执行检测 + double horCycle2CDiff = toleranceDetailRecord.getHorCycleDirect2CDifference(); + double verCycle2CDiff = toleranceDetailRecord.getVerCycleDirectIDifference(); + for (int cycleIndex = 0; cycleIndex < toleranceDetailRecord.getCycleCount(); cycleIndex++) { + if (cycleIndex == getCycleRecorder().currentCycleIndex()) { + continue; + } + String result = SingleCycleCheckMethod.check( + horCycle2CDiff, + verCycle2CDiff, + stationId(), + cycleIndex, + getSurveyorData(), + getCachedData()); + if (result != null && !result.isEmpty()) { + SingleCycleTipsMethod.showTips(result, + stationId(), + cycleIndex, + stateDelegate(), + fragmentManager(), + lifecycleOwner()); + return true; + } + //更新该测回进度 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + } + //9.所有测回都通过检测,可以执行「测站检测」 + //设置测量进度,但是需要注意,如果station已经通过检测,则不需要设置为completed + ThreadPoolUtil.execute(() -> { + ISurveyorScheduleDataSource scheduleDataSource = + SurveyorDatabaseFactory.instance.getScheduleDataSource(); + String key = SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null); + SurveyorScheduleRecord scheduleRecord = scheduleDataSource.findScheduleSync(key); + if (scheduleRecord != null) { + String statue = scheduleRecord.getStatue(); + if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(statue)) { + onCompletedCheck(); + return; + } + } + scheduleDataSource.record(new SurveyorScheduleRecord(key, + SurveyorScheduleConstants.STATUE_VALUE_COMPLETED)); + + //如果测量完成,则进入测站检测界面 + navigation2(StateType.checkStation); + }); + return true; + } + + static void enter(StateManager stateManager, int cycleIndex) { + Bundle args = new Bundle(); + args.putInt(KEY_CYCLE_INDEX, cycleIndex); + stateManager.enter(StateType.doCalScheduleAllCycle, args); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInSingleCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInSingleCycleState.java new file mode 100644 index 0000000..527ced4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInSingleCycleState.java @@ -0,0 +1,110 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.method.SingleCycleCheckMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.surveyor.method.SingleCycleTipsMethod; + +/** + * 在单个测回内计算当前测量进度。 + *

+ * 1.如果有没有完成测量,则跳转到相应位置。 + * 2.如果测量完成,检测数据限差 + * 3.进入idle + */ +class _DoCalScheduleInSingleCycleState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoCalScheduleInSingleCycleState(StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doCalScheduleSingleCycle, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + protected _DoCalScheduleInSingleCycleState(StateType stateType, final StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(stateType, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + /** + * 在其他测回是否包含需要测量的数据 + *

+ * 当前类默认返回false,不检测其他测回 + */ + protected boolean isNeedCancelEnterIdle(int currentCycle) { + return false; + } + + @Override + final public void enter(Bundle args) { + //重置自动测量状态 + if (autoModeSwitcher.isAutoModeClose()) { + autoModeSwitcher.resetAutoMode(); + } + //计算状态之前,重置测量状态 + getSurveyorData().clearSurveyStateAndPosition(); + + ICycleRecorder cycleRecorder = getCycleRecorder(); + cycleRecorder.changeCycleIndex(args.getInt(KEY_CYCLE_INDEX, 0)); + setCurrentCycle(cycleRecorder.currentCycleIndex()); + + //1.检测当前cycle是否完成测量 + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData()); + //2.如果当前测回还有待测数据,则执行测量 + if (!completed) { + //从当前测回开始处查找目标并执行测量 + findTargetFromBeginInCurrentCycle(false); + return; + } + //3.如果当前测回结束测量,判断是否通过检测 + ToleranceDetailRecord toleranceDetailRecord = getToleranceRecord(); + double horCycle2CDiff = toleranceDetailRecord.getHorCycleDirect2CDifference(); + double verCycle2CDiff = toleranceDetailRecord.getVerCycleDirectIDifference(); + String error = SingleCycleCheckMethod.check( + horCycle2CDiff, + verCycle2CDiff, + stationId(), + getCycleRecorder().currentCycleIndex(), + getSurveyorData(), + getCachedData()); + if (error != null && !error.isEmpty()) { + SingleCycleTipsMethod.showTips(error, + stationId(), + getCycleRecorder().currentCycleIndex(), + stateDelegate(), + fragmentManager(), + lifecycleOwner()); + return; + } + //4.更新测站状态 + setSingleCycleSchedule(getCycleRecorder().currentCycleIndex(), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + //5.检测其他测回状态 + if (isNeedCancelEnterIdle(getCycleRecorder().currentCycleIndex())) { + return; + } + + //6.清空测量状态 + onCompletedCheck(); + } + + protected void onCompletedCheck() { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + + protected static final String KEY_CYCLE_INDEX = "___cycle__index__"; + + static void enter(StateManager stateManager, int cycleIndex) { + Bundle args = new Bundle(); + args.putInt(KEY_CYCLE_INDEX, cycleIndex); + stateManager.enter(StateType.doCalScheduleSingleCycle, args); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteAllCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteAllCycleState.java new file mode 100644 index 0000000..c687f54 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteAllCycleState.java @@ -0,0 +1,70 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +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.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.utils.ThreadPoolUtil; + +import com.bingce.controlnetwork.R; + +/* + * 删除本测站所有测回数据 + * */ +class _DoDeleteAllCycleState extends __BaseState { + + private static final String KEY_STATION_ID = "__station_id"; + + static Bundle args(String stationId) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + return args; + } + + public _DoDeleteAllCycleState(StateManager stateManager) { + super(StateType.doDeleteAllCycle, stateManager); + } + + @Override + 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)); + } + + 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); + }); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteCurrentCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteCurrentCycleState.java new file mode 100644 index 0000000..6fa1af8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteCurrentCycleState.java @@ -0,0 +1,69 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +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.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.state.StateType; +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__"; + + static Bundle args(String stationId, int periodIndex) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + args.putInt(KEY_PERIOD_INDEX, periodIndex); + return args; + } + + public _DoDeleteCurrentCycleState(StateManager stateManager) { + super(StateType.doDeleteCurrentCycle, stateManager); + } + + @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)); + } + + private void deleteSingleCycle(String stationId, int cycleIndex) { + ThreadPoolUtil.execute(() -> { + //删除数据 + ICachedData stationSurveyorDataSource = getCachedData(); + stationSurveyorDataSource.deleteSurveyorRecordSync(stationId, cycleIndex); + + //清除已经提示测站可以检测标识 + IConfigDataSource configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource(); + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; + configDataSource.setSync(key, ConfigConstants.VALUE_NO); + + //设置当前测回 + setCurrentCycleSync(cycleIndex); + //重置所有测回和当次测回进度 + setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setSingleCycleScheduleSync(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + if (cycleIndex == 0) { + //当第一测回 + //重置学习测量的标志 + resetLearnDataTag(); + } + + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true); + }); + + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMove2NextValidateState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMove2NextValidateState.java new file mode 100644 index 0000000..7afaeb3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMove2NextValidateState.java @@ -0,0 +1,95 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +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.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 移动到一个待测量位置 + *

+ * 不会跳转到其他测期 + *

+ * 可能涉及转向(盘左->盘右) + */ +class _DoMove2NextValidateState extends __BaseState { + + public _DoMove2NextValidateState(StateManager stateManager) { + super(StateType.doMove2NextValidate, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cachedData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + + int pointCount = cachedData.pointCount(); + int currentIndex = surveyorData.currentIndex(); + if (currentIndex < 0) { + currentIndex = 0; + } + final int currentCycleIndex = cycleRecorder.currentCycleIndex(); + final LeftOrRight currentSurveyorState = surveyorData.leftOrRight(); + + //1.先查找补测数据 + FindTargetMethod.Target surveyorTarget = FindTargetMethod.findDirtyTargetInSingleCycle(stationId(), currentCycleIndex, + currentIndex, + currentSurveyorState, + pointCount, + true, + cachedData); + //如果在当前测回找到待被测数据,立刻跳转到相应位置 + if (surveyorTarget != null) { + navigation2(surveyorTarget.itemIndex, surveyorTarget.leftOrRight); + return; + } + //2.查找empty数据 + FindTargetMethod.Target emptyTarget = FindTargetMethod.findEmptyTargetInSingleCycle(stationId(), currentCycleIndex, + currentIndex, + currentSurveyorState, + pointCount, + true, + cachedData); + if (emptyTarget != null) { + if (isAutoSurveyOpen()) { + if (emptyTarget.itemIndex == getCachedData().pointCount() - 1 + && emptyTarget.leftOrRight == LeftOrRight.right) { + TtsManager.getInstance().speak(Tools.getString(R.string.start_face_right)); + } + } + //直接跳转到目标点,开启新测量 + navigation2(emptyTarget.itemIndex, emptyTarget.leftOrRight); + return; + } + //3.当前测回完成测量,停留状态 + //重置标识 +// quitSurveyStateAndStandStill(false); + enterIdleAndClearSurveyorStatePosition(); + } + + /** + * 跳转到下一目标点 + * + * @param targetIndex 目标点索引 + * @param targetSurveyorState 测量状态(盘左or盘右) + */ + private void navigation2(int targetIndex, LeftOrRight targetSurveyorState) { + //更新测量进度 + setSurveyPosition(targetIndex, targetSurveyorState); + + //清除测量状态,进入idle,但是不停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(false); + + //滚动 + scroll2(targetIndex); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMoveBackState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMoveBackState.java new file mode 100644 index 0000000..14b7152 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMoveBackState.java @@ -0,0 +1,143 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.SurveyorRecord; +import com.bingce.controlapphelper.model.DataCategory; +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.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + +import com.bingce.controlnetwork.R; + +/** + * 移动到上一测量结点,伴随删除上次测量数据 + */ +public class _DoMoveBackState extends __BaseState { + + public _DoMoveBackState(StateManager stateManager) { + super(StateType.doMoveBack, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cachedDataSource = getCachedData(); + ISurveyorData surveyorDataSource = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + + final int pointCount = cachedDataSource.pointCount(); + final int currentCycle = cycleRecorder.currentCycleIndex(); + final int currentIndex = surveyorDataSource.currentIndex(); + final LeftOrRight leftOrRight = surveyorDataSource.leftOrRight(); + + if (currentIndex < 0) { + //如果测量结束,直接使用0号点盘右 + int targetIndex = 0; + LeftOrRight targetState = LeftOrRight.right; + warningWithStandStill(cachedDataSource, currentCycle, targetIndex, targetState); + return; + } + String currentPointId = cachedDataSource.pointId(currentCycle, currentIndex); + String currentRecordKey = IdUtil.createSurveyorRecordId(stationId(), currentCycle, currentPointId, leftOrRight); + DataCategory dataCategory = cachedDataSource.valueState(currentRecordKey); + if (dataCategory.isNeedResurvey()) {//如果当前位置是脏数据(说明正在补测) + //回退到上一个脏数据位置 + back2LastDirtyPosition(currentCycle, currentIndex, leftOrRight, pointCount, cachedDataSource); + } else if (dataCategory.isEmptyData()) { + //如果是空数据,说明测量进行中,查找上一个数据即可 + //需要提醒用户数据会被删除 + back2LastVisiblePosition(currentCycle, currentIndex, leftOrRight, pointCount, cachedDataSource); + } else { + //bug,不应该有这个地方 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + } + + private void back2LastDirtyPosition(int currentCycle, int currentIndex, LeftOrRight leftOrRight, + int pointCount, ICachedData cachedData) { + //反向查找,但是找到目标后不能删除其数据,否则会造成「数据空洞」 + FindTargetMethod.Target target = FindTargetMethod.findTargetInSingleCycle( + stationId(), currentCycle, currentIndex, leftOrRight, pointCount, false, + DataCategory.dirtyAndSurveyed, + cachedData); + if (target == null) { + //在dirtyAndNeedReSurveyor数据没有修复完成之前,不能回退正常数据 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + //找到dirtyAndSurveyed数据, + //则将其校正为dirtyAndNeedReSurveyor + String pointId = cachedData.pointId(target.cycleIndex, target.itemIndex); + String recordKey = IdUtil.createSurveyorRecordId(stationId(), target.cycleIndex, pointId, target.leftOrRight); + SurveyorRecord surveyorRecord = cachedData.getSurveyorRecord(recordKey); + if (surveyorRecord != null) { + if (surveyorRecord.value1Status.isResurveyed()) { + surveyorRecord.value1Status = DataCategory.needResurvey(); + } + if (surveyorRecord.value2Status.isResurveyed()) { + surveyorRecord.value2Status = DataCategory.needResurvey(); + } + cachedData.updateCache(surveyorRecord); + //重置进度 + resetSchedule(_DoMoveBackState.this, + target.itemIndex, + target.leftOrRight); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + } + } + + private void back2LastVisiblePosition(int currentCycle, int currentIndex, LeftOrRight leftOrRight, + int pointCount, + ICachedData cachedData) { + + //从当前开始,向上查找第一个normal数据 + FindTargetMethod.Target target = + FindTargetMethod.findTargetInSingleCycle( + stationId(), currentCycle, currentIndex, leftOrRight, pointCount, false, + DataCategory.normalCategory(), + cachedData); + if (target == null) { + failureTipsWithAutoStandStill(getContext().getString(R.string.tips_no_more_record_2_rollback)); + return; + } + + warningWithStandStill(cachedData, + currentCycle, + target.itemIndex, + target.leftOrRight); + } + + private void warningWithStandStill( + ICachedData cachedDataSource, + int currentCycle, int itemIndex, LeftOrRight leftOrRight) { + optionTipsWithStandStill(getContext().getString(R.string.tips_will_resurvey_last_record), + () -> { + //删除当前数据 + cachedDataSource.deleteSurveyorRecord(stationId(), + currentCycle, itemIndex, leftOrRight); + //重置进度 + setSingleCycleSchedule(currentCycle, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + resetSchedule(this, itemIndex, leftOrRight); + }); + } + + private static void resetSchedule(__BaseState state, + int targetIndex, + LeftOrRight leftOrRight) { + //设置测量目标点 + state.setSurveyPosition(targetIndex, leftOrRight); + //清除测量状态,进入idle + //如果当前已经关闭自动测量,就不重置自动测量开关(用户已经表示不想自动测量) + state.enterIdleAndClearSurveyStateAndResetAutoMode(!state.isAutoSurveyClosed()); + + state.scroll2(targetIndex); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoRecordCleanState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoRecordCleanState.java new file mode 100644 index 0000000..222fbc8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoRecordCleanState.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.DataCategory; +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.state.StateType; + +/** + * 记录测量数据 + */ +class _DoRecordCleanState extends __BaseState { + public _DoRecordCleanState(StateManager stateManager) { + super(StateType.doRecordClean, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cacheData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + //设置数据正常 + surveyorData.setDataCategory(DataCategory.normalCategory()); + //存储(缓存+数据库) + cacheData.cache(cycleRecorder.currentCycleIndex(), surveyorData); + + //检测单测回是否完成 + navigation2(StateType.isSingleCycleCompleted); + } +} 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 new file mode 100644 index 0000000..f018210 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoSurveyorState.java @@ -0,0 +1,298 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.model.DataCategory; +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.state.ISurveyState; +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; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.surveyor.state.StateConstants; +import com.bingce.device.Device; +import com.bingce.totalstation.TotalStation; +import com.bingce.totalstation.protocol.south.SouthAndroidBtInterface; +import com.bingce.totalstation.protocol.topcon.TopconInterface; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import blankj.utilcode.util.ToastUtils; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoSurveyorState extends __BaseState implements ISurveyorListener, ISurveyorRemindListener { + private final ISurveyState surveyState; + //最多测量次数,如果3次测量都没有获取正常数据,则跳过 + private static final int MAX_SURVEYOR_COUNT = 3; + private static int failureCount = 0; + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_EXCEED_MAX = 1;//测量失败次数超出最大限制 + private static final int RESULT_FAILURE_ERROR = 2;//测量失败,又没有允许重复尝试 + private static final boolean allowTryWhenFailure = true;//在测量失败的时候,是否允许重新测量 + + private int measureTimeIndex = 0;//当前测点是第几次测量 + private boolean isAlreadyRemindUserAimingAtWire = false; + + private final Handler handler; + + public _DoSurveyorState(StateManager stateManager, ISurveyState surveyState) { + super(StateType.doSurveyor, stateManager); + this.surveyState = surveyState; + handler = new Handler(Looper.getMainLooper()); + } + + @Override + public void enter(Bundle args) { + measureTimeIndex = 0; + + isAlreadyRemindUserAimingAtWire = false; + if (args != null) { + isAlreadyRemindUserAimingAtWire = args.getBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE); + } + + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + ICachedData cachedDataSource = getCachedData(); + + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + int cycleCount = toleranceRecord.getCycleCount(); + int pointCount = cachedDataSource.pointCount(); + + int otherCycle = -1; + //1.先检测其他测回是否有正在测量数据 + for (int cycleIndex = 0; cycleIndex < cycleCount; cycleIndex++) { + if (cycleIndex == currentCycleIndex) { + continue; + } + //遍历该测回内所有点,检测是否有测量数据 + for (int itemIndex = 0; itemIndex < pointCount; itemIndex++) { + String pointId = cachedDataSource.pointId(cycleIndex, 0); + String key = IdUtil.createSurveyorRecordId(stationId(), cycleIndex, pointId, LeftOrRight.left); + //检测该测回是否有数据,目前应该只需要检测盘左0就可以了,因为一个测回内数据不能跳过 + DataCategory dataCategory = cachedDataSource.valueState(key); + if (dataCategory.hasData()) { + //说明该测回有数据,则进一步检测是否完成 + if (!cachedDataSource.isSingleCycleAllDataValidate(cycleIndex)) { + //已经测量但是没有完成,则提示 + otherCycle = cycleIndex; + break; + } + } + } + //如果当前遍历到的测回有数据,则退出遍历,提醒用户 + if (otherCycle >= 0) { + break; + } + } + //2.如果其他测回有正在测量数据,且没有完成测量,提示用户继续测量将会删除其数据 + if (otherCycle != -1) { + final int targetCycleIndex = otherCycle; + optionTipsWithStandStill( + SurveyorCycleUtil.cycleName(otherCycle) + Tools.getString(R.string.unfinished_measurements_starting_this_measurement_will_delete), + () -> optionTipsWithStandStill( + Tools.getString(R.string.confirm_delete) + SurveyorCycleUtil.cycleName(targetCycleIndex) + Tools.getString(R.string.data_ask), + () -> { + String stationId = stationId(); + //删除数据 + cachedDataSource.deleteSurveyorRecord(stationId, targetCycleIndex); +// isAlreadyRemindUserAimingAtWire = false; + //执行测量 + doSurveyor(); + })); + return; + } + + //3.其他测回没有正在测量数据,则在当前测回执行测量 + doSurveyor(); + } + + private void doSurveyor() { + failureCount = 0; + //判断设备是否连接 + if (surveyorImpl().isReady()) { + //发送测量信号 + SurveyStateEvent.postSurveying(positionFragment); + //注册接收测量数据 + surveyorImpl().prepareSurveyor(); + sendSurveyRequest(); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + Device.getInstance().remindConnectDevice(); + } + } + + @Override + public void onReceive(double originalHa, double originalVa, double sd, double clockwiseHa, double topVa, double hd, double vd) { + //重置错误读数 + failureCount = 0; + if (getSurveyorData().onSurveyor(originalHa, originalVa, sd, hd)) { + //测量数据成功,可以退出测量状态 + onSuccess(); + } else {//测量数据不完全,需要继续测量 + measureTimeIndex = 1;//更新测量索引 + refreshUI(); + + if (TotalStation.getInstance() instanceof TopconInterface) { + //这个仪器需要延迟500毫秒发送指令 + handler.postDelayed(this::sendSurveyRequest, 500); + } else if (TotalStation.getInstance() instanceof SouthAndroidBtInterface) { + handler.postDelayed(this::sendSurveyRequest, 100); + } else { + sendSurveyRequest(); + } + } + } + + @Override + public void onError(String errorMsg) { + TtsManager.getInstance().speak(errorMsg); + if (allowTryWhenFailure) {//允许重新测量 + if (!isLive()) { + return; + } + //测量出现异常,需要处理 + failureCount++; + if (failureCount >= MAX_SURVEYOR_COUNT) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.many_measure_failed)); + } + 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); + } + } else { + onCompleted(RESULT_FAILURE_ERROR, errorMsg); + } + } + + private void sendSurveyRequest() { + int currentIndex = getCurrentIndex(); + if (currentIndex < 0) { + currentIndex = 0; + } + + SurveyorPoint surveyorPoint = getCachedData().getSurveyorPoint(getCycleRecorder().currentCycleIndex(), currentIndex); + ISurveyorData surveyorData = getSurveyorData(); + + surveyorImpl().requestSurveyor(new RequestSurveyorParam(getRequestSurveyorParamAuto(), getInstrumentHeight(), surveyorPoint, measureTimeIndex, + surveyorData.currentIndex(), surveyorData.leftOrRight(), isAlreadyRemindUserAimingAtWire)); + } + + private void onSuccess() { + onCompleted(RESULT_SUCCESS, ""); + } + + private void onCompleted(int result, String msg) { + //退出测量 + surveyorImpl().exitSurveyor(); + switch (result) { + case RESULT_SUCCESS://进入读数检测状态 + //检测是否处于「自动测量」 + if (!surveyState.isAutoSurveying()) { + SurveyStateEvent.postSuccess(positionFragment); + } + navigation2(StateType.checkReadData); + break; + case RESULT_FAILURE_EXCEED_MAX: +// if (SettingValueUtil.isAbandonPoint() && isAllowAbandonForVarifyIndex()) { +// dealErrorDataSkip(msg); +// } else { +// dealErrorDataNormal(msg); +// } + dealErrorDataNormal(msg); + break; + case RESULT_FAILURE_ERROR: + dealErrorDataNormal(msg); + break; + default: + throw new RuntimeException("un reached state -- surveyor"); + } + } + + @Override + protected void quite() { + super.quite(); + surveyorImpl().exitSurveyor(); + } + + @Override + protected void resume() { + getSurveyorData().clearSurveyState(); + } + + @Override + public void remindUserAimingAtWire() { + //退出测量 + surveyorImpl().exitSurveyor(); + navigation2(StateType.doWellMeasureRotationReady); + } + + private void dealErrorDataNormal(String msg) { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg); + navigation2(StateType.SurveyorFailure, args); + } + + private void dealErrorDataNormal(String msg, boolean isShowDialog) { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg, isShowDialog); + navigation2(StateType.SurveyorFailure, args); + } + + private void dealErrorDataSkip(String msg) { + optionTipsCountDown(msg + Tools.getString(R.string.is_it_abandoned), + Tools.getString(R.string.switch_abandon), + Tools.getString(R.string.ignore), + () -> { + changeSkip(getCycleRecorder().currentCycleIndex(), getCurrentIndex()); + navigation2(StateType.isSingleCycleCompleted); + }, + () -> dealErrorDataNormal(msg, false), + () -> dealErrorDataNormal(msg, false)); + } + + /** + * 针对第一个点和闭合是否废弃验证 + * + * @return + */ + private boolean isAllowAbandonForVarifyIndex() { + boolean autoClose = getStation().isAutoClose(); + int pointCount = getCachedData().pointCount(); + boolean abandon = true; + int currentIndex = getCurrentIndex(); + if (autoClose) { + if (currentIndex == 0 || currentIndex == pointCount - 1) { + abandon = false; + } + } else { + if (currentIndex == 0) { + abandon = false; + } + } + return abandon; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoWellMeasureRotationReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoWellMeasureRotationReadyState.java new file mode 100644 index 0000000..9bdbde8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoWellMeasureRotationReadyState.java @@ -0,0 +1,30 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +/** + * 钢丝测量旋转到位状态 + */ +class _DoWellMeasureRotationReadyState extends __BaseState { + + public _DoWellMeasureRotationReadyState(StateManager stateManager) { + super(StateType.doWellMeasureRotationReady, stateManager); + } + + @Override + public void enter(Bundle args) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.please_aiming_at_alone_distance_point_then_measure))); + SurveyStateEvent.postIdle(positionFragment); + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, false, true)); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IdleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IdleState.java new file mode 100644 index 0000000..0606880 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IdleState.java @@ -0,0 +1,134 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; + +/** + * 空闲状态 + *

+ * 将刷新界面 + */ +class _IdleState extends __BaseState { + private final @NonNull + IAutoModeSwitcher autoModeSwitcher; + + public _IdleState(StateManager stateManager, @NonNull IAutoModeSwitcher autoModeSwitcher) { + super(StateType.idle, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + //1.刷新界面 + refreshUI(); + + refreshGoBackBtnEnable(); + + //3.当前cycle是否完成测量 + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData()); + //4.检测是否满足自动测量条件 + ThreadPoolUtil.execute(() -> { + //判断当前条件是否满足自动测量 + + boolean haveAutoCondition = haveAutoCondition(); + + if (haveAutoCondition && autoModeSwitcher.isAutoModeOpen() && isLive()) { + navigation2(StateType.doSurveyor); + } else if (haveAutoCondition && autoModeSwitcher.isAutoModeNotSpecial() && !completed) { + //用户选择后会发送通知,更新测量按钮UI + tips4StartAutoSurvey(); + } else { +// ControlSurveyResult.isAbandon(autoMeasureReadyCode) != null//这个错误 + if (autoModeSwitcher.isAutoModeOpen()) { + autoModeSwitcher.resetAutoMode(); + } + postEvent(haveAutoCondition, autoModeSwitcher.isAutoModeOpen(), completed); + } + + }); + } + + /** + * 弹框提示用户是否开启自动测量 + */ + private void tips4StartAutoSurvey() { + runOnUI(() -> + TipsWith2OptionFragment.hardTips( + fragmentManager(), + lifecycleOwner(), + getContext().getString(R.string.tips_finish_study_should_auto_survey), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doSurveyor); + + postEvent(true, true, false); + } + + @Override + public void onCancel() { + autoModeSwitcher.closeAutoMode(); + + postEvent(true, false, false); + } + + @Override + public void onIgnore() { + autoModeSwitcher.closeAutoMode(); + + postEvent(true, false, false); + } + } + )); + } + + private void postEvent(boolean isReadyAutoSurvey, boolean isOpenAutoSurvey, boolean isSingleCompleted) { + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, isReadyAutoSurvey, isOpenAutoSurvey)); + if (isSingleCompleted) { + SurveyStateEvent.postCompleted(positionFragment); + } else if (!isOpenAutoSurvey) { + SurveyStateEvent.postIdle(positionFragment); + } + } + + @Override + protected void resume() { + autoModeSwitcher.resetAutoMode(); + //刷新测量按钮 + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData()); + boolean isReady = autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS; + + postEvent(isReady, false, completed); + } + + private boolean haveAutoCondition() { + int autoMeasureReadyCode = autoModeSwitcher.isReadyAutoSurvey(); + return autoMeasureReadyCode == ControlSurveyResult.CODE_SUCCESS; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Is2CCheckReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Is2CCheckReadyState.java new file mode 100644 index 0000000..4b17c04 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Is2CCheckReadyState.java @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.DataCategory; +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.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + +/** + * 判断是否满足「2C」检测条件 + */ +class _Is2CCheckReadyState extends __BaseState { + private static final int RESULT_YES = 0;//可以检测「2C」 + private static final int RESULT_NO = 1;//不可以检测「2C」 + + public _Is2CCheckReadyState(StateManager stateManager) { + super(StateType.isReady2CCheck, stateManager); + } + + @Override + public void enter(Bundle args) { + ISurveyorData surveyorDataSource = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + ICachedData cachedData = getCachedData(); + + int currentIndex = surveyorDataSource.currentIndex(); + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + LeftOrRight currentLeftOrRight = surveyorDataSource.leftOrRight(); + + //只需要对面位置有「新鲜数据」,就能执行2c + //当前位置正处于测量,数据还没有缓存,所以不需要检测数据合法性 + String pointId = cachedData.pointId(currentCycleIndex, currentIndex); + DataCategory oppositeCategory = cachedData.valueState( + IdUtil.createSurveyorRecordId(stationId(), currentCycleIndex, pointId, currentLeftOrRight.opposite())); + if (oppositeCategory.isFreshData()) { + onCompleted(RESULT_YES); + } else { + onCompleted(RESULT_NO); + } + } + + private void onCompleted(int result) { + if (RESULT_YES == result) { + navigation2(StateType.check2C); + } else if (RESULT_NO == result) { + navigation2(StateType.doRecordClean); + } else { + throw new RuntimeException("error half cycle complete check"); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsAllCycleCompletedState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsAllCycleCompletedState.java new file mode 100644 index 0000000..01a20e4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsAllCycleCompletedState.java @@ -0,0 +1,90 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +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.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.SpeakCache; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/* + * 检测是否所有 测期都完成了测量 + * + * 只有在当前测期完成测量之后,才会进入当前状态 + * */ +public class _IsAllCycleCompletedState extends __BaseState { + private static final int INVALIDATE_CYCLE = -1; + private final IAutoModeSwitcher autoModeSwitcher; + + public _IsAllCycleCompletedState(@NonNull StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.isAllCycleCompleted, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + int cycleCount = getToleranceRecord().getCycleCount(); + + int theCycleNotAllDataIsValidate = INVALIDATE_CYCLE; + //查找数据不全的测回 + for (int cycleIndex = 0; cycleIndex < cycleCount; cycleIndex++) { + if (!getCachedData().isSingleCycleAllDataValidate(cycleIndex)) { + //对不全数据的测回赋值 + theCycleNotAllDataIsValidate = cycleIndex; + break; + } + } + + boolean completed = INVALIDATE_CYCLE == theCycleNotAllDataIsValidate; + + if (completed) { + if (isAutoSurveyOpen()) { + //检测是否已经提示 + //检测是否需要提示测站检测 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + ThreadPoolUtil.execute(() -> { + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId(); + ConfigRecord record = configDataSource.getByKeySync(key); + if (record == null || ConfigConstants.VALUE_NO.equals(record.getConfigValue())) { + runOnUI(() -> TtsManager.getInstance().speak(Tools.getString(R.string.all_cycle_completed))); + } + }); + } + //标识测站完成测量(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //进入idle状态 + //清除测量状态,进入测站检测,停止自动测量 + enterStationCheckAndClearSurveyStateAndResetAutoMode(); + } else { + if (autoModeSwitcher.isAutoModeOpen()) { + //直接切换测回 + //切换测回 + getCycleRecorder().changeCycleIndex(theCycleNotAllDataIsValidate); + //修改当前测回 + setCurrentCycle(theCycleNotAllDataIsValidate); + //存储一下已经播放切换测回的的节点 + SpeakCache.getInstance().saveSpeakSwitchCycle(); + //查找测量目标 + findTargetFromBeginInCurrentCycle(false); + //播报 + TtsManager.getInstance().speak(Tools.getString(R.string.current_cycle_complete_start_surveyor) + SurveyorCycleUtil.cycleName(theCycleNotAllDataIsValidate)); + } else { + //提示是否进入其他未完成测回继续测量 + option4Jump2OtherEmptyCycle(theCycleNotAllDataIsValidate); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsHalfCycleZeroCheckReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsHalfCycleZeroCheckReadyState.java new file mode 100644 index 0000000..cfdc465 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsHalfCycleZeroCheckReadyState.java @@ -0,0 +1,68 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.DataCategory; +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.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + +/* + * 判断是否需要检测「半测回归零差」 + * */ +class _IsHalfCycleZeroCheckReadyState extends __BaseState { + private static final int RESULT_ERROR = -1;//状态错误 + private static final int RESULT_YES = 0;//可以检测「半测回归零差」 + private static final int RESULT_NO = 1;//不可以检测「半测回归零差」 + + public _IsHalfCycleZeroCheckReadyState(StateManager stateManager) { + super(StateType.isHalfCycleZeroCheckReady, stateManager); + } + + + @Override + public void enter(Bundle args) { + if (isStationClosed()) { + ICachedData cachedData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + int pointCount = cachedData.pointCount(); + int currentItemIndex = surveyorData.currentIndex(); + + //检测target处数据类型,如果存在dirty或empty数据,则不进行半测回归零 + //当前位置不需要检测,因为下处于测量中 + int result = RESULT_NO; + if (currentItemIndex == 0 || currentItemIndex == pointCount - 1) { + ICycleRecorder cycleRecorder = getCycleRecorder(); + int cycleIndex = cycleRecorder.currentCycleIndex(); + String stationId = stationId(); + LeftOrRight leftOrRight = surveyorData.leftOrRight(); + int targetIndex = pointCount - 1 - currentItemIndex; + + String targetPointId = cachedData.pointId(cycleRecorder.currentCycleIndex(), targetIndex); + String targetKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, targetPointId, leftOrRight); + DataCategory targetDataCategory = cachedData.valueState(targetKey); + //对面数据正常,可以执行半测回归零 + if (targetDataCategory.isFreshData()) { + result = RESULT_YES; + } + } + onCompleted(result); + } else { + onCompleted(RESULT_ERROR); + } + + } + + private void onCompleted(int result) { + if (RESULT_YES == result) {//检测半测回归零 + navigation2(StateType.checkHalfCycleZero); + } else if (RESULT_NO == result || RESULT_ERROR == result) { + navigation2(StateType.isReady2CCheck); + } else { + throw new RuntimeException("error half cycle complete check"); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsSingleCycleCompletedState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsSingleCycleCompletedState.java new file mode 100644 index 0000000..e54e20c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsSingleCycleCompletedState.java @@ -0,0 +1,75 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + + +public class _IsSingleCycleCompletedState extends __BaseState { + private static final int RESULT_YES = 0;//测回结束 + private static final int RESULT_NO = 1;//测回未结束 + + public _IsSingleCycleCompletedState(StateManager stateManager) { + super(StateType.isSingleCycleCompleted, stateManager); + } + + @Override + public void enter(Bundle args) { + onCompleted( + isSingleCycleCompleted(stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData())); + } + + private void onCompleted(boolean completed) { + if (completed) { + //这里先刷新下UI,不然弹窗后面的list不显示最后一条数据 + getSurveyorData().clearSurveyStateAndPosition(); + refreshUI(); + + int cycleIndex = getCycleRecorder().currentCycleIndex(); + //更新测回测量进度 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //状态切换 + navigation2(StateType.checkSingleCycle); + } else { + findTargetFromBeginInCurrentCycle(false); + } + } + + /** + * 判断单个测回是否测量完成(不要求通过检测) + */ + public static boolean isSingleCycleCompleted(String stationId, int cycleIndex, ICachedData cachedData) { + int result = RESULT_YES; + + //测回内所有数据都是「新鲜数据」才能执行「测回内检测」 + for (int index = 0; index < cachedData.pointCount(); index++) { + + if (cachedData.isPointAbandon(cycleIndex, index)) { + continue; + } + + String pointId = cachedData.pointId(cycleIndex, index); + + String leftKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.left); + String rightKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.right); + + DataCategory leftDataCategory = cachedData.valueState(leftKey); + DataCategory rightDataCategory = cachedData.valueState(rightKey); + + if (leftDataCategory.isFreshData() && rightDataCategory.isFreshData()) { + continue; + } + result = RESULT_NO; + break; + } + + return RESULT_YES == result; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_SurveyorFailureState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_SurveyorFailureState.java new file mode 100644 index 0000000..9135bf6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_SurveyorFailureState.java @@ -0,0 +1,52 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +/* + * 仪器导致的测量失败 + * + * 全站仪多次测量失败,进入该状态 + * */ +class _SurveyorFailureState extends __BaseState { + + public _SurveyorFailureState(StateManager stateManager) { + super(StateType.SurveyorFailure, stateManager); + } + + @Override + public void enter(Bundle args) { + String error = ""; + boolean isShowDialog = true; + if (args != null) { + error = args.getString(KEY); + isShowDialog = args.getBoolean(KEY_IS_SHOW_DIALOG, true); + } + + if (isShowDialog) { + failureTipsWithAutoStandStill(error + Tools.getString(R.string.please_observe_target)); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + + } + + private static final String KEY = "error"; + private static final String KEY_IS_SHOW_DIALOG = "KEY_IS_SHOW_DIALOG"; + + public static Bundle args(String error) { + Bundle args = new Bundle(); + args.putString(KEY, error); + return args; + } + + public static Bundle args(String error, boolean isShowDialog) { + Bundle args = new Bundle(); + args.putString(KEY, error); + args.putBoolean(KEY_IS_SHOW_DIALOG, isShowDialog); + return args; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/__BaseState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/__BaseState.java new file mode 100644 index 0000000..a4dfef3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/__BaseState.java @@ -0,0 +1,586 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +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.model.IStateDelegate; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +public abstract class __BaseState { + private final StateType type; + private final StateManager stateManager; + + protected final int positionFragment = MeasureFragment.POSITION_DIRECTION_MEASURE; + + /** + * 判断常量 + */ + private final int DEFAULT_AUTO_MODE = 0; + private final int RESET_AUTO_MODE = 1; + private final int CLOSE_AUTO_MODE = 2; + + public __BaseState(final StateType stateType, final StateManager stateManager) { + this.type = stateType; + this.stateManager = stateManager; + } + + final protected StateType getType() { + return type; + } + + final protected @NonNull + ToleranceDetailRecord getToleranceRecord() { + return stateManager.toleranceRecord; + } + + final protected @NonNull + ISurveyorData getSurveyorData() { + return stateManager.surveyorData; + } + + private @NonNull + IAutoModeSwitcher autoModeRecorder() { + return stateManager; + } + + /** + * 设置测量位置 + */ + final protected void setSurveyPosition(int index, LeftOrRight leftOrRight) { + stateManager.surveyorData.setCurrentIndex(index); + stateManager.surveyorData.setLeftOrRight(leftOrRight); + //新增 + if (isAloneDistance()) + ToastUtils.showShort(getContext().getString(R.string.attention_point_is_alone_distance)); + } + + final protected ISurveyor surveyorImpl() { + return stateManager.surveyor; + } + + final protected @NonNull + ICachedData getCachedData() { + return stateManager.cachedData; + } + + SurveyorStationRecord getStation() { + return stateManager.stationRecord; + } + + RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return stateManager.getRequestSurveyorParamAuto(); + } + + void changeSkip(int cycleIndex, int index) { + SurveyorStationRecord station = getStation(); + //缓存点 + getCachedData().setPointAbandon(cycleIndex, index); + //数据库点 + String pointId = getCachedData().originalPointId(cycleIndex, index); + for (SurveyorPoint surveyorPoint : station.items) { + if (TextUtils.equals(pointId, surveyorPoint.getOriginalPointId())) { + surveyorPoint.setAbandon(true); + break; + } + } + ThreadPoolUtil.execute(() -> { + SurveyorDatabaseFactory.instance.getSurveyorStation().update(station); + }); + } + + final protected @NonNull + ICycleRecorder getCycleRecorder() { + return stateManager.cycleRecorder; + } + + final protected @NonNull + Context getContext() { + return stateManager.context; + } + + final protected void scroll2(int itemIndex) { + stateManager.scrollDelegate.onScrollTo(itemIndex); + } + + final protected void toast(String warning) { + ToastUtils.showShort(warning); + } + + final protected void toast(@StringRes int warning) { + ToastUtils.showShort(warning); + } + + public abstract void enter(Bundle args);//进入状态 + + final protected void navigation2(StateType stateType) { + stateManager.enter(stateType); + } + + final protected void navigation2(StateType stateType, Bundle args) { + stateManager.enter(stateType, args); + } + + final boolean isStationClosed() { + return stateManager.isStationAutoClosed(); + } + + final protected String stationId() { + return stateManager.stationId(); + } + + final protected FragmentManager fragmentManager() { + return stateManager.fragmentManager(); + } + + final protected LifecycleOwner lifecycleOwner() { + return stateManager.lifecycleOwner(); + } + + final protected void tips(String msg, Runnable runnable) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + if (runnable != null) { + runnable.run(); + } + }); + } + + /** + * 错误提示 + *

+ * 用户不能忽略,点击确定后自动「停留原地」 + */ + final protected void failureTipsWithAutoStandStill(String msg) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void failureTipsWithAutoStandStill(String msg, Runnable runnable) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + runnable.run(); + enterIdleAndClearSurveyStateAndResetAutoMode(true); + }); + } + + final protected void optionTipsWithStandStill(String msg, Runnable confirmCallback) { + optionTips(msg, null, null, + confirmCallback, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void optionTips(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + if (stateManager.isDead()) { + return; + } + TipsWith2OptionFragment.tips( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + final protected void optionTipsCountDown(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + if (stateManager.isDead()) { + return; + } + + TipsWith2OptionFragment.tipsCountDownTime( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + protected final void option4Jump2OtherCycle4Resurvey(int cycleIndex) { + option4Jump2OtherCycle(cycleIndex, true); + } + + protected final void option4Jump2OtherEmptyCycle(int cycleIndex) { + option4Jump2OtherCycle(cycleIndex, false); + } + + private void option4Jump2OtherCycle(int cycleIndex, boolean resurveyOrEmpty) { + String msg = Tools.getString(R.string.there_is_empty_data_to_be_tested_hint); + if (resurveyOrEmpty) { + msg = Tools.getString(R.string.there_is_supplementary_data_to_be_tested_hint); + } + optionTips(Tools.getString(R.string.at) + SurveyorCycleUtil.cycleName(cycleIndex) + msg, + null, + null, + () -> { + //切换测回 + getCycleRecorder().changeCycleIndex(cycleIndex); + //数据库存储修改当前测回 + setCurrentCycle(cycleIndex); + //查找测量目标 + findTargetFromBeginInCurrentCycle(false); + }, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void runOnUI(Runnable runnable) { + stateManager.runOnUI(runnable); + } + + final protected void runOnBackground(Runnable runnable) { + ThreadPoolUtil.execute(runnable); + } + + /** + * 设置测站的测回 + * + * @param cycle + */ + final protected void setCurrentCycle(int cycle) { + getCycleRecorder().changeCycleIndex(cycle); + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null), + String.valueOf(cycle))); + } + + final protected void setCurrentCycleSync(int cycle) { + getCycleRecorder().changeCycleIndex(cycle); + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null), + String.valueOf(cycle))); + } + + final protected void setSingleCycleSchedule(int cycleIndex, String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), null, cycleIndex), + schedule)); + } + + final protected void setSingleCycleScheduleSync(int cycleIndex, String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), null, cycleIndex), + schedule)); + } + + final protected void setAllCycleSchedule(String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null), + schedule)); + } + + final protected void setAllCycleScheduleSync(String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null), + schedule)); + } + + /** + * 如果resetAutoSurveyState为true,将重置autoSurvey状态为unknown + */ + final protected void findTargetFromBeginInCurrentCycle(boolean resetAutoSurveyState) { + getSurveyorData().clearSurveyStateAndPosition(); + if (resetAutoSurveyState) { + autoModeRecorder().resetAutoMode(); + } + navigation2(StateType.doMove2NextValidate); + } + + final protected void enterIdleAndClearSurveyState() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + /** + * 取消测量,会停在当前位置(索引+盘左or盘右),并进入idle + */ + final protected void enterIdleAndClearSurveyStateAndResetAutoMode(boolean resetAutoMode) { + clearSurveyStateAndCloseAutoModeAndStandStill(resetAutoMode ? RESET_AUTO_MODE : DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + final protected void enterIdleAndClearSurveyorStatePosition() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + true, StateType.idle); + } + + final protected void enterStationCheckAndClearSurveyStateAndResetAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(RESET_AUTO_MODE, + false, StateType.checkStation); + } + + final protected void enterIdleAndClearSurveyStateAndCloseAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(CLOSE_AUTO_MODE, false, StateType.idle); + } + + /** + * @param autoMode + * @param clearPosition + * @param stateType + */ + private void clearSurveyStateAndCloseAutoModeAndStandStill(int autoMode, boolean clearPosition, StateType stateType) { + //重置或者关闭自动模式 + if (autoMode == RESET_AUTO_MODE) { + autoModeRecorder().resetAutoMode(); + } else if (autoMode == CLOSE_AUTO_MODE) { + autoModeRecorder().closeAutoMode(); + } + //更新测量进度标识 + if (clearPosition) { + getSurveyorData().clearSurveyStateAndPosition(); + } else { + getSurveyorData().clearSurveyState(); + } + //进入某个状态 + navigation2(stateType); + } + + + /** + * 更新UI + */ + final protected void refreshUI() { + runOnUI(() -> getCachedData().notifyDateChange()); + } + + protected void quite() { + } + + protected void resume() { + } + + protected boolean isLive() { + return !stateManager.isDead(); + } + + protected boolean isAutoSurveyOpen() { + return stateManager.isAutoModeOpen(); + } + + protected boolean isAutoSurveyClosed() { + return stateManager.isAutoModeClose(); + } + + protected IStateDelegate stateDelegate() { + return new IStateDelegate() { + @Override + public void onOptionTips( + String msg, String confirmButton, String cancelButton, + Runnable confirmCallback, Runnable cancelCallback, Runnable ignoreCallback) { + optionTips( + msg, confirmButton, cancelButton, + confirmCallback, cancelCallback, ignoreCallback); + } + + @Override + public void resetSurveyorStateAndKeepPosition() { + //关闭自动测量 + autoModeRecorder().resetAutoMode(); + //更新测量进度标识 + getSurveyorData().clearSurveyState(); + //进入空闲状态 + navigation2(StateType.idle); + } + + @Override + public void resurveyPoints(int cycleIndex, List pointIds) { + if (cycleIndex == -1) { + cycleIndex = getCycleRecorder().currentCycleIndex(); + } + + //更新记录数据,包括将数据置为dirty和切换cycle + getCachedData().markReSurveyor(stationId(), cycleIndex, pointIds); + getCycleRecorder().changeCycleIndex(cycleIndex); + + //根据当前状态,查找一个目标 + findTargetFromBeginInCurrentCycle(true); + + //更新数据库标识 + setCurrentCycle(cycleIndex); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + + @Override + public void deleteSingleCycleData(int cycleIndex) { + //删除数据 + getCachedData().deleteSurveyorRecord(stationId(), cycleIndex); + //切换测回--一般不用,但是这里为了保险 + getCycleRecorder().changeCycleIndex(cycleIndex); + //查找一个新目标开启测量 + findTargetFromBeginInCurrentCycle(true); + + //更新数据库标识 + setCurrentCycle(cycleIndex); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + }; + } + + protected int getCurrentIndex() { + return stateManager.surveyorData.currentIndex(); + } + + protected int getCurrentCycleIndex() { + return stateManager.cycleRecorder.currentCycleIndex(); + } + + protected boolean isAloneDistance() { + return stateManager.getCachedData().isAloneDistance(stateManager.getCurrentCycle(), getCurrentIndex()); + } + + protected double getInstrumentHeight() { + return stateManager.getInsturmentHeight(); + } + + protected void refreshGoBackBtnEnable() { + stateManager.refreshGoBackBtnEnable(); + } + + protected void resetLearnDataTag() { + getRequestSurveyorParamAuto().resetCodeAutoMeasureCondition(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/ILookCase.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/ILookCase.java new file mode 100644 index 0000000..2c74b90 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/ILookCase.java @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + + +import com.bingce.controlapphelper.model.DataCategory; + +public interface ILookCase { + boolean whichCase(DataCategory dataCategory); +} + 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 new file mode 100644 index 0000000..4704a51 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/StateManagerHeightTraverse.java @@ -0,0 +1,541 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +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.event.RefreshGoBackButton; +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.AutoSurveyorMethod; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.IStateType; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorAutoImpl; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorMockAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorSingleImpl; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +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.coordlib.model.Coordinate; +import com.bingce.totalstation.ControlSurveyData; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.VipManager; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import blankj.utilcode.util.ToastUtils; + +public class StateManagerHeightTraverse implements IAutoModeSwitcher, ISurveyState, IStateType { + private final Map stateMap = new HashMap<>(); + private StateType currentStateType = StateType.idle; + private final FragmentManager fragmentManager; + private final LifecycleOwner lifecycleOwner; + private final IUIRunner iuiRunner; + final IScrollDelegate scrollDelegate; + + @NonNull + SurveyorStationRecord stationRecord; + final @NonNull + RequestSurveyorParamAuto requestSurveyorParamAuto; + final @NonNull + ToleranceDetailRecord toleranceRecord; + final @NonNull + ISurveyorData surveyorData; + final @NonNull + ICachedData cachedData; + final @NonNull + ICycleRecorder cycleRecorder; + final @NonNull + Context context; + private AutoModeType autoMode = AutoModeType.unknown; + @NonNull + final ISurveyor surveyor; + private final PointRecord stationPointRecord; + private final int positionFragment; + final boolean supportAutoSurvey; + + private StateManagerHeightTraverse( + final int positionFragment, + final boolean supportAutoSurvey,//是否支持自动测量 + final @NonNull RequestSurveyorParamAuto requestSurveyorParamAuto, + final @NonNull SurveyorStationRecord stationRecord, + final @NonNull PointRecord stationPointRecord, + final @NonNull ToleranceDetailRecord toleranceRecord, + final @NonNull Context context, + final @NonNull ISurveyorData surveyorData, + final @NonNull ICycleRecorder cycleRecorder, + final @NonNull ICachedData cachedData, + final @NonNull IScrollDelegate scrollDelegate, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner iuiRunner) { + this.positionFragment = positionFragment; + this.supportAutoSurvey = supportAutoSurvey; + + this.requestSurveyorParamAuto = requestSurveyorParamAuto; + this.stationRecord = stationRecord; + this.fragmentManager = fragmentManager; + this.lifecycleOwner = lifecycleOwner; + this.iuiRunner = iuiRunner; + this.scrollDelegate = scrollDelegate; + + this.context = context; + this.toleranceRecord = toleranceRecord; + this.surveyorData = surveyorData; + this.cachedData = cachedData; + this.cycleRecorder = cycleRecorder; + + this.stationPointRecord = stationPointRecord; + + if (Test.DEBUG) { + surveyor = new SurveyorMockAuto(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE, this.stationRecord.getId(), + this.stationRecord.isAutoClose(), + toleranceRecord.getCycleCount(), + cachedData, surveyorData, cycleRecorder, this, this); + } else { + if (supportAutoSurvey) { + surveyor = new SurveyorAutoImpl(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE, this); + } else { + surveyor = new SurveyorSingleImpl(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE); + } + } + _DoSurveyorState doSurveyorState = new _DoSurveyorState(positionFragment, this, this); + //注册接收数据的状态 + surveyor.register((ISurveyorListener) doSurveyorState); + surveyor.register((ISurveyorRemindListener) doSurveyorState); + + stateMap.put(StateType.init, new _Init(positionFragment, this)); + stateMap.put(StateType.doSurveyor, doSurveyorState); + stateMap.put(StateType.doAutoSurveyor, new _DoAutoSurveyorState(positionFragment, this, this)); + stateMap.put(StateType.SurveyorFailure, new _SurveyorFailureState(positionFragment, this)); + stateMap.put(StateType.doMove2NextValidate, new _DoMove2NextValidateState(positionFragment, this)); + stateMap.put(StateType.doMoveBack, new _DoMoveBackState(positionFragment, this)); + stateMap.put(StateType.checkStation, new _CheckStationState(positionFragment, this)); + + stateMap.put(StateType.doDeleteAllCycle, new _DoDeleteAllCycleState(positionFragment, this)); + stateMap.put(StateType.doDeleteCurrentCycle, new _DoDeleteCurrentCycleState(positionFragment, this)); + stateMap.put(StateType.doCalAdjust, new _DoCalAdjustState(positionFragment, this)); + stateMap.put(StateType.idle, new _IdleState(positionFragment, this, this)); + stateMap.put(StateType.doWellMeasureRotationReady, new _DoWellMeasureRotationReadyState(positionFragment, this)); + stateMap.put(StateType.checkTolerance, new _CheckToleranceState(positionFragment, this)); + + //监听测站数据变化 + runOnUI(() -> SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationRecord.getId()) + .observe(lifecycleOwner, record -> { + if (record == null || !stationRecord.getId().equals(record.getId())) { + return; + } + updateSurveyorStationRecord(record); + })); + } + + private void updateSurveyorStationRecord(SurveyorStationRecord record) { + this.stationRecord = record; + //更新测点信息 + if (stationRecord.getItems() != null) { + for (SurveyorPoint item : stationRecord.getItems()) { + if (item == null || !SurveyorPoint.TYPE_POINT.equals(item.getType())) { + //排除非测点 + continue; + } + cachedData.updateSurveyPointParams(item); + } + } + + cachedData.notifyDateChange(); + } + + String stationId() { + return stationRecord.getId(); + } + + + @Override + public void enter(StateType type, Bundle args) { + if (isDead()) { + return; + } + __BaseState baseState = stateMap.get(type); + if (baseState != null) { + this.currentStateType = type; + runOnUI(() -> baseState.enter(args)); + } + } + + @Override + public void enter(StateType type) { + enter(type, null); + } + + void runOnUI(Runnable action) { + if (iuiRunner != null) { + iuiRunner.runOnUI(action); + } + } + + public void doSurveyor() { + boolean inValidate = isInValidate(); + + if (inValidate) { + return; + } + + int pointCount = cachedData.pointCount(); + if (pointCount == 0) { + ToastUtils.showShort(Tools.getString(R.string.no_data_available_yet)); + return; + } + + Bundle bundle = null; + if (isRotationReadyState()) { + //当前是旋转到位状态 + bundle = new Bundle(); + bundle.putBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE, true); + } + + enter(StateType.doSurveyor, bundle); + } + + public void doAutoSurveyor() { + if (isInValidate()) { + return; + } + enter(StateType.doAutoSurveyor); + } + + public void deleteCurrentStationSurveyorData() { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteAllCycle, _DoDeleteAllCycleState.args(stationId())); + } + + /** + * 删除当前测回记录(删除后视或前视的所有记录) + * + * @param cycleIndex + */ + public void deleteCurrentStationSurveyorData(int positionFragment) { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteCurrentCycle, _DoDeleteCurrentCycleState.args(stationId(), positionFragment)); + } + + public void stationCheck() { + if (isInValidate()) { + return; + } + enter(StateType.checkStation); + } + + public String stationCheckOnly() { + return _CheckStationState._stationCheck(stationId(), toleranceRecord, cachedData); + } + + public void stationAdjustOnly(String showType) { + ThreadPoolUtil.execute(() -> { + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (adjustResult.isError()) { + runOnUI(() -> TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, adjustResult.errorString)); + return; + } + + ArrayList adjustList = new ArrayList<>(); + if (adjustResult.result != null && !adjustResult.result.isEmpty()) { + adjustList.add(adjustResult.result.get(0)); + } + StationDataAdjustDialogFragment.showDialog(showType, adjustList, adjustResult.showSlopDistance, fragmentManager()); + + //伴随平差 设置进度为通过检测 + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + __BaseState.getScheduleKey(positionFragment), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED)); + }); + + } + + + public void stationAdjust(String type) { + if (isInValidate()) { + return; + } + Bundle bundle = new Bundle(); + bundle.putString(StationDataAdjustDialogFragment.KEY_SHOW_TYPE, type); + enter(StateType.doCalAdjust, bundle); + } + + public void switch2Cycle(int cycleIndex) { + if (isInValidate()) { + } +// _DoCalScheduleInSingleCycleState.enter(this, cycleIndex); + } + + public void calScheduleWhenEnterSurveyFragment(int cycleIndex) { + if (isInValidate()) { + return; + } + _Init.enter(this, cycleIndex); + } + + public void moveBack() { + if (isInValidate()) { + return; + } + enter(StateType.doMoveBack); + } + + //检测当前状态是否支持从外界主动改变状态 + //如果是空闲或者是测站通过检测是有效的状态 + public boolean isInValidate() { + return currentStateType != StateType.idle + && StateType.stationCheckedSuccess != currentStateType + && !isRotationReadyState(); + } + + private boolean isRotationReadyState() { + return currentStateType == StateType.doWellMeasureRotationReady; + } + + public void quite() { + _live = false; + for (Map.Entry entry : stateMap.entrySet()) { + entry.getValue().quite(); + } + //进入idle状态 + this.currentStateType = StateType.idle; + } + + private boolean _live = true; + + public boolean isDead() { + return !_live; + } + + public void resume() { + _live = true; + for (Map.Entry entry : stateMap.entrySet()) { + entry.getValue().resume(); + } + } + + FragmentManager fragmentManager() { + return this.fragmentManager; + } + + LifecycleOwner lifecycleOwner() { + return this.lifecycleOwner; + } + + final boolean isStationAutoClosed() { + return stationRecord.isAutoClose(); + } + + @WorkerThread + public static StateManagerHeightTraverse newInstance( + int positionFragment, + boolean isSupportAutoMode, + @NonNull RequestSurveyorParamAuto requestSurveyorParamAuto, + @NonNull SurveyorStationRecord stationRecord, + @NonNull Context context, + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull ToleranceDetailRecord toleranceRecord, + @NonNull ISurveyorData surveyorData, + @NonNull ICycleRecorder cycleRecorder, + @NonNull ICachedData cachedData, + IScrollDelegate scrollDelegate, + IUIRunner runner) { + //读取测点record + String stationPointId = null; + if (stationRecord.getItems() != null) { + for (SurveyorPoint stationItem : stationRecord.getItems()) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + stationPointId = stationItem.getPointId(); + break; + } + } + } + PointRecord stationPointRecord = null; + if (stationPointId != null) { + stationPointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationPointId); + } + if (stationPointRecord == null) { + return null; + } + boolean supportAuto = Test.DEBUG; + if (isSupportAutoMode && + (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProLevel())) { + supportAuto = true; + } + return new StateManagerHeightTraverse( + positionFragment, + supportAuto, + requestSurveyorParamAuto, + stationRecord, + stationPointRecord, + toleranceRecord, + context, + surveyorData, + cycleRecorder, + cachedData, + scrollDelegate, + fragmentManager, lifecycleOwner, runner); + } + + @Override + public boolean isAutoModeOpen() { + return autoMode == AutoModeType.start; + } + + @Override + public boolean isAutoModeClose() { + return autoMode == AutoModeType.stop; + } + + @Override + public boolean isAutoModeNotSpecial() { + return autoMode == AutoModeType.unknown; + } + + @Override + public void openAutoMode() { + autoMode = AutoModeType.start; + } + + @Override + public void closeAutoMode() { + autoMode = AutoModeType.stop; + } + + @Override + public void resetAutoMode() { + autoMode = AutoModeType.unknown; + } + + + @Override + public int isReadyAutoSurvey() { + if (!supportAutoSurvey) { + return ControlSurveyResult.CODE_ERROR; + } + if (!surveyor.isReady()) {//仪器连接上才算ready + return ControlSurveyResult.CODE_ERROR; + } + + Coordinate stationBasePoint = getStationCoord(); + double instrumentHeight = getInsturmentHeight(); + + return requestSurveyorParamAuto.checkAutoCondition(getCachedData(), stationBasePoint, instrumentHeight); + } + + @Override + public String isMeasuredValueMatchDesign() { + if (!supportAutoSurvey) { + return null; + } + Coordinate stationBasePoint = getStationCoord(); + double instrumentHeight = getInsturmentHeight(); + List originMeasureList = requestSurveyorParamAuto.getOriginMeasureList(getCachedData()); + return AutoSurveyorMethod.checkAutoSurveyorMeasuredValue(stationBasePoint, instrumentHeight, originMeasureList); + } + + @Override + public boolean isSurveying() { + return currentStateType == StateType.doSurveyor || currentStateType == StateType.doAutoSurveyor; + } + + @Override + public boolean isAutoSurveying() { + return isAutoModeOpen(); + } + + + @NonNull + public ICachedData getCachedData() { + return cachedData; + } + + /** + * 获取当前测回 + * + * @return + */ + public int getCurrentCycle() { + return cycleRecorder.currentCycleIndex(); + } + + public int getCurrentIndex() { + return surveyorData.currentIndex(); + } + + private Coordinate getStationCoord() { + if (PointRecord.TYPE_KNOWN_POINT.equals(stationPointRecord.getPointType())) { + return new Coordinate( + stationPointRecord.getX(), + stationPointRecord.getY(), + stationPointRecord.getZ()); + } + return null; + } + + public double getInsturmentHeight() { + return DigitalUtil.valueOfDoubleString(stationRecord.getInstrumentHeight(), 0); + } + + @NonNull + public RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return requestSurveyorParamAuto; + } + + public void refreshGoBackBtnEnable() { + FindTargetMethod.Target deleteTartget = _DoMove2NextValidateState.findTarget(stationId(), cachedData.pointCount(), cachedData, + surveyorData.currentIndex(), false, + dataCategory -> !dataCategory.isEmptyData()); + EventBus.getDefault().post(new RefreshGoBackButton(deleteTartget != null)); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckStationState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckStationState.java new file mode 100644 index 0000000..8b2ae0d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckStationState.java @@ -0,0 +1,343 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +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.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.SelectReSurveyorCycleFragment; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * 执行「测站检测」 + *

+ * 前置条件: + * 所有测回都完成测量,并且通过「测回内检测」 + */ +class _CheckStationState extends __BaseState { + + public _CheckStationState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.checkStation, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + //执行测站检测 + String error = _stationCheck(stationId(), getToleranceRecord(), getCachedData()); + if (error.isEmpty()) { + //进入finish状态 + navigation2(StateType.stationCheckedSuccess); + } else { + showErrorTips(error, stationId(), getToleranceRecord().getCycleCount(), + getCachedData(), + this, + fragmentManager(), + lifecycleOwner()); + } + } + + /** + * 提示错误信息,并让用户选择下一步操作 + */ + public static void showErrorTips(String msg, String stationId, int cycleCount, + ICachedData stationSurveyorDataSource, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + state.optionTips(msg, + Tools.getString(R.string.retest_cycle), + Tools.getString(R.string.retest_station), + () -> state.runOnBackground(() -> reSurveyorCycle(stationId, cycleCount, + stationSurveyorDataSource, + state, fragmentManager, lifecycleOwner)), + () -> reSurveyorStation(msg, stationId, cycleCount, + stationSurveyorDataSource, + state, fragmentManager, lifecycleOwner), + () -> state.enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + + @WorkerThread + private static void reSurveyorCycle(String stationId, int cycleCount, + ICachedData cachedData, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + SurveyorStationRecord stationRecord = SurveyorDatabaseFactory.instance.getSurveyorStation().getRecordSync(stationId); + if (stationRecord == null) { + state.enterIdleAndClearSurveyStateAndResetAutoMode(true); + return; + } + state.runOnUI(() -> SelectReSurveyorCycleFragment.start( + fragmentManager, + lifecycleOwner, + cycleCount, + (cycleIndex) -> { + if (cycleIndex == -1) { + state.enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + //记录补测数据类型 + List pointIds = new ArrayList<>(); + pointIds.add(cachedData.pointId(cycleIndex, cycleIndex)); + cachedData.markReSurveyor(stationId, cycleIndex, pointIds); + //更新测量状态 + state.setCurrentCycle(cycleIndex); + state.setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + state.setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + //查找新测量目标 + state.findTargetFromBeginInCurrentCycle(true, cycleIndex); + } + } + )); + } + + static void reSurveyorStation(String msg, String stationId, int cycleCount, + ICachedData cachedData, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + state.optionTips(Tools.getString(R.string.is_delete_all_station_data), null, null, + () -> {//1.选择删除测站所有数据,则执行相应逻辑 + ThreadPoolUtil.execute(() -> { + //删除数据 + cachedData.deleteSurveyorRecord(stationId); + //更新测量进度 + state.setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + for (int index = 0; index < cycleCount; index++) { + state.setSingleCycleSchedule(index, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + + state.resetLearnDataTag(); + + //重新测量 + state.findTargetFromBeginInCurrentCycle(true, 0); + }); + }, + () -> {//2.如果用户不选择删除,则循环提示,让他重新在重测和删除做选择 + //循环显示 + showErrorTips(msg, stationId, cycleCount, + cachedData, state, + fragmentManager, lifecycleOwner); + }, + () -> 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 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 < 1; index++) { + double 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 < 1; 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(verCyclesAngleDifference, verCyclesIDifference, distCyclesDifference, + verValueError, verIError, distError); + } + + /** + * 根据超限信息生成错误描述 + * + * @param verValueError 垂直角同方向值互差 + */ + private static String _errorString(double verLimit, double verILimit, double distLimit + , List<_ErrorItem> verValueError, List<_ErrorItem> verIError, List<_ErrorItem> distError) { + StringBuilder stringBuilder = new StringBuilder(); + 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/heighttraverse/_CheckToleranceState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckToleranceState.java new file mode 100644 index 0000000..96dd47b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckToleranceState.java @@ -0,0 +1,313 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; +import android.text.TextUtils; + +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.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.SurveyorRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.data.SpeakCache; +import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod; +import com.bingce.controlapphelper.surveyor.method.SingleCycleCheckMethod; +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.surveyor.state.AutoModeType; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 检测限差 + */ +public class _CheckToleranceState extends __BaseState { + + public _CheckToleranceState(int positionFragment, + StateManagerHeightTraverse stateManager) { + super(StateType.checkTolerance, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + //检测读数 + if (!checkReadData()) { + return; + } + + ICachedData cacheData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + + + //设置数据正常 + surveyorData.setDataCategory(DataCategory.normalCategory()); + //存储(缓存+数据库) + cacheData.cache(getCurrentCycleIndex(), surveyorData); + + if (isSingleCycleCompleted(stationId(), getCurrentCycleIndex(), cacheData)) { + refreshUI(); + //更新测回测量进度 + setSingleCycleSchedule(getCurrentCycleIndex(), SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + boolean singleSuccess = checkSingleCycle(); + if (singleSuccess) { + checkAllCycle(); + } + } else { + findNextSurveyorPoint(); + } + + } + + private void checkAllCycle() { + int cycleCount = getToleranceRecord().getCycleCount(); + int nextCycleIndex = -1; + //查找数据不全的测回 + for (int cycleIndex = 0; cycleIndex < cycleCount; cycleIndex++) { + if (!getCachedData().isSingleCycleAllDataValidate(cycleIndex)) { + //对不全数据的测回赋值 + nextCycleIndex = cycleIndex; + break; + } + } + + if (nextCycleIndex != -1) { + //有其他测回数据没有测完 + if (isAutoSurveyOpen()) { + //修改当前测回 + setCurrentCycle(nextCycleIndex); + //存储一下已经播放切换测回的的节点 + SpeakCache.getInstance().saveSpeakSwitchCycle(); + //播报 + TtsManager.getInstance().speak(Tools.getString(R.string.current_cycle_complete_start_surveyor) + SurveyorCycleUtil.cycleName(nextCycleIndex)); + //查找测量目标 + findNextSurveyorPoint(); + } else { +// //提示是否进入其他未完成测回继续测量 +// option4Jump2OtherEmptyCycle(nextCycleIndex); + //查找测量目标 + findNextSurveyorPoint(); + } + return; + } + + if (isAutoSurveyOpen()) { + //检测是否已经提示 + //检测是否需要提示测站检测 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + ThreadPoolUtil.execute(() -> { + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId(); + ConfigRecord record = configDataSource.getByKeySync(key); + if (record == null || ConfigConstants.VALUE_NO.equals(record.getConfigValue())) { + runOnUI(() -> TtsManager.getInstance().speak(Tools.getString(R.string.all_cycle_completed))); + } + }); + } + //标识测站完成测量(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //进入idle状态 + //清除测量状态,进入测站检测,停止自动测量 + setAutoAndSurveyorState(AutoModeType.unknown, false); + + String error = _CheckStationState._stationCheck(stationId(), getToleranceRecord(), getCachedData()); + if (error.isEmpty()) { + //进入finish状态 + ISurveyorData surveyorData = getSurveyorData(); + surveyorData.clearSurveyStateAndPosition(); + //设置测量进度(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + //通知刷新 + tips(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked), null); + if (isAutoSurveyOpen()) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked))); + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + _CheckStationState.showErrorTips(error, stationId(), getToleranceRecord().getCycleCount(), + getCachedData(), + this, + fragmentManager(), + lifecycleOwner()); + } + + } + + private boolean checkSingleCycle() { + ICachedData cachedData = getCachedData(); + String stationId = stationId(); + ISurveyorData surveyorData = getSurveyorData(); + int currentCycleIndex = surveyorData.currentIndex(); + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + int cycleCount = toleranceRecord.cycleCount; + + //预处理 + for (int index = 0; index < cachedData.pointCount(); index++) { + String pointId = cachedData.pointId(currentCycleIndex, index); + String keyLeft = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + SurveyorRecord left = cachedData.getSurveyorRecord(keyLeft); + _changeDirtyRecord2NormalBeforeCheck(left, cachedData); + String keyRight = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.right); + SurveyorRecord right = cachedData.getSurveyorRecord(keyRight); + _changeDirtyRecord2NormalBeforeCheck(right, cachedData); + } + + //执行单测回内检测 + String error = SingleCycleCheckMethod.checkVerI( + toleranceRecord.getVerCycleDirectIDifference(), + stationId(), currentCycleIndex, surveyorData, cachedData); + if (error != null) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.check_cycle_inner_failed)); + } + _CheckStationState.showErrorTips(error, stationId(), cycleCount, cachedData, this, fragmentManager(), lifecycleOwner()); + return false; + } + + //更新测量进度 + setSingleCycleSchedule(currentCycleIndex, + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + return true; + } + + private void _changeDirtyRecord2NormalBeforeCheck( + SurveyorRecord record, ICachedData cachedDataSource) { + if (record == null) { + return; + } + if (record.value1Status.isResurveyed() || record.value2Status.isResurveyed()) { + if (record.value1Status.isResurveyed()) { + record.value1Status = DataCategory.normalCategory(); + } + if (record.value2Status.isResurveyed()) { + record.value2Status = DataCategory.normalCategory(); + } + + cachedDataSource.updateCache(record); + } + } + + private boolean checkReadData() { + int surveyorCount = getToleranceRecord().getSurveyorCount(); + if (surveyorCount > 1) {//单次测量,直接通过检测 + //多次测量,执行检测 + ISurveyorData surveyorDataSource = getSurveyorData(); + double horDifference = getToleranceRecord().getHorReadDifference(); + double verDifference = getToleranceRecord().getVerReadDifference(); + double distanceDifference = getToleranceRecord().getSlopeReadDifference(); + double horDiffRadian = DeviationValueOfRadianMethod.similarRadianDiff(surveyorDataSource.getAngleHor1(), surveyorDataSource.getAngleHor2()); + double verDiffRadian = DeviationValueOfRadianMethod.similarRadianDiff(surveyorDataSource.getAngleVer1(), surveyorDataSource.getAngleVer2()); + + String msg = null; +// if (verDifference < RadianMethod.radian2S(verDiffRadian)) { +// msg = "垂直角读数超限,请重新观测该目标."; +// } else + if (!isAloneDistance()//增加单独测距判断 + && distanceDifference < distanceReadDiff(surveyorDataSource.getDistance1(), surveyorDataSource.getDistance2())) { + msg = Tools.getString(R.string.distance_read_data_limit); + } + + if (!TextUtils.isEmpty(msg)) { + failureTipsWithAutoStandStill(msg); + return false; + } + } + + return checkLeft(); + } + + /** + * 如果是测回内首次测量,需要判断是否是盘左 + */ + private boolean checkLeft() { + LeftOrRight leftOrRight = getSurveyorData().leftOrRight(); + if (leftOrRight == LeftOrRight.left) { + //如果是首次测量,强制要求使用盘左 + double vAngle = getSurveyorData().getAngleVer(); + if (!isFaceLeft(vAngle)) { + failureTipsWithAutoStandStill( + getContext().getString(R.string.error_tips_please_start_from_left), + () -> { + TotalStation.getInstance().requestChangeFace(); + }); + return false; + } + } + return true; + } + + /** + * 是否是盘左 + * + * @param vAngle + * @return + */ + private boolean isFaceLeft(double vAngle) { + return vAngle >= 0 && vAngle <= Math.PI; + } + + /** + * 斜距两次读数差 + * + * @param distance1 读数1 + * @param distance2 读数2 + * @return 读数差(单位毫米) + */ + public double distanceReadDiff(double distance1, double distance2) { + return Math.abs(distance1 - distance2) * 1000; + } + + /** + * 判断单个测回是否测量完成(不要求通过检测) + */ + public static boolean isSingleCycleCompleted(String stationId, int cycleIndex, ICachedData cachedData) { + if (cachedData.pointCount() == 0) { + return false; + } + if (cycleIndex == -1) { + cycleIndex = 0; + } + + boolean isCompleted = true; + + //测回内所有数据都是「新鲜数据」才能执行「测回内检测」 + for (int index = 0; index < cachedData.pointCountReal(); index++) { + + if (cachedData.isPointAbandon(cycleIndex, index)) { + continue; + } + + String pointId = cachedData.pointId(cycleIndex, index); + + String leftKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.left); + String rightKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.right); + + DataCategory leftDataCategory = cachedData.valueState(leftKey); + DataCategory rightDataCategory = cachedData.valueState(rightKey); + + if (leftDataCategory.isFreshData() && rightDataCategory.isFreshData()) { + continue; + } + isCompleted = false; + break; + } + + return isCompleted; + } + + private void findNextSurveyorPoint() { + findTargetFromBeginInCurrentCycle(false, 0); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoAutoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoAutoSurveyorState.java new file mode 100644 index 0000000..4e366b2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoAutoSurveyorState.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoAutoSurveyorState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoAutoSurveyorState(int positionFragment, StateManagerHeightTraverse stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doAutoSurveyor, positionFragment, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + if (autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS) { + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doMove2NextValidate); + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoCalAdjustState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoCalAdjustState.java new file mode 100644 index 0000000..da5f28c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoCalAdjustState.java @@ -0,0 +1,45 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; + +/** + * 平差计算 + */ +public class _DoCalAdjustState extends __BaseState { + + public _DoCalAdjustState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doCalAdjust, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + String showType = null; + if (args != null) { + showType = args.getString(StationDataAdjustDialogFragment.KEY_SHOW_TYPE); + } + startCalAdjust(showType); + } + + private void startCalAdjust(String showType) { + runOnBackground(() -> { + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(getStation(), getCachedData()); + if (adjustResult.isError()) { + runOnUI(() -> _CheckStationState.showErrorTips(adjustResult.errorString, stationId(), getToleranceRecord().getCycleCount(), + getCachedData(), + _DoCalAdjustState.this, + fragmentManager(), + lifecycleOwner())); + return; + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + + StationDataAdjustDialogFragment.showDialog(showType, adjustResult.result, adjustResult.showSlopDistance, fragmentManager()); + } + ); + } +} 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 new file mode 100644 index 0000000..af296b3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteAllCycleState.java @@ -0,0 +1,73 @@ +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; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.utils.ThreadPoolUtil; + +/* + * 删除本测站所有测回数据 + * */ +class _DoDeleteAllCycleState extends __BaseState { + + private static final String KEY_STATION_ID = "__station_id"; + + static Bundle args(String stationId) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + return args; + } + + public _DoDeleteAllCycleState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doDeleteAllCycle, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + String stationId = args.getString(KEY_STATION_ID); + + ThreadPoolUtil.execute(() -> deleteAllCycleData(stationId)); +// optionTipsWithStandStill(getContext().getString(R.string.tips_delete_station_all_surveyor_records), +// () -> deleteAllCycleData(stationId)); + } + + @WorkerThread + private void deleteAllCycleData(String stationId) { + //删除数据 + 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 new file mode 100644 index 0000000..559c32b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteCurrentCycleState.java @@ -0,0 +1,106 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +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.state.StateType; +import com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse.MeasureHeightTraverseFragment; +import com.bingce.utils.ThreadPoolUtil; + +class _DoDeleteCurrentCycleState extends __BaseState { + + private static final String KEY_STATION_ID = "__station_id"; + 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_POSITION_FRAGMENT_INDEX, periodIndex); + return args; + } + + public _DoDeleteCurrentCycleState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doDeleteCurrentCycle, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + String stationId = args.getString(KEY_STATION_ID); + 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 positionFragment) { + ThreadPoolUtil.execute(() -> { + ICachedData cachedData = getCachedData(); + + int cycleCount = getToleranceRecord().cycleCount; + + 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); + //设置当前测回 + 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/_DoMove2NextValidateState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMove2NextValidateState.java new file mode 100644 index 0000000..c476e4e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMove2NextValidateState.java @@ -0,0 +1,122 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.DataCategory; +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.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 移动到一个待测量位置 + *

+ * 不会跳转到其他测期 + *

+ * 可能涉及转向(盘左->盘右) + */ +class _DoMove2NextValidateState extends __BaseState { + + public _DoMove2NextValidateState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doMove2NextValidate, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cachedData = getCachedData(); + + int pointCount = cachedData.pointCount(); + + int cycle = 0; + if (args != null) { + cycle = args.getInt(BundleConstants.KEY_CYCLE_INDEX, 0); + } + + //1.先查找补测数据 + FindTargetMethod.Target surveyorTarget = findTarget(stationId(), pointCount, cachedData, cycle, true, + dataCategory -> DataCategory.dirtyAndNeedReSurveyor == dataCategory); + + + //如果在当前测回找到待被测数据,立刻跳转到相应位置 + if (surveyorTarget != null) { + lookTargetAfter(surveyorTarget.itemIndex, surveyorTarget.leftOrRight); + return; + } + //2.查找empty数据 + FindTargetMethod.Target emptyTarget = findTarget(stationId(), pointCount, cachedData, cycle, true, + dataCategory -> DataCategory.empty == dataCategory); + + if (emptyTarget != null) { + if (isAutoSurveyOpen()) { + if (emptyTarget.itemIndex == getCachedData().pointCount() - 1 + && emptyTarget.leftOrRight == LeftOrRight.right) { + TtsManager.getInstance().speak(Tools.getString(R.string.start_face_right)); + } + } + //直接跳转到目标点,开启新测量 + lookTargetAfter(emptyTarget.itemIndex, emptyTarget.leftOrRight); + return; + } + + enterIdleAndClearSurveyorStatePosition(); + + } + + public static FindTargetMethod.Target findTarget(final String stationId, + final int pointCount, + final @NonNull ICachedData cachedData, + int startLookPosition, + boolean isAscLook, + ILookCase lookCase) { + if (isAscLook) { + for (int i = startLookPosition; i < pointCount; i++) { + FindTargetMethod.Target targetAscOrDesc = getTargetAscOrDesc(stationId, i, cachedData, true, lookCase); + if (targetAscOrDesc != null) { + return targetAscOrDesc; + } + } + } else { + for (int j = startLookPosition; j >= 0; j--) { + FindTargetMethod.Target targetAscOrDesc = getTargetAscOrDesc(stationId, j, cachedData, false, lookCase); + if (targetAscOrDesc != null) { + return targetAscOrDesc; + } + } + } + return null; + } + + public static FindTargetMethod.Target getTargetAscOrDesc(String stationId, int pointIndex, ICachedData cachedData, boolean isAscLook, ILookCase lookCase) { + FindTargetMethod.Target target; + if (isAscLook) { + target = getTarget(stationId, pointIndex, cachedData, LeftOrRight.left, lookCase); + if (target != null) return target; + target = getTarget(stationId, pointIndex, cachedData, LeftOrRight.right, lookCase); + } else { + target = getTarget(stationId, pointIndex, cachedData, LeftOrRight.right, lookCase); + if (target != null) return target; + target = getTarget(stationId, pointIndex, cachedData, LeftOrRight.left, lookCase); + } + return target; + } + + private static FindTargetMethod.Target getTarget(String stationId, int pointIndex, ICachedData cachedData, LeftOrRight leftOrRight, ILookCase lookCase) { + String pointId = cachedData.pointId(pointIndex, pointIndex); + String leftKey = IdUtil.createSurveyorRecordId(stationId, pointIndex, pointId, leftOrRight); + DataCategory dataCategory = cachedData.valueState(leftKey); + if (lookCase.whichCase(dataCategory)) { + return new FindTargetMethod.Target(pointIndex, pointIndex, leftOrRight); + } + return null; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMoveBackState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMoveBackState.java new file mode 100644 index 0000000..fdec5ca --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMoveBackState.java @@ -0,0 +1,161 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.SurveyorRecord; +import com.bingce.controlapphelper.model.DataCategory; +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.controlapphelper.util.IdUtil; + +import com.bingce.controlnetwork.R; + +/** + * 回退 + * 移动到上一测量结点,伴随删除上次测量数据 + */ +public class _DoMoveBackState extends __BaseState { + + public _DoMoveBackState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doMoveBack, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cachedData = getCachedData(); + + final int pointCount = cachedData.pointCount(); + +// if (currentIndex < 0) { +// //如果测量结束,直接使用0号点盘右 +// int targetIndex = 0; +// LeftOrRight targetState = LeftOrRight.right; +// warningWithStandStill(cachedDataSource, currentCycle, targetIndex, targetState); +// return; +// } + + FindTargetMethod.Target deleteTartget = _DoMove2NextValidateState.findTarget(stationId(), pointCount, cachedData, + getCurrentIndex(), false, dataCategory -> !dataCategory.isEmptyData()); + + if (deleteTartget == null) { + goIdle(); + return; + } + + cachedData.deleteSurveyorRecord(stationId(), deleteTartget.itemIndex, deleteTartget.itemIndex, deleteTartget.leftOrRight); + + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + + //直接跳转到目标点,开启新测量 + //更新测量进度 + setSurveyPosition(deleteTartget.itemIndex, deleteTartget.leftOrRight); + //清除测量状态,进入idle,但是不停止自动测量 + goIdle(); + //滚动 + scroll2(deleteTartget.itemIndex); + + +// if (dataCategory.isNeedResurvey()) {//如果当前位置是脏数据(说明正在补测) +// //回退到上一个脏数据位置 +// back2LastDirtyPosition(currentCycle, currentIndex, leftOrRight, pointCount, cachedDataSource); +// } else if (dataCategory.isEmptyData()) { +// //如果是空数据,说明测量进行中,查找上一个数据即可 +// //需要提醒用户数据会被删除 +// back2LastVisiblePosition(currentCycle, currentIndex, leftOrRight, pointCount, cachedDataSource); +// } else { +// //bug,不应该有这个地方 +// enterIdleAndClearSurveyStateAndResetAutoMode(true); +// } + } + + private void goIdle() { + enterIdleAndClearSurveyStateAndResetAutoMode(false); + } + + private void back2LastDirtyPosition(int currentCycle, int currentIndex, LeftOrRight leftOrRight, + int pointCount, ICachedData cachedData) { + //反向查找,但是找到目标后不能删除其数据,否则会造成「数据空洞」 + FindTargetMethod.Target target = FindTargetMethod.findTargetInSingleCycle( + stationId(), currentCycle, currentIndex, leftOrRight, pointCount, false, + DataCategory.dirtyAndSurveyed, + cachedData); + if (target == null) { + //在dirtyAndNeedReSurveyor数据没有修复完成之前,不能回退正常数据 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + //找到dirtyAndSurveyed数据, + //则将其校正为dirtyAndNeedReSurveyor + String pointId = cachedData.pointId(target.cycleIndex, target.itemIndex); + String recordKey = IdUtil.createSurveyorRecordId(stationId(), target.cycleIndex, pointId, target.leftOrRight); + SurveyorRecord surveyorRecord = cachedData.getSurveyorRecord(recordKey); + if (surveyorRecord != null) { + if (surveyorRecord.value1Status.isResurveyed()) { + surveyorRecord.value1Status = DataCategory.needResurvey(); + } + if (surveyorRecord.value2Status.isResurveyed()) { + surveyorRecord.value2Status = DataCategory.needResurvey(); + } + cachedData.updateCache(surveyorRecord); + //重置进度 + resetSchedule(_DoMoveBackState.this, + target.itemIndex, + target.leftOrRight); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + } + } + + private void back2LastVisiblePosition(int currentCycle, int currentIndex, LeftOrRight leftOrRight, + int pointCount, + ICachedData cachedData) { + + //从当前开始,向上查找第一个normal数据 + FindTargetMethod.Target target = + FindTargetMethod.findTargetInSingleCycle( + stationId(), currentCycle, currentIndex, leftOrRight, pointCount, false, + DataCategory.normalCategory(), + cachedData); + if (target == null) { + failureTipsWithAutoStandStill(getContext().getString(R.string.tips_no_more_record_2_rollback)); + return; + } + + warningWithStandStill(cachedData, + currentCycle, + target.itemIndex, + target.leftOrRight); + } + + private void warningWithStandStill( + ICachedData cachedDataSource, + int currentCycle, int itemIndex, LeftOrRight leftOrRight) { + optionTipsWithStandStill(getContext().getString(R.string.tips_will_resurvey_last_record), + () -> { + //删除当前数据 + cachedDataSource.deleteSurveyorRecord(stationId(), + currentCycle, itemIndex, leftOrRight); + //重置进度 + setSingleCycleSchedule(currentCycle, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + resetSchedule(this, itemIndex, leftOrRight); + }); + } + + private static void resetSchedule(__BaseState state, + int targetIndex, + LeftOrRight leftOrRight) { + //设置测量目标点 + state.setSurveyPosition(targetIndex, leftOrRight); + //清除测量状态,进入idle + //如果当前已经关闭自动测量,就不重置自动测量开关(用户已经表示不想自动测量) + state.enterIdleAndClearSurveyStateAndResetAutoMode(!state.isAutoSurveyClosed()); + + state.scroll2(targetIndex); + } +} 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 new file mode 100644 index 0000000..0f1deee --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoSurveyorState.java @@ -0,0 +1,245 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.SurveyStateEvent; +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.state.ISurveyState; +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; +import com.bingce.device.Device; +import com.bingce.totalstation.TotalStation; +import com.bingce.totalstation.protocol.south.SouthAndroidBtInterface; +import com.bingce.totalstation.protocol.topcon.TopconInterface; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import blankj.utilcode.util.ToastUtils; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoSurveyorState extends __BaseState implements ISurveyorListener, ISurveyorRemindListener { + private final ISurveyState surveyState; + //最多测量次数,如果3次测量都没有获取正常数据,则跳过 + private static final int MAX_SURVEYOR_COUNT = 3; + private static int failureCount = 0; + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_EXCEED_MAX = 1;//测量失败次数超出最大限制 + private static final int RESULT_FAILURE_ERROR = 2;//测量失败,又没有允许重复尝试 + private static final boolean allowTryWhenFailure = true;//在测量失败的时候,是否允许重新测量 + + private int measureTimeIndex = 0;//当前测点是第几次测量 + private boolean isAlreadyRemindUserAimingAtWire = false; + + private final Handler handler; + + public _DoSurveyorState(int positionFragment, StateManagerHeightTraverse stateManager, ISurveyState surveyState) { + super(StateType.doSurveyor, positionFragment, stateManager); + this.surveyState = surveyState; + handler = new Handler(Looper.getMainLooper()); + } + + @Override + public void enter(Bundle args) { + measureTimeIndex = 0; + + isAlreadyRemindUserAimingAtWire = false; + if (args != null) { + isAlreadyRemindUserAimingAtWire = args.getBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE); + } + + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + ICachedData cachedDataSource = getCachedData(); + + //3.其他测回没有正在测量数据,则在当前测回执行测量 + doSurveyor(); + } + + private void doSurveyor() { + failureCount = 0; + //判断设备是否连接 + if (surveyorImpl().isReady()) { + //发送测量信号 + SurveyStateEvent.postSurveying(positionFragment); + //注册接收测量数据 + surveyorImpl().prepareSurveyor(); + sendSurveyRequest(); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + Device.getInstance().remindConnectDevice(); + } + } + + + @Override + public void onReceive(double originalHa, double originalVa, double sd, double clockwiseHa, double topVa, double hd, double vd) { + //重置错误读数 + failureCount = 0; + if (getSurveyorData().onSurveyor(originalHa, originalVa, sd, hd)) { + //测量数据成功,可以退出测量状态 + onSuccess(); + } else {//测量数据不完全,需要继续测量 + measureTimeIndex = 1;//更新测量索引 + refreshUI(); + + if (TotalStation.getInstance() instanceof TopconInterface) { + //这个仪器需要延迟500毫秒发送指令 + handler.postDelayed(this::sendSurveyRequest, 500); + } else if (TotalStation.getInstance() instanceof SouthAndroidBtInterface) { + handler.postDelayed(this::sendSurveyRequest, 100); + } else { + sendSurveyRequest(); + } + } + } + + @Override + public void onError(String errorMsg) { + TtsManager.getInstance().speak(errorMsg); + if (allowTryWhenFailure) {//允许重新测量 + if (!isLive()) { + return; + } + //测量出现异常,需要处理 + failureCount++; + if (failureCount >= MAX_SURVEYOR_COUNT) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.many_measure_failed)); + } + 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)); + } + } else { + onCompleted(RESULT_FAILURE_ERROR, errorMsg); + } + } + + private void sendSurveyRequest() { + int currentIndex = getCurrentIndex(); + if (currentIndex < 0) { + currentIndex = 0; + } + + SurveyorPoint surveyorPoint = getCachedData().getSurveyorPoint(getCycleRecorder().currentCycleIndex(), currentIndex); + ISurveyorData surveyorData = getSurveyorData(); + + surveyorImpl().requestSurveyor(new RequestSurveyorParam(getRequestSurveyorParamAuto(), getInstrumentHeight(), surveyorPoint, measureTimeIndex, + surveyorData.currentIndex(), surveyorData.leftOrRight(), isAlreadyRemindUserAimingAtWire)); + } + + private void onSuccess() { + onCompleted(RESULT_SUCCESS, ""); + } + + private void onCompleted(int result, String msg) { + //退出测量 + surveyorImpl().exitSurveyor(); + switch (result) { + case RESULT_SUCCESS://进入读数检测状态 + //检测是否处于「自动测量」 + if (!surveyState.isAutoSurveying()) { + SurveyStateEvent.postSuccess(positionFragment); + } + navigation2(StateType.checkTolerance); + break; + case RESULT_FAILURE_EXCEED_MAX: +// if (SettingValueUtil.isAbandonPoint() && isAllowAbandonForVarifyIndex()) { +// dealErrorDataSkip(msg); +// } else { +// dealErrorDataNormal(msg); +// } + dealErrorDataNormal(msg); + break; + case RESULT_FAILURE_ERROR: + dealErrorDataNormal(msg); + break; + default: + throw new RuntimeException("un reached state -- surveyor"); + } + } + + @Override + protected void quite() { + super.quite(); + surveyorImpl().exitSurveyor(); + } + + @Override + protected void resume() { + getSurveyorData().clearSurveyState(); + } + + @Override + public void remindUserAimingAtWire() { + //退出测量 + surveyorImpl().exitSurveyor(); + navigation2(StateType.doWellMeasureRotationReady); + } + + private void dealErrorDataNormal(String msg) { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg); + navigation2(StateType.SurveyorFailure, args); + } + + private void dealErrorDataNormal(String msg, boolean isShowDialog) { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg, isShowDialog); + navigation2(StateType.SurveyorFailure, args); + } + + private void dealErrorDataSkip(String msg) { + optionTipsCountDown(msg + Tools.getString(R.string.is_it_abandoned), + Tools.getString(R.string.switch_abandon), + Tools.getString(R.string.ignore), + () -> { + changeSkip(getCycleRecorder().currentCycleIndex(), getCurrentIndex()); + navigation2(StateType.isSingleCycleCompleted); + }, + () -> dealErrorDataNormal(msg, false), + () -> dealErrorDataNormal(msg, false)); + } + + /** + * 针对第一个点和闭合是否废弃验证 + * + * @return + */ + private boolean isAllowAbandonForVarifyIndex() { + boolean autoClose = getStation().isAutoClose(); + int pointCount = getCachedData().pointCount(); + boolean abandon = true; + int currentIndex = getCurrentIndex(); + if (autoClose) { + if (currentIndex == 0 || currentIndex == pointCount - 1) { + abandon = false; + } + } else { + if (currentIndex == 0) { + abandon = false; + } + } + return abandon; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoWellMeasureRotationReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoWellMeasureRotationReadyState.java new file mode 100644 index 0000000..0a98059 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoWellMeasureRotationReadyState.java @@ -0,0 +1,30 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +/** + * 钢丝测量旋转到位状态 + */ +class _DoWellMeasureRotationReadyState extends __BaseState { + + public _DoWellMeasureRotationReadyState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doWellMeasureRotationReady, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.please_aiming_at_alone_distance_point_then_measure))); + SurveyStateEvent.postIdle(positionFragment); + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, false, true)); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_IdleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_IdleState.java new file mode 100644 index 0000000..0fe1e91 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_IdleState.java @@ -0,0 +1,135 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; + +/** + * 空闲状态 + *

+ * 将刷新界面 + */ +class _IdleState extends __BaseState { + private final @NonNull + IAutoModeSwitcher autoModeSwitcher; + + public _IdleState(int positionFragment, StateManagerHeightTraverse stateManager, @NonNull IAutoModeSwitcher autoModeSwitcher) { + super(StateType.idle, positionFragment, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + //1.刷新界面 + refreshUI(); + + refreshGoBackBtnEnable(); + + //3.当前cycle是否完成测量 + boolean completed = _CheckToleranceState.isSingleCycleCompleted( + stationId(), + getCurrentCycleIndex(), + getCachedData()); + + //4.检测是否满足自动测量条件 + ThreadPoolUtil.execute(() -> { + //判断当前条件是否满足自动测量 + + boolean haveAutoCondition = haveAutoCondition(); + + if (haveAutoCondition && autoModeSwitcher.isAutoModeOpen() && isLive()) { + navigation2(StateType.doSurveyor); + } else if (haveAutoCondition && autoModeSwitcher.isAutoModeNotSpecial() && !completed) { + //用户选择后会发送通知,更新测量按钮UI + tips4StartAutoSurvey(); + } else { +// ControlSurveyResult.isAbandon(autoMeasureReadyCode) != null//这个错误 + if (autoModeSwitcher.isAutoModeOpen()) { + autoModeSwitcher.resetAutoMode(); + } + postEvent(haveAutoCondition, autoModeSwitcher.isAutoModeOpen(), completed); + } + + }); + } + + /** + * 弹框提示用户是否开启自动测量 + */ + private void tips4StartAutoSurvey() { + runOnUI(() -> + TipsWith2OptionFragment.hardTips( + fragmentManager(), + lifecycleOwner(), + getContext().getString(R.string.tips_finish_study_should_auto_survey), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doSurveyor); + + postEvent(true, true, false); + } + + @Override + public void onCancel() { + autoModeSwitcher.closeAutoMode(); + + postEvent(true, false, false); + } + + @Override + public void onIgnore() { + autoModeSwitcher.closeAutoMode(); + + postEvent(true, false, false); + } + } + )); + } + + private void postEvent(boolean isReadyAutoSurvey, boolean isOpenAutoSurvey, boolean isSingleCompleted) { + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, isReadyAutoSurvey, isOpenAutoSurvey)); + if (isSingleCompleted) { + SurveyStateEvent.postCompleted(positionFragment); + } else if (!isOpenAutoSurvey) { + SurveyStateEvent.postIdle(positionFragment); + } + } + + @Override + protected void resume() { + autoModeSwitcher.resetAutoMode(); + //刷新测量按钮 + boolean completed = _CheckToleranceState.isSingleCycleCompleted( + stationId(), + getCurrentCycleIndex(), + getCachedData()); + boolean isReady = autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS; + + postEvent(isReady, false, completed); + } + + private boolean haveAutoCondition() { + int autoMeasureReadyCode = autoModeSwitcher.isReadyAutoSurvey(); + return autoMeasureReadyCode == ControlSurveyResult.CODE_SUCCESS; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_Init.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_Init.java new file mode 100644 index 0000000..a7508f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_Init.java @@ -0,0 +1,69 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; + +public class _Init extends __BaseState { + + public _Init(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.init, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + + if (getCachedData().pointCount() == 0) { + navigation2(StateType.idle); + return; + } + + //计算状态之前,重置测量状态 + getSurveyorData().clearSurveyStateAndPosition(); + + //1.先查找补测数据 + FindTargetMethod.Target target = lookTarget(dataCategory -> DataCategory.dirtyAndNeedReSurveyor == dataCategory); + if (target != null) { + lookTargetAfter(target.itemIndex, target.leftOrRight); + return; + } + //2.查找empty数据 + target = lookTarget(dataCategory -> DataCategory.empty == dataCategory); + if (target != null) { + //直接跳转到目标点,开启新测量 + lookTargetAfter(target.itemIndex, target.leftOrRight); + return; + } + //3. + String error = _CheckStationState._stationCheck(stationId(), getToleranceRecord(), getCachedData()); + if (error.isEmpty()) { + //设置测量进度(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + _CheckStationState.showErrorTips(error, stationId(), getToleranceRecord().getCycleCount(), + getCachedData(), + this, + fragmentManager(), + lifecycleOwner()); + } + } + + private FindTargetMethod.Target lookTarget(ILookCase lookCase) { + return _DoMove2NextValidateState.findTarget(stationId(), + getCachedData().pointCount(), getCachedData(), 0, true, + lookCase); + } + + static void enter(StateManagerHeightTraverse stateManager, int cycleIndex) { + Bundle args = new Bundle(); + args.putInt(BundleConstants.KEY_CYCLE_INDEX, cycleIndex); + stateManager.enter(StateType.init, args); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_SurveyorFailureState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_SurveyorFailureState.java new file mode 100644 index 0000000..43527b3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_SurveyorFailureState.java @@ -0,0 +1,52 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +/* + * 仪器导致的测量失败 + * + * 全站仪多次测量失败,进入该状态 + * */ +class _SurveyorFailureState extends __BaseState { + + public _SurveyorFailureState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.SurveyorFailure, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + String error = ""; + boolean isShowDialog = true; + if (args != null) { + error = args.getString(KEY); + isShowDialog = args.getBoolean(KEY_IS_SHOW_DIALOG, true); + } + + if (isShowDialog) { + failureTipsWithAutoStandStill(error + Tools.getString(R.string.please_observe_target)); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + + } + + private static final String KEY = "error"; + private static final String KEY_IS_SHOW_DIALOG = "KEY_IS_SHOW_DIALOG"; + + public static Bundle args(String error) { + Bundle args = new Bundle(); + args.putString(KEY, error); + return args; + } + + public static Bundle args(String error, boolean isShowDialog) { + Bundle args = new Bundle(); + args.putString(KEY, error); + args.putBoolean(KEY_IS_SHOW_DIALOG, isShowDialog); + return args; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/__BaseState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/__BaseState.java new file mode 100644 index 0000000..a26c1e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/__BaseState.java @@ -0,0 +1,572 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +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.BundleConstants; +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.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse.MeasureHeightTraverseFragment; +import com.bingce.controlnetwork.surveyor.state.AutoModeType; +import com.bingce.utils.ThreadPoolUtil; + +import blankj.utilcode.util.ToastUtils; + +public abstract class __BaseState { + private final StateType type; + private final StateManagerHeightTraverse stateManager; + + protected final int positionFragment; + + /** + * 判断常量 + */ + private final int DEFAULT_AUTO_MODE = 0; + private final int RESET_AUTO_MODE = 1; + private final int CLOSE_AUTO_MODE = 2; + + public __BaseState(final StateType stateType, final int positionFragment, final StateManagerHeightTraverse stateManager) { + this.type = stateType; + this.positionFragment = positionFragment; + this.stateManager = stateManager; + } + + final protected StateType getType() { + return type; + } + + final protected @NonNull + ToleranceDetailRecord getToleranceRecord() { + return stateManager.toleranceRecord; + } + + final protected @NonNull + ISurveyorData getSurveyorData() { + return stateManager.surveyorData; + } + + private @NonNull + IAutoModeSwitcher autoModeRecorder() { + return stateManager; + } + + protected void lookTargetAfter(int targetIndex, LeftOrRight targetSurveyorState) { + //更新测量进度 + setSurveyPosition(targetIndex, targetSurveyorState); + + //清除测量状态,进入idle,但是不停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(false); + + //滚动 + scroll2(targetIndex); + } + + /** + * 设置测量位置 + */ + final protected void setSurveyPosition(int index, LeftOrRight leftOrRight) { + stateManager.surveyorData.setCurrentIndex(index); + stateManager.surveyorData.setLeftOrRight(leftOrRight); + //新增 + if (isAloneDistance()) + ToastUtils.showShort(getContext().getString(R.string.attention_point_is_alone_distance)); + } + + final protected ISurveyor surveyorImpl() { + return stateManager.surveyor; + } + + final protected @NonNull + ICachedData getCachedData() { + return stateManager.cachedData; + } + + SurveyorStationRecord getStation() { + return stateManager.stationRecord; + } + + RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return stateManager.getRequestSurveyorParamAuto(); + } + + void changeSkip(int cycleIndex, int index) { + SurveyorStationRecord station = getStation(); + //缓存点 + getCachedData().setPointAbandon(cycleIndex, index); + //数据库点 + String pointId = getCachedData().originalPointId(cycleIndex, index); + for (SurveyorPoint surveyorPoint : station.items) { + if (TextUtils.equals(pointId, surveyorPoint.getOriginalPointId())) { + surveyorPoint.setAbandon(true); + break; + } + } + ThreadPoolUtil.execute(() -> { + SurveyorDatabaseFactory.instance.getSurveyorStation().update(station); + }); + } + + final protected @NonNull + ICycleRecorder getCycleRecorder() { + return stateManager.cycleRecorder; + } + + final protected @NonNull + Context getContext() { + return stateManager.context; + } + + final protected void scroll2(int itemIndex) { + stateManager.scrollDelegate.onScrollTo(itemIndex); + } + + final protected void toast(String warning) { + ToastUtils.showShort(warning); + } + + final protected void toast(@StringRes int warning) { + ToastUtils.showShort(warning); + } + + public abstract void enter(Bundle args);//进入状态 + + final protected void navigation2(StateType stateType) { + stateManager.enter(stateType); + } + + final protected void navigation2(StateType stateType, Bundle args) { + stateManager.enter(stateType, args); + } + + final boolean isStationClosed() { + return stateManager.isStationAutoClosed(); + } + + final protected String stationId() { + return stateManager.stationId(); + } + + final protected FragmentManager fragmentManager() { + return stateManager.fragmentManager(); + } + + final protected LifecycleOwner lifecycleOwner() { + return stateManager.lifecycleOwner(); + } + + final protected void tips(String msg, Runnable runnable) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + if (runnable != null) { + runnable.run(); + } + }); + } + + /** + * 错误提示 + *

+ * 用户不能忽略,点击确定后自动「停留原地」 + */ + final protected void failureTipsWithAutoStandStill(String msg) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void failureTipsWithAutoStandStill(String msg, Runnable runnable) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + if (runnable != null) + runnable.run(); + enterIdleAndClearSurveyStateAndResetAutoMode(true); + }); + } + + final protected void optionTipsWithStandStill(String msg, Runnable confirmCallback) { + optionTips(msg, null, null, + confirmCallback, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void optionTips(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + if (stateManager.isDead()) { + return; + } + TipsWith2OptionFragment.tips( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + final protected void optionTipsCountDown(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + if (stateManager.isDead()) { + return; + } + + TipsWith2OptionFragment.tipsCountDownTime( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + protected final void option4Jump2OtherCycle4Resurvey(int cycleIndex) { + option4Jump2OtherCycle(cycleIndex, true); + } + + protected final void option4Jump2OtherEmptyCycle(int cycleIndex) { + option4Jump2OtherCycle(cycleIndex, false); + } + + private void option4Jump2OtherCycle(int cycleIndex, boolean resurveyOrEmpty) { + String msg = Tools.getString(R.string.there_is_empty_data_to_be_tested_hint); + if (resurveyOrEmpty) { + msg = Tools.getString(R.string.there_is_supplementary_data_to_be_tested_hint); + } + optionTips(Tools.getString(R.string.at) + SurveyorCycleUtil.cycleName(cycleIndex) + msg, + null, + null, + () -> { + //切换测回 + getCycleRecorder().changeCycleIndex(cycleIndex); + //数据库存储修改当前测回 + setCurrentCycle(cycleIndex); + //查找测量目标 + findTargetFromBeginInCurrentCycle(false, 0); + }, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void runOnUI(Runnable runnable) { + stateManager.runOnUI(runnable); + } + + final protected void runOnBackground(Runnable runnable) { + ThreadPoolUtil.execute(runnable); + } + + /** + * 设置测站的测回 + * + * @param cycle + */ + final protected void setCurrentCycle(int cycle) { + getCycleRecorder().changeCycleIndex(cycle); + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), getScheduleKey(positionFragment)), + String.valueOf(cycle))); + } + + final protected void setCurrentCycleSync(int cycle) { + getCycleRecorder().changeCycleIndex(cycle); + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), getScheduleKey(positionFragment)), + String.valueOf(cycle))); + } + + final protected void setSingleCycleSchedule(int cycleIndex, String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), getScheduleKey(positionFragment), cycleIndex), + schedule)); + } + + final protected void setSingleCycleScheduleSync(int cycleIndex, String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), getScheduleKey(positionFragment), cycleIndex), + schedule)); + } + + final protected void setAllCycleSchedule(String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), getScheduleKey(positionFragment)), + schedule)); + } + + final protected void setAllCycleScheduleSync(String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), getScheduleKey(positionFragment)), + schedule)); + } + + /** + * 如果resetAutoSurveyState为true,将重置autoSurvey状态为unknown + */ + final protected void findTargetFromBeginInCurrentCycle(boolean resetAutoSurveyState, int startLookCycleIndex) { +// getSurveyorData().clearSurveyStateAndPosition(); + if (resetAutoSurveyState) { + autoModeRecorder().resetAutoMode(); + } + if (startLookCycleIndex != -1) { + Bundle bundle = new Bundle(); + bundle.putInt(BundleConstants.KEY_CYCLE_INDEX, startLookCycleIndex); + navigation2(StateType.doMove2NextValidate, bundle); + } else { + navigation2(StateType.doMove2NextValidate); + } + } + + final protected void enterIdleAndClearSurveyState() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + /** + * 取消测量,会停在当前位置(索引+盘左or盘右),并进入idle + */ + final protected void enterIdleAndClearSurveyStateAndResetAutoMode(boolean resetAutoMode) { + clearSurveyStateAndCloseAutoModeAndStandStill(resetAutoMode ? RESET_AUTO_MODE : DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + final protected void enterIdleAndClearSurveyorStatePosition() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + true, StateType.idle); + } + + final protected void enterStationCheckAndClearSurveyStateAndResetAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(RESET_AUTO_MODE, + false, StateType.checkStation); + } + + final protected void enterIdleAndClearSurveyStateAndCloseAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(CLOSE_AUTO_MODE, false, StateType.idle); + } + + /** + * @param autoMode + * @param clearPosition + * @param stateType + */ + private void clearSurveyStateAndCloseAutoModeAndStandStill(int autoMode, boolean clearPosition, StateType stateType) { + //重置或者关闭自动模式 + if (autoMode == RESET_AUTO_MODE) { + autoModeRecorder().resetAutoMode(); + } else if (autoMode == CLOSE_AUTO_MODE) { + autoModeRecorder().closeAutoMode(); + } + //更新测量进度标识 + if (clearPosition) { + getSurveyorData().clearSurveyStateAndPosition(); + } else { + getSurveyorData().clearSurveyState(); + } + //进入某个状态 + navigation2(stateType); + } + + protected void setAutoAndSurveyorState(AutoModeType autoModeType, boolean clearPosition) { + if (autoModeType == AutoModeType.start) { + autoModeRecorder().openAutoMode(); + } else if (autoModeType == AutoModeType.stop) { + autoModeRecorder().closeAutoMode(); + } else if (autoModeType == AutoModeType.unknown) { + autoModeRecorder().resetAutoMode(); + } + + if (clearPosition) { + getSurveyorData().clearSurveyStateAndPosition(); + } else { + getSurveyorData().clearSurveyState(); + } + } + + + /** + * 更新UI + */ + final protected void refreshUI() { + runOnUI(() -> getCachedData().notifyDateChange()); + } + + protected void quite() { + } + + protected void resume() { + } + + protected boolean isLive() { + return !stateManager.isDead(); + } + + protected boolean isAutoSurveyOpen() { + return stateManager.isAutoModeOpen(); + } + + protected boolean isAutoSurveyClosed() { + return stateManager.isAutoModeClose(); + } + + protected int getCurrentIndex() { + return stateManager.surveyorData.currentIndex(); + } + + protected int getCurrentCycleIndex() { +// return stateManager.cycleRecorder.currentCycleIndex(); + return getCurrentIndex(); + } + + protected boolean isAloneDistance() { + return stateManager.getCachedData().isAloneDistance(stateManager.getCurrentCycle(), getCurrentIndex()); + } + + protected double getInstrumentHeight() { + return stateManager.getInsturmentHeight(); + } + + protected void refreshGoBackBtnEnable() { + stateManager.refreshGoBackBtnEnable(); + } + + protected void resetLearnDataTag() { + getRequestSurveyorParamAuto().resetCodeAutoMeasureCondition(); + } + + public static String getScheduleKey(int positionFragment) { + if (positionFragment == MeasureHeightTraverseFragment.POSITION_BACK_PAGE) { + return SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_BACK; + } + return SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_FRONT; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/surveyor/TestDataSelectFragment.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/surveyor/TestDataSelectFragment.java new file mode 100644 index 0000000..c8f1a2b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/surveyor/TestDataSelectFragment.java @@ -0,0 +1,74 @@ +package com.bingce.controlnetwork.surveyor.surveyor; + +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.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.surveyor.test.Test; + +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; +import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; + +public class TestDataSelectFragment extends DialogFragment { + + @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) { + IndexWithTextAdapter adapter = new IndexWithTextAdapter<>(Test.items, new IndexWithTextAdapter.IOnItemClick() { + @Override + public void onItemClick(Test.Item item) { + Test.type = item; + dismiss(); + } + }); + recyclerView.setAdapter(adapter); + } + + public static void show(FragmentManager fragmentManager) { + TestDataSelectFragment fragment = new TestDataSelectFragment(); + fragment.show(fragmentManager, TestDataSelectFragment.class.getName()); + } +} 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/ViewUtil.java b/app/src/main/java/com/bingce/controlnetwork/ui/ViewUtil.java new file mode 100644 index 0000000..944b6e4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/ViewUtil.java @@ -0,0 +1,18 @@ +package com.bingce.controlnetwork.ui; + +import android.app.Activity; +import android.view.View; + +public class ViewUtil { + public static void setOnClick(View view, View.OnClickListener listener) { + if (view == null) { + return; + } + view.setOnClickListener(listener); + } + + public static void setOnClick(Activity activity, int view, View.OnClickListener listener) { + View v = activity.findViewById(view); + setOnClick(v, listener); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/helper/OnActivityTouchListener.java b/app/src/main/java/com/bingce/controlnetwork/ui/helper/OnActivityTouchListener.java new file mode 100644 index 0000000..419c603 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/helper/OnActivityTouchListener.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.ui.helper; + +import android.view.MotionEvent; + +public interface OnActivityTouchListener { + void getTouchCoordinates(MotionEvent ev); +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/helper/RecyclerTouchListener.java b/app/src/main/java/com/bingce/controlnetwork/ui/helper/RecyclerTouchListener.java new file mode 100644 index 0000000..6687e8c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/helper/RecyclerTouchListener.java @@ -0,0 +1,918 @@ +package com.bingce.controlnetwork.ui.helper; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.app.Activity; +import android.graphics.Rect; +import android.os.Handler; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.animation.DecelerateInterpolator; +import android.widget.ListView; + +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener, OnActivityTouchListener { + private static final String TAG = "RecyclerTouchListener"; + final Handler handler = new Handler(); + Activity act; + List unSwipeableRows; + /* + * independentViews are views on the foreground layer which when clicked, act "independent" from the foreground + * ie, they are treated separately from the "row click" action + */ + List independentViews; + List unClickableRows; + List optionViews; + Set ignoredViewTypes; + // Cached ViewConfiguration and system-wide constant values + private final int touchSlop; + private final int minFlingVel; + private final int maxFlingVel; + private final long ANIMATION_STANDARD = 300; + private final long ANIMATION_CLOSE = 150; + // Fixed properties + private final RecyclerView rView; + // private SwipeListener mSwipeListener; + private int bgWidth = 1; + private final int bgWidthLeft = 1; // 1 and not 0 to prevent dividing by zero + // Transient properties + // private List mPendingDismisses = new ArrayList<>(); + private int mDismissAnimationRefCount = 0; + private float touchedX; + private float touchedY; + private boolean isFgSwiping; + private int mSwipingSlop; + private VelocityTracker mVelocityTracker; + private int touchedPosition; + private View touchedView; + private boolean mPaused; + private boolean bgVisible, fgPartialViewClicked; + private int bgVisiblePosition; + private View bgVisibleView; + private boolean isRViewScrolling; + private int heightOutsideRView, screenHeight; + private boolean mLongClickPerformed; + // Foreground view (to be swiped), Background view (to show) + private View fgView; + private View bgView; + //view ID + private int fgViewID; + private int bgViewID, bgViewIDLeft; + private ArrayList fadeViews; + private OnRowClickListener mRowClickListener; + private OnRowLongClickListener mRowLongClickListener; + private OnSwipeOptionsClickListener mBgClickListener, mBgClickListenerLeft; + // user choices + private boolean clickable = false; + private boolean longClickable = false; + private boolean swipeable = false; + private final boolean swipeableLeftOptions = false; + private final int LONG_CLICK_DELAY = 800; + private boolean longClickVibrate; + Runnable mLongPressed = new Runnable() { + public void run() { + if (!longClickable) + return; + + mLongClickPerformed = true; + + if (!bgVisible && touchedPosition >= 0 && !unClickableRows.contains(touchedPosition) && !isRViewScrolling) { + if (longClickVibrate) { +// Vibrator vibe = (Vibrator) act.getSystemService(Context.VIBRATOR_SERVICE); +// vibe.vibrate(100); // do we really need to add vibrate service + } + mRowLongClickListener.onRowLongClicked(touchedPosition); + } + } + }; + + public RecyclerTouchListener(Activity a, RecyclerView recyclerView) { + this.act = a; + ViewConfiguration vc = ViewConfiguration.get(recyclerView.getContext()); + touchSlop = vc.getScaledTouchSlop(); + minFlingVel = vc.getScaledMinimumFlingVelocity() * 16; + maxFlingVel = vc.getScaledMaximumFlingVelocity(); + rView = recyclerView; + bgVisible = false; + bgVisiblePosition = -1; + bgVisibleView = null; + fgPartialViewClicked = false; + unSwipeableRows = new ArrayList<>(); + unClickableRows = new ArrayList<>(); + ignoredViewTypes = new HashSet<>(); + independentViews = new ArrayList<>(); + optionViews = new ArrayList<>(); + fadeViews = new ArrayList<>(); + isRViewScrolling = false; + +// mSwipeListener = listener; + + rView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + /** + * This will ensure that this RecyclerTouchListener is paused during recycler view scrolling. + * If a scroll listener is already assigned, the caller should still pass scroll changes through + * to this listener. + */ + setEnabled(newState != RecyclerView.SCROLL_STATE_DRAGGING); + + /** + * This is used so that clicking a row cannot be done while scrolling + */ + isRViewScrolling = newState != RecyclerView.SCROLL_STATE_IDLE; + } + + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + + } + }); + } + + /** + * Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures. + * + * @param enabled Whether or not to watch for gestures. + */ + public void setEnabled(boolean enabled) { + mPaused = !enabled; + } + + @Override + public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent motionEvent) { + return handleTouchEvent(motionEvent); + } + + @Override + public void onTouchEvent(RecyclerView rv, MotionEvent motionEvent) { + handleTouchEvent(motionEvent); + } + + /*////////////// Clickable ////////////////////*/ + + public RecyclerTouchListener setClickable(OnRowClickListener listener) { + this.clickable = true; + this.mRowClickListener = listener; + return this; + } + + public RecyclerTouchListener setClickable(boolean clickable) { + this.clickable = clickable; + return this; + } + + public RecyclerTouchListener setLongClickable(boolean vibrate, OnRowLongClickListener listener) { + this.longClickable = true; + this.mRowLongClickListener = listener; + this.longClickVibrate = vibrate; + return this; + } + + public RecyclerTouchListener setLongClickable(boolean longClickable) { + this.longClickable = longClickable; + return this; + } + + public RecyclerTouchListener setIndependentViews(Integer... viewIds) { + this.independentViews = new ArrayList<>(Arrays.asList(viewIds)); + return this; + } + + public RecyclerTouchListener setUnClickableRows(Integer... rows) { + this.unClickableRows = new ArrayList<>(Arrays.asList(rows)); + return this; + } + + public RecyclerTouchListener setIgnoredViewTypes(Integer... viewTypes) { + ignoredViewTypes.clear(); + ignoredViewTypes.addAll(Arrays.asList(viewTypes)); + return this; + } + + //////////////// Swipeable //////////////////// + + public RecyclerTouchListener setSwipeable(int foregroundID, int backgroundID, OnSwipeOptionsClickListener listener) { + this.swipeable = true; + if (fgViewID != 0 && foregroundID != fgViewID) + throw new IllegalArgumentException("foregroundID does not match previously set ID"); + fgViewID = foregroundID; + bgViewID = backgroundID; + this.mBgClickListener = listener; + + if (act instanceof RecyclerTouchListenerHelper) + ((RecyclerTouchListenerHelper) act).setOnActivityTouchListener(this); + + DisplayMetrics displaymetrics = new DisplayMetrics(); + act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); + screenHeight = displaymetrics.heightPixels; + + return this; + } + + public RecyclerTouchListener setSwipeable(boolean value) { + this.swipeable = value; + if (!value) + invalidateSwipeOptions(); + return this; + } + + public RecyclerTouchListener setSwipeOptionViews(Integer... viewIds) { + this.optionViews = new ArrayList<>(Arrays.asList(viewIds)); + return this; + } + + public RecyclerTouchListener setUnSwipeableRows(Integer... rows) { + this.unSwipeableRows = new ArrayList<>(Arrays.asList(rows)); + return this; + } + + //////////////// Fade Views //////////////////// + + // Set views which are faded out as fg is opened + public RecyclerTouchListener setViewsToFade(Integer... viewIds) { + this.fadeViews = new ArrayList<>(Arrays.asList(viewIds)); + return this; + } + + // the entire foreground is faded out as it is opened + public RecyclerTouchListener setFgFade() { + if (!fadeViews.contains(fgViewID)) + this.fadeViews.add(fgViewID); + return this; + } + + //-------------- Checkers for preventing ---------------// + + private boolean isIndependentViewClicked(MotionEvent motionEvent) { + for (int i = 0; i < independentViews.size(); i++) { + if (touchedView != null) { + Rect rect = new Rect(); + int x = (int) motionEvent.getRawX(); + int y = (int) motionEvent.getRawY(); + touchedView.findViewById(independentViews.get(i)).getGlobalVisibleRect(rect); + if (rect.contains(x, y)) { + return false; + } + } + } + return true; + } + + private int getOptionViewID(MotionEvent motionEvent) { + for (int i = 0; i < optionViews.size(); i++) { + if (touchedView != null) { + Rect rect = new Rect(); + int x = (int) motionEvent.getRawX(); + int y = (int) motionEvent.getRawY(); + touchedView.findViewById(optionViews.get(i)).getGlobalVisibleRect(rect); + if (rect.contains(x, y)) { + return optionViews.get(i); + } + } + } + return -1; + } + + private int getIndependentViewID(MotionEvent motionEvent) { + for (int i = 0; i < independentViews.size(); i++) { + if (touchedView != null) { + Rect rect = new Rect(); + int x = (int) motionEvent.getRawX(); + int y = (int) motionEvent.getRawY(); + touchedView.findViewById(independentViews.get(i)).getGlobalVisibleRect(rect); + if (rect.contains(x, y)) { + return independentViews.get(i); + } + } + } + return -1; + } + + @Override + public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { + + } + + public void invalidateSwipeOptions() { + bgWidth = 1; + } + + public void openSwipeOptions(int position) { + if (!swipeable || rView.getChildAt(position) == null + || unSwipeableRows.contains(position) || shouldIgnoreAction(position)) + return; + if (bgWidth < 2) { + if (act.findViewById(bgViewID) != null) + bgWidth = act.findViewById(bgViewID).getWidth(); + heightOutsideRView = screenHeight - rView.getHeight(); + } + touchedPosition = position; + touchedView = rView.getChildAt(position); + fgView = touchedView.findViewById(fgViewID); + bgView = touchedView.findViewById(bgViewID); + bgView.setMinimumHeight(fgView.getHeight()); + + closeVisibleBG(null); + animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD); + bgVisible = true; + bgVisibleView = fgView; + bgVisiblePosition = touchedPosition; + } + + @Deprecated + public void closeVisibleBG() { + if (bgVisibleView == null) { + Log.e(TAG, "No rows found for which background options are visible"); + return; + } + bgVisibleView.animate() + .translationX(0) + .setDuration(ANIMATION_CLOSE) + .setListener(null); + + animateFadeViews(bgVisibleView, 1f, ANIMATION_CLOSE); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + + public void closeVisibleBG(final OnSwipeListener mSwipeCloseListener) { + if (bgVisibleView == null) { + Log.e(TAG, "No rows found for which background options are visible"); + return; + } + final ObjectAnimator translateAnimator = ObjectAnimator.ofFloat(bgVisibleView, + View.TRANSLATION_X, 0f); + translateAnimator.setDuration(ANIMATION_CLOSE); + translateAnimator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + if (mSwipeCloseListener != null) + mSwipeCloseListener.onSwipeOptionsClosed(); + translateAnimator.removeAllListeners(); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + }); + translateAnimator.start(); + + animateFadeViews(bgVisibleView, 1f, ANIMATION_CLOSE); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + + private void animateFadeViews(View downView, float alpha, long duration) { + if (fadeViews != null) { + for (final int viewID : fadeViews) { + downView.findViewById(viewID).animate() + .alpha(alpha) + .setDuration(duration); + } + } + } + + private void animateFG(View downView, Animation animateType, long duration) { + if (animateType == Animation.OPEN) { + ObjectAnimator translateAnimator = ObjectAnimator.ofFloat( + fgView, View.TRANSLATION_X, -bgWidth); + translateAnimator.setDuration(duration); + translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f)); + translateAnimator.start(); + animateFadeViews(downView, 0f, duration); + } else if (animateType == Animation.CLOSE) { + ObjectAnimator translateAnimator = ObjectAnimator.ofFloat( + fgView, View.TRANSLATION_X, 0f); + translateAnimator.setDuration(duration); + translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f)); + translateAnimator.start(); + animateFadeViews(downView, 1f, duration); + } + } + + private void animateFG(View downView, final Animation animateType, long duration, + final OnSwipeListener mSwipeCloseListener) { + final ObjectAnimator translateAnimator; + if (animateType == Animation.OPEN) { + translateAnimator = ObjectAnimator.ofFloat(fgView, View.TRANSLATION_X, -bgWidth); + translateAnimator.setDuration(duration); + translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f)); + translateAnimator.start(); + animateFadeViews(downView, 0f, duration); + } else /*if (animateType == Animation.CLOSE)*/ { + translateAnimator = ObjectAnimator.ofFloat(fgView, View.TRANSLATION_X, 0f); + translateAnimator.setDuration(duration); + translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f)); + translateAnimator.start(); + animateFadeViews(downView, 1f, duration); + } + + translateAnimator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + if (mSwipeCloseListener != null) { + if (animateType == Animation.OPEN) + mSwipeCloseListener.onSwipeOptionsOpened(); + else if (animateType == Animation.CLOSE) + mSwipeCloseListener.onSwipeOptionsClosed(); + } + translateAnimator.removeAllListeners(); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + }); + } + + private boolean handleTouchEvent(MotionEvent motionEvent) { + if (swipeable && bgWidth < 2) { +// bgWidth = rView.getWidth(); + if (act.findViewById(bgViewID) != null) + bgWidth = act.findViewById(bgViewID).getWidth(); + + heightOutsideRView = screenHeight - rView.getHeight(); + } + + switch (motionEvent.getActionMasked()) { + + // When finger touches screen + case MotionEvent.ACTION_DOWN: { + if (mPaused) { + break; + } + + // Find the child view that was touched (perform a hit test) + Rect rect = new Rect(); + int childCount = rView.getChildCount(); + int[] listViewCoords = new int[2]; + rView.getLocationOnScreen(listViewCoords); + // x and y values respective to the recycler view + int x = (int) motionEvent.getRawX() - listViewCoords[0]; + int y = (int) motionEvent.getRawY() - listViewCoords[1]; + View child; + + /* + * check for every child (row) in the recycler view whether the touched co-ordinates belong to that + * respective child and if it does, register that child as the touched view (touchedView) + */ + for (int i = 0; i < childCount; i++) { + child = rView.getChildAt(i); + child.getHitRect(rect); + if (rect.contains(x, y)) { + touchedView = child; + break; + } + } + + if (touchedView != null) { + touchedX = motionEvent.getRawX(); + touchedY = motionEvent.getRawY(); + touchedPosition = rView.getChildAdapterPosition(touchedView); + + if (shouldIgnoreAction(touchedPosition)) { + touchedPosition = ListView.INVALID_POSITION; + return false; // <-- guard here allows for ignoring events, allowing more than one view type and preventing NPE + } + + if (longClickable) { + mLongClickPerformed = false; + handler.postDelayed(mLongPressed, LONG_CLICK_DELAY); + } + if (swipeable) { + mVelocityTracker = VelocityTracker.obtain(); + mVelocityTracker.addMovement(motionEvent); + fgView = touchedView.findViewById(fgViewID); + bgView = touchedView.findViewById(bgViewID); +// bgView.getLayoutParams().height = fgView.getHeight(); + bgView.setMinimumHeight(fgView.getHeight()); + + /* + * bgVisible is true when the options menu is opened + * This block is to register fgPartialViewClicked status - Partial view is the view that is still + * shown on the screen if the options width is < device width + */ + if (bgVisible && fgView != null) { + handler.removeCallbacks(mLongPressed); + x = (int) motionEvent.getRawX(); + y = (int) motionEvent.getRawY(); + fgView.getGlobalVisibleRect(rect); + fgPartialViewClicked = rect.contains(x, y); + } else { + fgPartialViewClicked = false; + } + } + } + + /* + * If options menu is shown and the touched position is not the same as the row for which the + * options is displayed - close the options menu for the row which is displaying it + * (bgVisibleView and bgVisiblePosition is used for this purpose which registers which view and + * which position has it's options menu opened) + */ + x = (int) motionEvent.getRawX(); + y = (int) motionEvent.getRawY(); + rView.getHitRect(rect); + if (swipeable && bgVisible && touchedPosition != bgVisiblePosition) { + handler.removeCallbacks(mLongPressed); + closeVisibleBG(null); + } + break; + } + + case MotionEvent.ACTION_CANCEL: { + handler.removeCallbacks(mLongPressed); + if (mLongClickPerformed) + break; + + if (mVelocityTracker == null) { + break; + } + if (swipeable) { + if (touchedView != null && isFgSwiping) { + // cancel + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD); + } + mVelocityTracker.recycle(); + mVelocityTracker = null; + isFgSwiping = false; + bgView = null; + } + touchedX = 0; + touchedY = 0; + touchedView = null; + touchedPosition = ListView.INVALID_POSITION; + break; + } + + // When finger is lifted off the screen (after clicking, flinging, swiping, etc..) + case MotionEvent.ACTION_UP: { + handler.removeCallbacks(mLongPressed); + if (mLongClickPerformed) + break; + + if (mVelocityTracker == null && swipeable) { + break; + } + if (touchedPosition < 0) + break; + + // swipedLeft and swipedRight are true if the user swipes in the respective direction (no conditions) + boolean swipedLeft = false; + boolean swipedRight = false; + /* + * swipedLeftProper and swipedRightProper are true if user swipes in the respective direction + * and if certain conditions are satisfied (given some few lines below) + */ + boolean swipedLeftProper = false; + boolean swipedRightProper = false; + + float mFinalDelta = motionEvent.getRawX() - touchedX; + + // if swiped in a direction, make that respective variable true + if (isFgSwiping) { + swipedLeft = mFinalDelta < 0; + swipedRight = mFinalDelta > 0; + } + + /* + * If the user has swiped more than half of the width of the options menu, or if the + * velocity of swiping is between min and max fling values + * "proper" variable are set true + */ + if (Math.abs(mFinalDelta) > bgWidth / 2 && isFgSwiping) { + swipedLeftProper = mFinalDelta < 0; + swipedRightProper = mFinalDelta > 0; + } else if (swipeable) { + mVelocityTracker.addMovement(motionEvent); + mVelocityTracker.computeCurrentVelocity(1000); + float velocityX = mVelocityTracker.getXVelocity(); + float absVelocityX = Math.abs(velocityX); + float absVelocityY = Math.abs(mVelocityTracker.getYVelocity()); + if (minFlingVel <= absVelocityX && absVelocityX <= maxFlingVel + && absVelocityY < absVelocityX && isFgSwiping) { + // dismiss only if flinging in the same direction as dragging + swipedLeftProper = (velocityX < 0) == (mFinalDelta < 0); + swipedRightProper = (velocityX > 0) == (mFinalDelta > 0); + } + } + + ///////// Manipulation of view based on the 4 variables mentioned above /////////// + + // if swiped left properly and options menu isn't already visible, animate the foreground to the left + if (swipeable && !swipedRight && swipedLeftProper && touchedPosition != RecyclerView.NO_POSITION + && !unSwipeableRows.contains(touchedPosition) && !bgVisible) { + + final View downView = touchedView; // touchedView gets null'd before animation ends + final int downPosition = touchedPosition; + ++mDismissAnimationRefCount; + //TODO - speed + animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD); + bgVisible = true; + bgVisibleView = fgView; + bgVisiblePosition = downPosition; + } + // else if swiped right properly when options menu is visible, close the menu and bring the foreground + // to it's original position + else if (swipeable && !swipedLeft && swipedRightProper && touchedPosition != RecyclerView.NO_POSITION + && !unSwipeableRows.contains(touchedPosition) && bgVisible) { + // dismiss + final View downView = touchedView; // touchedView gets null'd before animation ends + final int downPosition = touchedPosition; + + ++mDismissAnimationRefCount; + //TODO - speed + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + // else if swiped left incorrectly (not satisfying the above conditions), animate the foreground back to + // it's original position (spring effect) + else if (swipeable && swipedLeft && !bgVisible) { + // cancel + final View tempBgView = bgView; + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD, new OnSwipeListener() { + @Override + public void onSwipeOptionsClosed() { + if (tempBgView != null) + tempBgView.setVisibility(View.VISIBLE); + } + + @Override + public void onSwipeOptionsOpened() { + + } + }); + + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + // else if swiped right incorrectly (not satisfying the above conditions), animate the foreground to + // it's open position (spring effect) + else if (swipeable && swipedRight && bgVisible) { + // cancel + animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD); + bgVisible = true; + bgVisibleView = fgView; + bgVisiblePosition = touchedPosition; + } + // This case deals with an error where the user can swipe left, then right + // really fast and the fg is stuck open - so in that case we close the fg + else if (swipeable && swipedRight && !bgVisible) { + // cancel + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + // This case deals with an error where the user can swipe right, then left + // really fast and the fg is stuck open - so in that case we open the fg + else if (swipeable && swipedLeft && bgVisible) { + // cancel + animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD); + bgVisible = true; + bgVisibleView = fgView; + bgVisiblePosition = touchedPosition; + } + + // if clicked + else if (!swipedRight && !swipedLeft) { + // if partial foreground view is clicked (see ACTION_DOWN) bring foreground back to original position + // bgVisible is true automatically since it's already checked in ACTION_DOWN block + if (swipeable && fgPartialViewClicked) { + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + // On Click listener for rows + else if (clickable && !bgVisible && touchedPosition >= 0 && !unClickableRows.contains(touchedPosition) + && isIndependentViewClicked(motionEvent) && !isRViewScrolling) { + mRowClickListener.onRowClicked(touchedPosition); + } + // On Click listener for independent views inside the rows + else if (clickable && !bgVisible && touchedPosition >= 0 && !unClickableRows.contains(touchedPosition) + && !isIndependentViewClicked(motionEvent) && !isRViewScrolling) { + final int independentViewID = getIndependentViewID(motionEvent); + if (independentViewID >= 0) + mRowClickListener.onIndependentViewClicked(independentViewID, touchedPosition); + } + // On Click listener for background options + else if (swipeable && bgVisible && !fgPartialViewClicked) { + final int optionID = getOptionViewID(motionEvent); + if (optionID >= 0 && touchedPosition >= 0) { + final int downPosition = touchedPosition; + closeVisibleBG(new OnSwipeListener() { + @Override + public void onSwipeOptionsClosed() { + mBgClickListener.onSwipeOptionClicked(optionID, downPosition); + } + + @Override + public void onSwipeOptionsOpened() { + + } + }); + } + } + } + } + // if clicked and not swiped + + if (swipeable) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + touchedX = 0; + touchedY = 0; + touchedView = null; + touchedPosition = ListView.INVALID_POSITION; + isFgSwiping = false; + bgView = null; + break; + + // when finger is moving across the screen (and not yet lifted) + case MotionEvent.ACTION_MOVE: { + if (mLongClickPerformed) + break; + if (mVelocityTracker == null || mPaused || !swipeable) { + break; + } + + mVelocityTracker.addMovement(motionEvent); + float deltaX = motionEvent.getRawX() - touchedX; + float deltaY = motionEvent.getRawY() - touchedY; + + /* + * isFgSwiping variable which is set to true here is used to alter the swipedLeft, swipedRightProper + * variables in "ACTION_UP" block by checking if user is actually swiping at present or not + */ + if (!isFgSwiping && Math.abs(deltaX) > touchSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) { + handler.removeCallbacks(mLongPressed); + isFgSwiping = true; + mSwipingSlop = (deltaX > 0 ? touchSlop : -touchSlop); + } + + // This block moves the foreground along with the finger when swiping + if (swipeable && isFgSwiping && !unSwipeableRows.contains(touchedPosition)) { + if (bgView == null) { + bgView = touchedView.findViewById(bgViewID); + bgView.setVisibility(View.VISIBLE); + } + // if fg is being swiped left + if (deltaX < touchSlop && !bgVisible) { + float translateAmount = deltaX - mSwipingSlop; +// if ((Math.abs(translateAmount) > bgWidth ? -bgWidth : translateAmount) <= 0) { + // swipe fg till width of bg. If swiped further, nothing happens (stalls at width of bg) + fgView.setTranslationX(Math.abs(translateAmount) > bgWidth ? -bgWidth : translateAmount); + if (fgView.getTranslationX() > 0) fgView.setTranslationX(0); +// } + + // fades all the fadeViews gradually to 0 alpha as dragged + if (fadeViews != null) { + for (int viewID : fadeViews) { + touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth)); + } + } + } + // if fg is being swiped right + else if (deltaX > 0 && bgVisible) { + // for closing rightOptions + if (bgVisible) { + float translateAmount = (deltaX - mSwipingSlop) - bgWidth; + + // swipe fg till it reaches original position. If swiped further, nothing happens (stalls at 0) + fgView.setTranslationX(translateAmount > 0 ? 0 : translateAmount); + + // fades all the fadeViews gradually to 0 alpha as dragged + if (fadeViews != null) { + for (int viewID : fadeViews) { + touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth)); + } + } + } + // for opening leftOptions + else { + float translateAmount = (deltaX - mSwipingSlop) - bgWidth; + + // swipe fg till it reaches original position. If swiped further, nothing happens (stalls at 0) + fgView.setTranslationX(translateAmount > 0 ? 0 : translateAmount); + + // fades all the fadeViews gradually to 0 alpha as dragged + if (fadeViews != null) { + for (int viewID : fadeViews) { + touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth)); + } + } + } + } + return true; + } + // moves the fg slightly to give the illusion of an "unswipeable" row + else if (swipeable && isFgSwiping && unSwipeableRows.contains(touchedPosition)) { + if (deltaX < touchSlop && !bgVisible) { + float translateAmount = deltaX - mSwipingSlop; + if (bgView == null) + bgView = touchedView.findViewById(bgViewID); + + if (bgView != null) + bgView.setVisibility(View.GONE); + + // swipe fg till width of bg. If swiped further, nothing happens (stalls at width of bg) + fgView.setTranslationX(translateAmount / 5); + if (fgView.getTranslationX() > 0) fgView.setTranslationX(0); + + // fades all the fadeViews gradually to 0 alpha as dragged +// if (fadeViews != null) { +// for (int viewID : fadeViews) { +// touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth)); +// } +// } + } + return true; + } + break; + } + } + return false; + } + + /** + * Gets coordinates from Activity and closes any + * swiped rows if touch happens outside the recycler view + */ + @Override + public void getTouchCoordinates(MotionEvent ev) { + int y = (int) ev.getRawY(); + if (swipeable && bgVisible && ev.getActionMasked() == MotionEvent.ACTION_DOWN + && y < heightOutsideRView) closeVisibleBG(null); + } + + private boolean shouldIgnoreAction(int touchedPosition) { + return rView == null || ignoredViewTypes.contains(rView.getAdapter().getItemViewType(touchedPosition)); + } + + private enum Animation { + OPEN, CLOSE + } + + /////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////// Interfaces ///////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////// + + public interface OnRowClickListener { + void onRowClicked(int position); + + void onIndependentViewClicked(int independentViewID, int position); + } + + public interface OnRowLongClickListener { + void onRowLongClicked(int position); + } + + public interface OnSwipeOptionsClickListener { + void onSwipeOptionClicked(int viewID, int position); + } + + public interface RecyclerTouchListenerHelper { + void setOnActivityTouchListener(OnActivityTouchListener listener); + } + + public interface OnSwipeListener { + void onSwipeOptionsClosed(); + + void onSwipeOptionsOpened(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableTextViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableTextViewHolder.java new file mode 100644 index 0000000..81db07d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableTextViewHolder.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import com.bingce.controlnetwork.R; + +public class DraggableTextViewHolder extends RecyclerView.ViewHolder { + public final TextView title; + public final ImageView dragBar; + + public DraggableTextViewHolder(@NonNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.title); + dragBar = itemView.findViewById(R.id.drag_bar); + } + + public static void update(DraggableTextViewHolder draggableTextViewHolder, StationDetailItem item, boolean editable) { + draggableTextViewHolder.title.setText(item.getName()); + if (StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType()) || !editable) { + draggableTextViewHolder.dragBar.setVisibility(View.GONE); + } else { + draggableTextViewHolder.dragBar.setVisibility(View.VISIBLE); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableViewHolder.java new file mode 100644 index 0000000..d8b69f7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableViewHolder.java @@ -0,0 +1,14 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; + +import androidx.annotation.NonNull; + +import org.jetbrains.annotations.NotNull; + +public class DraggableViewHolder extends IndexTextViewHolder { + + public DraggableViewHolder(@NonNull @NotNull View itemView) { + super(itemView); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/GroupParentViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/GroupParentViewHolder.java new file mode 100644 index 0000000..3daafea --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/GroupParentViewHolder.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class GroupParentViewHolder extends RecyclerView.ViewHolder { + public final TextView name; + public final ImageView expandIcon; + + public GroupParentViewHolder(@NonNull View itemView) { + super(itemView); + expandIcon = itemView.findViewById(R.id.expand_icon); + name = itemView.findViewById(R.id.groupName); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextSelectableViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextSelectableViewHolder.java new file mode 100644 index 0000000..ed8705b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextSelectableViewHolder.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; + +import androidx.annotation.NonNull; + +import com.bingce.controlnetwork.R; + +public class IndexTextSelectableViewHolder extends IndexTextViewHolder { + public final ImageView status; + public final View mask; + public final View item; + + public IndexTextSelectableViewHolder(@NonNull View itemView) { + super(itemView); + status = itemView.findViewById(R.id.status); + mask = itemView.findViewById(R.id.mask); + item = itemView.findViewById(R.id.item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextViewHolder.java new file mode 100644 index 0000000..1231cb8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextViewHolder.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class IndexTextViewHolder extends RecyclerView.ViewHolder { + public final TextView index; + public final TextView name; + + public IndexTextViewHolder(@NonNull View itemView) { + super(itemView); + index = itemView.findViewById(R.id.index); + name = itemView.findViewById(R.id.text); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextWithPrefixViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextWithPrefixViewHolder.java new file mode 100644 index 0000000..a979be9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextWithPrefixViewHolder.java @@ -0,0 +1,17 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.bingce.controlnetwork.R; + +public class IndexTextWithPrefixViewHolder extends IndexTextViewHolder { + public final TextView prefix; + + public IndexTextWithPrefixViewHolder(@NonNull View itemView) { + super(itemView); + prefix = itemView.findViewById(R.id.prefix); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/ItemWellViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/ItemWellViewHolder.java new file mode 100644 index 0000000..b35ec36 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/ItemWellViewHolder.java @@ -0,0 +1,40 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import com.bingce.controlnetwork.R; + +public class ItemWellViewHolder extends RecyclerView.ViewHolder { + public final TextView title; + public final ImageView dragBar; + + public ItemWellViewHolder(@NonNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.title); + dragBar = itemView.findViewById(R.id.drag_bar); + } + + public static void update(ItemWellViewHolder holder, StationDetailItem item, boolean editable, IUIBuilderDelegate iuiBuilderDelegate) { + holder.title.setText(item.getName()); + if (StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType()) || !editable) { + holder.dragBar.setVisibility(View.GONE); + } else { + holder.dragBar.setVisibility(View.VISIBLE); + } + + if (iuiBuilderDelegate != null) { + iuiBuilderDelegate.build(item.getType(), holder); + } + } + + public interface IUIBuilderDelegate { + void build(String itemType, ItemWellViewHolder holder); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyBoolViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyBoolViewHolder.java new file mode 100644 index 0000000..078fd4c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyBoolViewHolder.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.CheckBox; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class KeyBoolViewHolder extends RecyclerView.ViewHolder { + public final TextView key; + public final CheckBox checkBox; + + public KeyBoolViewHolder(@NonNull View itemView) { + super(itemView); + key = itemView.findViewById(R.id.name); + checkBox = itemView.findViewById(R.id.checkBox); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyValueViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyValueViewHolder.java new file mode 100644 index 0000000..e31e537 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyValueViewHolder.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class KeyValueViewHolder extends RecyclerView.ViewHolder { + public final TextView key; + public final TextView value; + + public KeyValueViewHolder(@NonNull View itemView) { + super(itemView); + key = itemView.findViewById(R.id.name); + value = itemView.findViewById(R.id.value); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/PrismManageViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/PrismManageViewHolder.java new file mode 100644 index 0000000..255fe93 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/PrismManageViewHolder.java @@ -0,0 +1,22 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class PrismManageViewHolder extends RecyclerView.ViewHolder { + public final TextView tvName; + public final TextView tvType; + public final TextView tvConstant; + + public PrismManageViewHolder(@NonNull View itemView) { + super(itemView); + tvName = itemView.findViewById(R.id.tvName); + tvType = itemView.findViewById(R.id.tvType); + tvConstant = itemView.findViewById(R.id.tvConstant); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationAdjustItemViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationAdjustItemViewHolder.java new file mode 100644 index 0000000..1b25b39 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationAdjustItemViewHolder.java @@ -0,0 +1,24 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class StationAdjustItemViewHolder extends RecyclerView.ViewHolder { + public final TextView pointName; + public final TextView horAngle; + public final TextView verAngle; + public final TextView distance; + + public StationAdjustItemViewHolder(@NonNull View itemView) { + super(itemView); + pointName = itemView.findViewById(R.id.point_name); + horAngle = itemView.findViewById(R.id.hor_angle); + verAngle = itemView.findViewById(R.id.ver_angle); + distance = itemView.findViewById(R.id.distance); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationGroupItemViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationGroupItemViewHolder.java new file mode 100644 index 0000000..f504ac0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationGroupItemViewHolder.java @@ -0,0 +1,46 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.R; + +public class StationGroupItemViewHolder extends RecyclerView.ViewHolder { + public final TextView title; + public final View pick; + public final View switchView; + + public StationGroupItemViewHolder(@NonNull @NotNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.groupName); + pick = itemView.findViewById(R.id.pick_station_point); + switchView = itemView.findViewById(R.id.switch_station_point); + } + + public static void update(StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder, + StationDetailItem item, + boolean adjustable, + IUIBuilderDelegate builderDelegate) { + surveyorStationSetupGroupParentViewHolder.title.setText(item.getName()); + //判断是否需要un enable添加按钮 + if (!adjustable) { + surveyorStationSetupGroupParentViewHolder.pick.setVisibility(View.GONE); + surveyorStationSetupGroupParentViewHolder.switchView.setVisibility(View.GONE); + } else { + if (builderDelegate != null) { + builderDelegate.build(item.getType(), surveyorStationSetupGroupParentViewHolder); + } + } + } + + public interface IUIBuilderDelegate { + void build(String itemType, StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataAloneDistanceViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataAloneDistanceViewHolder.java new file mode 100644 index 0000000..2b3524a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataAloneDistanceViewHolder.java @@ -0,0 +1,243 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.content.Context; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class SurveyorDataAloneDistanceViewHolder extends RecyclerView.ViewHolder { + private final Context context; + private final TextView leftLabel;//平距或斜距 + + private final TextView pointName; + private final TextView heightValue; + private final TextView prismValue; + + private final List distanceViews; + private final TextView tvFirstRound1, tvFirstRound2, tvFirstRound3, tvFirstRound4; + private final TextView tvSecondRound1, tvSecondRound2, tvSecondRound3, tvSecondRound4; + + private final TextView tvFirstRoundAverageDistance, tvSecondRoundAverageDistance;//第一,第二测回中值 + private final TextView tvFirstRound2D, tvSecondRound2D;//第一,第二测回2D + + private final View selectMask;//黄框 + + private final int ROUND_NUM = 2; + private final int EVERY_ROUND_NUM = 4; + + private final List realDistanceValues = new ArrayList<>(); + + public SurveyorDataAloneDistanceViewHolder(Context context, @NonNull @NotNull View itemView) { + super(itemView); + this.context = context; + + pointName = itemView.findViewById(R.id.pointName); + heightValue = itemView.findViewById(R.id.height_value); + prismValue = itemView.findViewById(R.id.prism_value); + + leftLabel = itemView.findViewById(R.id.left_label); + + tvFirstRound1 = itemView.findViewById(R.id.tvFirstRound1); + tvFirstRound2 = itemView.findViewById(R.id.tvFirstRound2); + tvFirstRound3 = itemView.findViewById(R.id.tvFirstRound3); + tvFirstRound4 = itemView.findViewById(R.id.tvFirstRound4); + tvSecondRound1 = itemView.findViewById(R.id.tvSecondRound1); + tvSecondRound2 = itemView.findViewById(R.id.tvSecondRound2); + tvSecondRound3 = itemView.findViewById(R.id.tvSecondRound3); + tvSecondRound4 = itemView.findViewById(R.id.tvSecondRound4); + + distanceViews = new ArrayList<>(); + distanceViews.add(tvFirstRound1); + distanceViews.add(tvFirstRound2); + distanceViews.add(tvFirstRound3); + distanceViews.add(tvFirstRound4); + distanceViews.add(tvSecondRound1); + distanceViews.add(tvSecondRound2); + distanceViews.add(tvSecondRound3); + distanceViews.add(tvSecondRound4); + + + tvFirstRoundAverageDistance = itemView.findViewById(R.id.tvFirstRoundAverageDistance); + tvSecondRoundAverageDistance = itemView.findViewById(R.id.tvSecondRoundAverageDistance); + tvFirstRound2D = itemView.findViewById(R.id.tvFirstRound2D); + tvSecondRound2D = itemView.findViewById(R.id.tvSecondRound2D); + + selectMask = itemView.findViewById(R.id.mask); + } + + public void setup(int itemIndex, + String stationId, + boolean showSlopDistance, + CachedDataAloneDistance cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData) { + if (showSlopDistance) { + leftLabel.setText(R.string.distance_slope); + } else { + leftLabel.setText(R.string.distance_horizontal); + } + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + int currentSurveyorIndex = surveyorData.currentIndex(); + //设置当前测量状态标识 + if (currentSurveyorIndex == itemIndex) { + selectMask.setVisibility(View.VISIBLE); + } else { + selectMask.setVisibility(View.GONE); + } + + //初始化 + initDefault(); + + //设置值 + pointName.setText(cachedData.pointName(currentCycleIndex, itemIndex)); + heightValue.setText(cachedData.getPrismHeight(currentCycleIndex, itemIndex)); + prismValue.setText(cachedData.getPrismTypeName(currentCycleIndex, itemIndex)); + + //先清空下realDistanceValues保证数据不错乱,注意位置在前面 + clearRealDistanceValues(); + List distanceDatas = getDistanceDataFromCacheData(cachedData, stationId, currentCycleIndex, itemIndex); + setDistanceViewData(distanceDatas, currentSurveyorIndex == itemIndex); + + //设置中值和2d + if (!realDistanceValues.isEmpty()) { + int distanceSize = realDistanceValues.size(); + int hanNum = distanceSize / EVERY_ROUND_NUM; + if (hanNum >= 1) { + //有可以显示的中值 + if (hanNum == ROUND_NUM) { + //当满足两测回都可以显示中值和2d的时候 + setFirstRound2DAndAverageDistance(); + setSecondRound2DAndAverageDistance(); + } else { + //当满足第一测回可以显示中值和2d的时候 + setFirstRound2DAndAverageDistance(); + } + } + } + + } + + /** + * 从缓存数据中读取距离数据 + * + * @param cachedData + * @param stationId + * @param currentCycleIndex + * @param itemIndex + * @return + */ + private List getDistanceDataFromCacheData(CachedDataAloneDistance cachedData, String stationId, int currentCycleIndex, int itemIndex) { + List distanceValues = null; + String pointId = cachedData.pointId(currentCycleIndex, itemIndex); + String recordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + AloneDistanceRecord aloneDistanceRecord = cachedData.getAloneDistanceRecord(recordId); + if (aloneDistanceRecord != null) { + distanceValues = aloneDistanceRecord.distanceValues; + } + return distanceValues; + } + + private void setFirstRound2DAndAverageDistance() { + List doubles1 = realDistanceValues.subList(0, EVERY_ROUND_NUM); + Double averageFirstRound = Tools.calculateCollectionDoubleAverage(doubles1); + Double maxSubMinFirstRound = Tools.calculateCollectionMaxSubMin(doubles1); + setAverageDistanceText(tvFirstRoundAverageDistance, averageFirstRound); + set2DText(tvFirstRound2D, maxSubMinFirstRound); + } + + private void setSecondRound2DAndAverageDistance() { + List doubles2 = realDistanceValues.subList(EVERY_ROUND_NUM, realDistanceValues.size()); + Double averageSecondRound = Tools.calculateCollectionDoubleAverage(doubles2); + Double maxSubMinSecondRound = Tools.calculateCollectionMaxSubMin(doubles2); + setAverageDistanceText(tvSecondRoundAverageDistance, averageSecondRound); + set2DText(tvSecondRound2D, maxSubMinSecondRound); + } + + + private void setTextColor(TextView tv, int value) { + tv.setTextColor(context.getResources().getColor(value)); + } + + private void setDistance(TextView tv, double distance) { + String distanceS; + if (distance == 0) { + distanceS = ORIGINAL_VALUE; + } else { + distanceS = Util.formatDouble2String(distance, SettingValueUtil.getLengthDecimalPoint()); + } + tv.setText(distanceS); + } + + private void set2DText(TextView tv, double value) { + tv.setText(String.format("%smm", Util.formatDouble2String(value * 1000, 1))); + } + + private void setAverageDistanceText(TextView tv, double value) { + tv.setText(Util.formatDouble2String(value, SettingValueUtil.getLengthDecimalPoint())); + } + + /** + * 初始化 + */ + private void initDefault() { + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + + initDefaultDistanceViewsData(); + + tvFirstRoundAverageDistance.setText(ORIGINAL_VALUE); + tvSecondRoundAverageDistance.setText(ORIGINAL_VALUE); + + tvFirstRound2D.setText(ORIGINAL_VALUE); + tvSecondRound2D.setText(ORIGINAL_VALUE); + } + + private void initDefaultDistanceViewsData() { + for (TextView textView : distanceViews) { + setDistance(textView, 0); + setTextColor(textView, R.color.value_1_normal); + } + } + + /** + * 设置view的数据 + * + * @param aloneDistanceValues + * @param isSelected + */ + private void setDistanceViewData(List aloneDistanceValues, boolean isSelected) { + if (aloneDistanceValues == null) return; + for (int i = 0; i < aloneDistanceValues.size(); i++) { + Double aDouble = aloneDistanceValues.get(i); + TextView textView = distanceViews.get(i); + setDistance(textView, aDouble); + setTextColor(textView, isSelected ? R.color.value_1_selected : R.color.value_1_normal); + //存一下 + realDistanceValues.add(aDouble); + } + } + + private void clearRealDistanceValues() { + realDistanceValues.clear(); + } + + + private static final String ORIGINAL_VALUE = "-"; +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolder.java new file mode 100644 index 0000000..744c8f8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolder.java @@ -0,0 +1,408 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.content.Context; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.DataCategory; +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.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.util.IdUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import org.jetbrains.annotations.NotNull; + +public class SurveyorDataViewHolder extends RecyclerView.ViewHolder { + private final Context context; + private final TextView leftLabel; + private final TextView rightLabel; + + public final TextView pointName; + public final TextView heightValue; + public final TextView prismValue; + + public final TextView leftAngleHor1; + public final TextView leftAngleHor2; + public final TextView leftAngleVer1; + public final TextView leftAngleVer2; + public final TextView leftDistance1; + public final TextView leftDistance2; + + public final TextView rightAngleHor1; + public final TextView rightAngleHor2; + public final TextView rightAngleVer1; + public final TextView rightAngleVer2; + public final TextView rightDistance1; + public final TextView rightDistance2; + + public final TextView averageHorAngle; + public final TextView averageVerAngle; + public final TextView averageDistance; + + public final View selectMask; + + public final TextView _2c; + public final TextView _i; + public final TextView _2d; + + public final TextView distanceTitle; + private final View itemView; + + public SurveyorDataViewHolder(Context context, @NonNull @NotNull View itemView) { + super(itemView); + this.context = context; + leftLabel = itemView.findViewById(R.id.left_label); + rightLabel = itemView.findViewById(R.id.right_label); + + pointName = itemView.findViewById(R.id.pointName); + heightValue = itemView.findViewById(R.id.height_value); + prismValue = itemView.findViewById(R.id.prism_value); + + leftAngleHor1 = itemView.findViewById(R.id.left_angle_hor_1); + leftAngleHor2 = itemView.findViewById(R.id.left_angle_hor_2); + leftAngleVer1 = itemView.findViewById(R.id.left_angle_ver_1); + leftAngleVer2 = itemView.findViewById(R.id.left_angle_ver_2); + leftDistance1 = itemView.findViewById(R.id.left_distance_1); + leftDistance2 = itemView.findViewById(R.id.left_distance_2); + + rightAngleHor1 = itemView.findViewById(R.id.right_angle_hor_1); + rightAngleHor2 = itemView.findViewById(R.id.right_angle_hor_2); + rightAngleVer1 = itemView.findViewById(R.id.right_angle_ver_1); + rightAngleVer2 = itemView.findViewById(R.id.right_angle_ver_2); + rightDistance1 = itemView.findViewById(R.id.right_distance_1); + rightDistance2 = itemView.findViewById(R.id.right_distance_2); + + averageHorAngle = itemView.findViewById(R.id.average_angle_hor); + averageVerAngle = itemView.findViewById(R.id.average_angle_ver); + averageDistance = itemView.findViewById(R.id.average_distance); + + selectMask = itemView.findViewById(R.id.mask); + + _2c = itemView.findViewById(R.id.value_2c); + _i = itemView.findViewById(R.id.value_i); + _2d = itemView.findViewById(R.id.value_2d); + + distanceTitle = itemView.findViewById(R.id.distance_title); + this.itemView = itemView; + } + + public void setup(int itemIndex, + String stationId, + boolean showSlopDistance, + ICachedData cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData) { + if (showSlopDistance) { + distanceTitle.setText(R.string.distance_slope); + } else { + distanceTitle.setText(R.string.distance_horizontal); + } + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + int currentSurveyorIndex = surveyorData.currentIndex(); + //设置当前测量状态标识 + if (currentSurveyorIndex == itemIndex) { + //当前非跳过点背景黄边白色 + selectMask.setBackground(Tools.getDrawable(R.drawable.select_mask)); + } else { + if (cachedData.isPointAbandon(currentCycleIndex, itemIndex)) { + selectMask.setBackground(Tools.getDrawable(R.drawable.bg_gray_3)); + } else { + selectMask.setBackgroundColor(Tools.getColor(R.color.white)); + } + } + + //初始化 + setValue(TYPE_LEFT1, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_LEFT2, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_RIGHT1, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_RIGHT2, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + setTextColor(TYPE_LEFT1, R.color.value_1_normal); + setTextColor(TYPE_LEFT2, R.color.value_2_normal); + rightLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + setTextColor(TYPE_RIGHT1, R.color.value_1_normal); + setTextColor(TYPE_RIGHT2, R.color.value_2_normal); + + averageHorAngle.setText(ORIGINAL_VALUE); + averageVerAngle.setText(ORIGINAL_VALUE); + averageDistance.setText(ORIGINAL_VALUE); + + _2c.setText(ORIGINAL_VALUE); + _i.setText(ORIGINAL_VALUE); + _2d.setText(ORIGINAL_VALUE); + + boolean aloneDistance = cachedData.isAloneDistance(currentCycleIndex, itemIndex); + + //如果当前正在测量,使用缓存数据设置相应信息 + LeftOrRight surveyorState = surveyorData.leftOrRight(); + if (currentSurveyorIndex == itemIndex) { + if (surveyorState == LeftOrRight.left) { + if (surveyorData.hasSurveyor1()) { + setValue(aloneDistance, TYPE_LEFT1, surveyorData.getAngleHor1(), surveyorData.getAngleVer1(), surveyorData.getDistance1()); + } + if (surveyorData.hasSurveyor2()) { + setValue(aloneDistance, TYPE_LEFT2, surveyorData.getAngleHor2(), surveyorData.getAngleVer2(), surveyorData.getDistance2()); + } + //设置颜色 + setTextColor(TYPE_LEFT1, R.color.value_1_selected); + setTextColor(TYPE_LEFT2, R.color.value_2_selected); + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_selected)); + } else if (surveyorState == LeftOrRight.right) { + if (surveyorData.hasSurveyor1()) { + setValue(aloneDistance, TYPE_RIGHT1, surveyorData.getAngleHor1(), surveyorData.getAngleVer1(), surveyorData.getDistance1()); + } + if (surveyorData.hasSurveyor2()) { + setValue(aloneDistance, TYPE_RIGHT2, surveyorData.getAngleHor2(), surveyorData.getAngleVer2(), surveyorData.getDistance2()); + } + //设置颜色 + setTextColor(TYPE_RIGHT1, R.color.value_1_selected); + setTextColor(TYPE_RIGHT2, R.color.value_2_selected); + rightLabel.setTextColor(context.getResources().getColor(R.color.value_1_selected)); + } + } + + //根据测量次数,控制数据显示 + setValue2Visibility(surveyorData.surveyorCount() > 1); + + pointName.setText(cachedData.pointName(currentCycleIndex, itemIndex)); + heightValue.setText(cachedData.getPrismHeight(currentCycleIndex, itemIndex)); + prismValue.setText(cachedData.getPrismTypeName(currentCycleIndex, itemIndex)); + + //重新监听observe---但是根据当前测量状态,需要排除一些数据监听 + boolean skipLeft1 = false, skipLeft2 = false, skipRight1 = false, skipRight2 = false; + //根据内存缓存排除 + if (currentSurveyorIndex == itemIndex) { + if (surveyorState == LeftOrRight.left) { + if (surveyorData.hasSurveyor1()) { + skipLeft1 = true; + } + if (surveyorData.hasSurveyor2() || surveyorData.surveyorCount() == 1) { + skipLeft2 = true; + } + } else if (surveyorState == LeftOrRight.right) { + if (surveyorData.hasSurveyor1()) { + skipRight1 = true; + } + if (surveyorData.hasSurveyor2() || surveyorData.surveyorCount() == 1) { + skipRight2 = true; + } + } + } + + String pointId = cachedData.pointId(currentCycleIndex, itemIndex); + String leftRecordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + if (!skipLeft1) { + DataCategory dataCategory = cachedData.valueState(leftRecordId, 0); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_LEFT1, + cachedData.angleHor1(leftRecordId), + cachedData.angleVer1(leftRecordId), + cachedData.distance1(leftRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_LEFT1, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_LEFT1, R.color.value_resurveyed); + } + } + if (!skipLeft2) { + DataCategory dataCategory = cachedData.valueState(leftRecordId, 1); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_LEFT2, + cachedData.angleHor2(leftRecordId), + cachedData.angleVer2(leftRecordId), + cachedData.distance2(leftRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_LEFT2, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_LEFT2, R.color.value_resurveyed); + } + } + String rightRecordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.right); + if (!skipRight1) { + DataCategory dataCategory = cachedData.valueState(rightRecordId, 0); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_RIGHT1, + cachedData.angleHor1(rightRecordId), + cachedData.angleVer1(rightRecordId), + cachedData.distance1(rightRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_RIGHT1, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_RIGHT1, R.color.value_resurveyed); + } + } + if (!skipRight2) { + DataCategory dataCategory = cachedData.valueState(rightRecordId, 1); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_RIGHT2, + cachedData.angleHor2(rightRecordId), + cachedData.angleVer2(rightRecordId), + cachedData.distance2(rightRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_RIGHT2, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_RIGHT2, R.color.value_resurveyed); + } + } + + + //均值(中值) + int surveyorCount = surveyorData.surveyorCount(); + CacheResult horAngleLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.horAngle, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + + if (horAngleLeftAndRightAverageValue.validate) { + double radian = RadianMethod.formatRadian(horAngleLeftAndRightAverageValue.value); + averageHorAngle.setText(RadianMethod.dmsStringOf(radian)); + } else { + averageHorAngle.setText(ORIGINAL_VALUE); + } + + + CacheResult verAngleLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.verAngle, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + if (verAngleLeftAndRightAverageValue.validate) {//显示天顶距 + averageVerAngle.setText(RadianMethod.dmsStringOf(Math.PI / 2 - verAngleLeftAndRightAverageValue.value)); + } else { + averageVerAngle.setText(ORIGINAL_VALUE); + } + + CacheResult distanceLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.distance, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + if (aloneDistance) { + averageDistance.setText(ORIGINAL_VALUE); + } else { + if (distanceLeftAndRightAverageValue.validate) { + averageDistance.setText(Util.formatDouble2String(distanceLeftAndRightAverageValue.value, + SettingValueUtil.getLengthDecimalPoint())); + } else { + averageDistance.setText(ORIGINAL_VALUE); + } + } + + //设置2c、i、2d + CacheResult value2C = ValueOf2cMethod.valueOf2C(SdAngleValueType.horAngle, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (value2C.validate && horAngleLeftAndRightAverageValue.validate) { + _2c.setText(String.format("%s″", Util.formatDouble2String(value2C.value, 1))); + } else { + _2c.setText(ORIGINAL_VALUE); + } + CacheResult valueI = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (valueI.validate && verAngleLeftAndRightAverageValue.validate) { + _i.setText(String.format("%s″", Util.formatDouble2String(valueI.value, 1))); + } else { + _i.setText(ORIGINAL_VALUE); + } + + CacheResult value2D = ValueOf2cMethod.valueOf2C(SdAngleValueType.distance, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (aloneDistance) { + _2d.setText(ORIGINAL_VALUE); + } else { + if (value2D.validate && distanceLeftAndRightAverageValue.validate) { + _2d.setText(String.format("%smm", Util.formatDouble2String(value2D.value, 1))); + } else { + _2d.setText(ORIGINAL_VALUE); + } + } + + } + + private void setTextColor(int type, int value) { + angleHor(type).setTextColor(context.getResources().getColor(value)); + angleVer(type).setTextColor(context.getResources().getColor(value)); + distance(type).setTextColor(context.getResources().getColor(value)); + } + + private void setValue(boolean aloneDistance, int type, double angleHor, double angleVer, double distance) { + //判断是否测水平角 + String angleVerS = RadianMethod.dmsStringOf(angleVer); + String distanceS = ORIGINAL_VALUE; + if (!aloneDistance) { + distanceS = Util.formatDouble2String(distance, + SettingValueUtil.getLengthDecimalPoint()); + } + setValue(type, + RadianMethod.dmsStringOf(angleHor), + angleVerS, + distanceS); + } + + private void setValue(int type, String angleHor, String angleVer, String distance) { + angleHor(type).setText(angleHor); + angleVer(type).setText(angleVer); + distance(type).setText(distance); + } + + private void setValue2Visibility(boolean visibility) { + leftAngleHor2.setVisibility(visibility ? View.VISIBLE : View.GONE); + leftAngleVer2.setVisibility(visibility ? View.VISIBLE : View.GONE); + leftDistance2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightAngleHor2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightAngleVer2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightDistance2.setVisibility(visibility ? View.VISIBLE : View.GONE); + } + + private TextView angleHor(int type) { + if (TYPE_LEFT1 == type) { + return leftAngleHor1; + } else if (TYPE_LEFT2 == type) { + return leftAngleHor2; + } else if (TYPE_RIGHT1 == type) { + return rightAngleHor1; + } + return rightAngleHor2; + } + + private TextView angleVer(int type) { + if (TYPE_LEFT1 == type) { + return leftAngleVer1; + } else if (TYPE_LEFT2 == type) { + return leftAngleVer2; + } else if (TYPE_RIGHT1 == type) { + return rightAngleVer1; + } + return rightAngleVer2; + } + + + private TextView distance(int type) { + if (TYPE_LEFT1 == type) { + return leftDistance1; + } else if (TYPE_LEFT2 == type) { + return leftDistance2; + } else if (TYPE_RIGHT1 == type) { + return rightDistance1; + } + return rightDistance2; + } + + private static final int TYPE_LEFT1 = 1; + private static final int TYPE_LEFT2 = 2; + private static final int TYPE_RIGHT1 = 3; + private static final int TYPE_RIGHT2 = 4; + private static final String ORIGINAL_VALUE = "-"; + private static final String SKIP_VALUE = "*"; +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolderHeightTraverse.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolderHeightTraverse.java new file mode 100644 index 0000000..6a989bf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolderHeightTraverse.java @@ -0,0 +1,366 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.content.Context; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.DataCategory; +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.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.util.IdUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import org.jetbrains.annotations.NotNull; + +public class SurveyorDataViewHolderHeightTraverse extends RecyclerView.ViewHolder { + private final Context context; + private final TextView leftLabel; + private final TextView rightLabel; + + public final TextView pointName; + public final TextView heightValue; + public final TextView prismValue; + + public final TextView leftAngleVer1; + public final TextView leftAngleVer2; + public final TextView leftDistance1; + public final TextView leftDistance2; + + public final TextView rightAngleVer1; + public final TextView rightAngleVer2; + public final TextView rightDistance1; + public final TextView rightDistance2; + + public final TextView averageVerAngle; + public final TextView averageDistance; + + public final View selectMask; + + public final TextView _i; + public final TextView _2d; + + public final TextView distanceTitle; + public final TextView tvCycleNum; + private final View itemView; + + public SurveyorDataViewHolderHeightTraverse(Context context, @NonNull @NotNull View itemView) { + super(itemView); + this.context = context; + leftLabel = itemView.findViewById(R.id.left_label); + rightLabel = itemView.findViewById(R.id.right_label); + + pointName = itemView.findViewById(R.id.pointName); + heightValue = itemView.findViewById(R.id.height_value); + prismValue = itemView.findViewById(R.id.prism_value); + + leftAngleVer1 = itemView.findViewById(R.id.left_angle_ver_1); + leftAngleVer2 = itemView.findViewById(R.id.left_angle_ver_2); + leftDistance1 = itemView.findViewById(R.id.left_distance_1); + leftDistance2 = itemView.findViewById(R.id.left_distance_2); + + rightAngleVer1 = itemView.findViewById(R.id.right_angle_ver_1); + rightAngleVer2 = itemView.findViewById(R.id.right_angle_ver_2); + rightDistance1 = itemView.findViewById(R.id.right_distance_1); + rightDistance2 = itemView.findViewById(R.id.right_distance_2); + + averageVerAngle = itemView.findViewById(R.id.average_angle_ver); + averageDistance = itemView.findViewById(R.id.average_distance); + + selectMask = itemView.findViewById(R.id.mask); + + _i = itemView.findViewById(R.id.value_i); + _2d = itemView.findViewById(R.id.value_2d); + + distanceTitle = itemView.findViewById(R.id.distance_title); + tvCycleNum = itemView.findViewById(R.id.tvCycleNum); + + this.itemView = itemView; + } + + public void setup(int itemIndex, + String stationId, + boolean showSlopDistance, + ICachedData cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData) { + if (showSlopDistance) { + distanceTitle.setText(R.string.distance_slope); + } else { + distanceTitle.setText(R.string.distance_horizontal); + } +// int currentCycleIndex = cycleRecorder.currentCycleIndex(); + int currentCycleIndex = itemIndex; + int currentSurveyorIndex = surveyorData.currentIndex(); + //设置当前测量状态标识 + if (currentSurveyorIndex == itemIndex) { + //当前非跳过点背景黄边白色 + selectMask.setBackground(Tools.getDrawable(R.drawable.select_mask)); + } else { + if (cachedData.isPointAbandon(currentCycleIndex, itemIndex)) { + selectMask.setBackground(Tools.getDrawable(R.drawable.bg_gray_3)); + } else { + selectMask.setBackgroundColor(Tools.getColor(R.color.white)); + } + } + tvCycleNum.setText(Tools.getString(R.string.test_n_cycle, (itemIndex + 1))); + + //初始化 + setValue(TYPE_LEFT1, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_LEFT2, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_RIGHT1, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_RIGHT2, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + setTextColor(TYPE_LEFT1, R.color.value_1_normal); + setTextColor(TYPE_LEFT2, R.color.value_2_normal); + rightLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + setTextColor(TYPE_RIGHT1, R.color.value_1_normal); + setTextColor(TYPE_RIGHT2, R.color.value_2_normal); + + averageVerAngle.setText(ORIGINAL_VALUE); + averageDistance.setText(ORIGINAL_VALUE); + + _i.setText(ORIGINAL_VALUE); + _2d.setText(ORIGINAL_VALUE); + + boolean aloneDistance = cachedData.isAloneDistance(currentCycleIndex, itemIndex); + + //如果当前正在测量,使用缓存数据设置相应信息 + LeftOrRight surveyorState = surveyorData.leftOrRight(); + if (currentSurveyorIndex == itemIndex) { + if (surveyorState == LeftOrRight.left) { + if (surveyorData.hasSurveyor1()) { + setValue(aloneDistance, TYPE_LEFT1, surveyorData.getAngleHor1(), surveyorData.getAngleVer1(), surveyorData.getDistance1()); + } + if (surveyorData.hasSurveyor2()) { + setValue(aloneDistance, TYPE_LEFT2, surveyorData.getAngleHor2(), surveyorData.getAngleVer2(), surveyorData.getDistance2()); + } + //设置颜色 + setTextColor(TYPE_LEFT1, R.color.value_1_selected); + setTextColor(TYPE_LEFT2, R.color.value_2_selected); + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_selected)); + } else if (surveyorState == LeftOrRight.right) { + if (surveyorData.hasSurveyor1()) { + setValue(aloneDistance, TYPE_RIGHT1, surveyorData.getAngleHor1(), surveyorData.getAngleVer1(), surveyorData.getDistance1()); + } + if (surveyorData.hasSurveyor2()) { + setValue(aloneDistance, TYPE_RIGHT2, surveyorData.getAngleHor2(), surveyorData.getAngleVer2(), surveyorData.getDistance2()); + } + //设置颜色 + setTextColor(TYPE_RIGHT1, R.color.value_1_selected); + setTextColor(TYPE_RIGHT2, R.color.value_2_selected); + rightLabel.setTextColor(context.getResources().getColor(R.color.value_1_selected)); + } + } + + //根据测量次数,控制数据显示 + setValue2Visibility(surveyorData.surveyorCount() > 1); + + pointName.setText(cachedData.pointName(currentCycleIndex, itemIndex)); + heightValue.setText(cachedData.getPrismHeight(currentCycleIndex, itemIndex)); + prismValue.setText(cachedData.getPrismTypeName(currentCycleIndex, itemIndex)); + + //重新监听observe---但是根据当前测量状态,需要排除一些数据监听 + boolean skipLeft1 = false, skipLeft2 = false, skipRight1 = false, skipRight2 = false; + //根据内存缓存排除 + if (currentSurveyorIndex == itemIndex) { + if (surveyorState == LeftOrRight.left) { + if (surveyorData.hasSurveyor1()) { + skipLeft1 = true; + } + if (surveyorData.hasSurveyor2() || surveyorData.surveyorCount() == 1) { + skipLeft2 = true; + } + } else if (surveyorState == LeftOrRight.right) { + if (surveyorData.hasSurveyor1()) { + skipRight1 = true; + } + if (surveyorData.hasSurveyor2() || surveyorData.surveyorCount() == 1) { + skipRight2 = true; + } + } + } + + String pointId = cachedData.pointId(currentCycleIndex, itemIndex); + String leftRecordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + if (!skipLeft1) { + DataCategory dataCategory = cachedData.valueState(leftRecordId, 0); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_LEFT1, + cachedData.angleHor1(leftRecordId), + cachedData.angleVer1(leftRecordId), + cachedData.distance1(leftRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_LEFT1, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_LEFT1, R.color.value_resurveyed); + } + } + if (!skipLeft2) { + DataCategory dataCategory = cachedData.valueState(leftRecordId, 1); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_LEFT2, + cachedData.angleHor2(leftRecordId), + cachedData.angleVer2(leftRecordId), + cachedData.distance2(leftRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_LEFT2, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_LEFT2, R.color.value_resurveyed); + } + } + String rightRecordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.right); + if (!skipRight1) { + DataCategory dataCategory = cachedData.valueState(rightRecordId, 0); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_RIGHT1, + cachedData.angleHor1(rightRecordId), + cachedData.angleVer1(rightRecordId), + cachedData.distance1(rightRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_RIGHT1, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_RIGHT1, R.color.value_resurveyed); + } + } + if (!skipRight2) { + DataCategory dataCategory = cachedData.valueState(rightRecordId, 1); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_RIGHT2, + cachedData.angleHor2(rightRecordId), + cachedData.angleVer2(rightRecordId), + cachedData.distance2(rightRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_RIGHT2, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_RIGHT2, R.color.value_resurveyed); + } + } + + + //均值(中值) + int surveyorCount = surveyorData.surveyorCount(); + + CacheResult verAngleLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.verAngle, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + if (verAngleLeftAndRightAverageValue.validate) {//显示天顶距 + averageVerAngle.setText(RadianMethod.dmsStringOf(Math.PI / 2 - verAngleLeftAndRightAverageValue.value)); + } else { + averageVerAngle.setText(ORIGINAL_VALUE); + } + + CacheResult distanceLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.distance, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + if (aloneDistance) { + averageDistance.setText(ORIGINAL_VALUE); + } else { + if (distanceLeftAndRightAverageValue.validate) { + averageDistance.setText(Util.formatDouble2String(distanceLeftAndRightAverageValue.value, + SettingValueUtil.getLengthDecimalPoint())); + } else { + averageDistance.setText(ORIGINAL_VALUE); + } + } + + //设置2c、i、2d + CacheResult valueI = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (valueI.validate && verAngleLeftAndRightAverageValue.validate) { + _i.setText(String.format("%s″", Util.formatDouble2String(valueI.value, 1))); + } else { + _i.setText(ORIGINAL_VALUE); + } + + CacheResult value2D = ValueOf2cMethod.valueOf2C(SdAngleValueType.distance, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (aloneDistance) { + _2d.setText(ORIGINAL_VALUE); + } else { + if (value2D.validate && distanceLeftAndRightAverageValue.validate) { + _2d.setText(String.format("%smm", Util.formatDouble2String(value2D.value, 1))); + } else { + _2d.setText(ORIGINAL_VALUE); + } + } + + } + + private void setTextColor(int type, int value) { + angleVer(type).setTextColor(context.getResources().getColor(value)); + distance(type).setTextColor(context.getResources().getColor(value)); + } + + private void setValue(boolean aloneDistance, int type, double angleHor, double angleVer, double distance) { + //判断是否测水平角 + String angleVerS = RadianMethod.dmsStringOf(angleVer); + String distanceS = ORIGINAL_VALUE; + if (!aloneDistance) { + distanceS = Util.formatDouble2String(distance, + SettingValueUtil.getLengthDecimalPoint()); + } + setValue(type, + RadianMethod.dmsStringOf(angleHor), + angleVerS, + distanceS); + } + + private void setValue(int type, String angleHor, String angleVer, String distance) { + angleVer(type).setText(angleVer); + distance(type).setText(distance); + } + + private void setValue2Visibility(boolean visibility) { + leftAngleVer2.setVisibility(visibility ? View.VISIBLE : View.GONE); + leftDistance2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightAngleVer2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightDistance2.setVisibility(visibility ? View.VISIBLE : View.GONE); + } + + private TextView angleVer(int type) { + if (TYPE_LEFT1 == type) { + return leftAngleVer1; + } else if (TYPE_LEFT2 == type) { + return leftAngleVer2; + } else if (TYPE_RIGHT1 == type) { + return rightAngleVer1; + } + return rightAngleVer2; + } + + + private TextView distance(int type) { + if (TYPE_LEFT1 == type) { + return leftDistance1; + } else if (TYPE_LEFT2 == type) { + return leftDistance2; + } else if (TYPE_RIGHT1 == type) { + return rightDistance1; + } + return rightDistance2; + } + + private static final int TYPE_LEFT1 = 1; + private static final int TYPE_LEFT2 = 2; + private static final int TYPE_RIGHT1 = 3; + private static final int TYPE_RIGHT2 = 4; + private static final String ORIGINAL_VALUE = "-"; + private static final String SKIP_VALUE = "*"; +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/TextSelectableViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/TextSelectableViewHolder.java new file mode 100644 index 0000000..cfd15ae --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/TextSelectableViewHolder.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class TextSelectableViewHolder extends RecyclerView.ViewHolder { + public final ImageView status; + public final TextView name; + + public TextSelectableViewHolder(@NonNull View itemView) { + super(itemView); + status = itemView.findViewById(R.id.status); + name = itemView.findViewById(R.id.text); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/TitleWithSubtitleViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/TitleWithSubtitleViewHolder.java new file mode 100644 index 0000000..14d7e98 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/TitleWithSubtitleViewHolder.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class TitleWithSubtitleViewHolder extends RecyclerView.ViewHolder { + public final TextView title; + public final TextView subTitle; + + public TitleWithSubtitleViewHolder(@NonNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.title); + subTitle = itemView.findViewById(R.id.sub_title); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/CommentListTextView.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/CommentListTextView.java new file mode 100644 index 0000000..5b873e3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/CommentListTextView.java @@ -0,0 +1,380 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.graphics.Color; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.text.style.ForegroundColorSpan; +import android.util.AttributeSet; +import android.view.View; + +import androidx.appcompat.widget.AppCompatTextView; + +import java.util.List; + +/** + * Created by lujianchao on 2017/1/19. + * + * @author lujianchao + */ + +public class CommentListTextView extends AppCompatTextView { + /** + * 所有评论数据 + */ + private List mInfos; + private onCommentListener mListener; + + /** + * 点击文字会触发两个回调,用这个变量控制屏蔽掉一个 + */ + private boolean isNickNameClick = false; + + + /** + * 最大显示行数,超过指定行数多一行显示为查看更多文本,可设置文本 + */ + private int mMaxlines = 6; + /** + * 当超过n行后,n+1行显示为这个文本; + */ + private String mMoreStr = "查看全部评论"; + /** + * 谁回复谁中回复字符串,可以变成别的 + */ + private String mTalkStr = "回复"; + /** + * 人名称颜色 + */ + private int mNameColor = Color.parseColor("#00376a"); + private int mCommentColor = Color.parseColor("#2d2d2d"); + private int mTalkColor = Color.parseColor("#2d2d2d"); + + public int getTalkColor() { + return mTalkColor; + } + + public CommentListTextView setTalkColor(final int mTalkColor) { + this.mTalkColor = mTalkColor; + return this; + } + + public int getMaxlines() { + return mMaxlines; + } + + public CommentListTextView setMaxlines(final int mMaxlines) { + this.mMaxlines = mMaxlines; + return this; + } + + public String getMoreStr() { + return mMoreStr; + } + + public CommentListTextView setMoreStr(final String mMoreStr) { + this.mMoreStr = mMoreStr; + return this; + } + + public String getTalkStr() { + return mTalkStr; + } + + public CommentListTextView setTalkStr(final String mTalkStr) { + this.mTalkStr = mTalkStr; + return this; + } + + public int getNameColor() { + return mNameColor; + } + + public CommentListTextView setNameColor(final int mNameColor) { + this.mNameColor = mNameColor; + return this; + } + + public int getCommentColor() { + return mCommentColor; + } + + public CommentListTextView setCommentColor(final int mCommentColor) { + this.mCommentColor = mCommentColor; + return this; + } + + public CommentListTextView(final Context context) { + super(context); + } + + + public CommentListTextView(final Context context, final AttributeSet attrs) { + super(context, attrs); + } + + public CommentListTextView setonCommentListener(final onCommentListener mListener) { + this.mListener = mListener; + return this; + } + + public void setData(List mInfos) { + this.mInfos = mInfos; + /** + * textview必须设置,否则自定义点击事件没响应 + */ + setMovementMethod(LinkMovementMethod.getInstance()); + setHighlightColor(Color.TRANSPARENT); + setText(getCommentString()); + setOnClickListener(new OnClickListener() { + @Override + public void onClick(final View v) { + if (isNickNameClick) { + isNickNameClick = false; + return; + } + if (mListener != null) { + mListener.onOtherClick(); + } + } + }); + } + + private SpannableStringBuilder getCommentString() { + SpannableStringBuilder mStringBuilder = new SpannableStringBuilder(); + /** + * 对评论数据进行处理,默认超过mMaxlines条则第mMaxlines+1条显示查看全部 + */ + for (int mI = 0; mI < mInfos.size(); mI++) { + final CommentInfo mInfo = mInfos.get(mI); + /** + * 拼接成“张三:今天天气真好”这种形式,就是一行显示的文本。 + * 或者为张三 回复 李四:今天天气真好 + */ + String mS = null; + if (mInfo.getTonickname() == null || mInfo.getTonickname().equals("")) { + mS = mInfo.getNickname() + ":" + mInfo.getComment(); + } else { + mS = mInfo.getNickname() + mTalkStr + mInfo.getTonickname() + ":" + mInfo.getComment(); + } + /** + * 获得一个SpannableString文本的对象 + */ + SpannableString mString = new SpannableString(mS); + /** + * 我们假设“张三:今天天气真好”这句话中“张三:”这三个字符为橘红色字体并且添加点击事件,其余评论内容单独添加事件,一般业务需求是点击人名跳到个人主页或者聊天,点击评论内容是对这条评论进行评论。 + * 谁回复谁同理,就不写了 + */ + int start = 0; + int end = (mInfo.getNickname()).length(); + final int finalMI = mI; + /** + * 处理第一个人名 + * 设置文本从第0个开始到end位置具有点击事件,点击后回调,updateDrawState中设置文本从第0个到第end位置的文本前景色就是文字颜色为橘红色 + */ + mString.setSpan(new ClickableSpan() { + + @Override + public void updateDrawState(TextPaint ds) { + /** + * 是否有下划线 + */ + ds.setUnderlineText(false); + /** + * 橘红色字体 + */ + ds.setColor(mNameColor); + } + + @Override + public void onClick(final View widget) { + isNickNameClick = true; + if (mListener != null) { + mListener.onNickNameClick(finalMI, mInfos.get(finalMI)); + } + } + }, 0, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + mString.setSpan(new ForegroundColorSpan(mTalkColor), mInfo.getNickname().length(), mInfo.getNickname().length() + mTalkStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + /** + * 处理第二个人名 + */ + if (mInfo.getTonickname() != null && !mInfo.getTonickname().equals("")) { + start = mInfo.getNickname().length() + mTalkStr.length(); + end = mInfo.getNickname().length() + mTalkStr.length() + mInfo.getTonickname().length(); + mString.setSpan(new ClickableSpan() { + @Override + public void updateDrawState(TextPaint ds) { + /** + * 是否有下划线 + */ + ds.setUnderlineText(false); + /** + * 橘红色字体 + */ + ds.setColor(mNameColor); + } + + @Override + public void onClick(final View widget) { + isNickNameClick = true; + if (mListener != null) { + mListener.onToNickNameClick(finalMI, mInfos.get(finalMI)); + } + } + }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + + /** + * 设置文本从第end个开始到最后位置具有点击事件,点击后回调,updateDrawState中设置文本从第end个到最后的文本前景色就是文字颜色为黑色 + */ + + mString.setSpan(new ClickableSpan() { + + @Override + public void updateDrawState(TextPaint ds) { + /** + * 是否有下划线 + */ + ds.setUnderlineText(false); + /** + * 黑色字体 + */ + ds.setColor(mCommentColor); + } + + @Override + public void onClick(final View widget) { + isNickNameClick = true; + if (mListener != null) { + mListener.onCommentItemClick(finalMI, mInfos.get(finalMI)); + } + } + }, end, mS.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + /** + * 设置文本从第end个到最后的文本前景色就是文字颜色为黑色,即评论内容为黑色 + */ + + mStringBuilder.append(mString); + mStringBuilder.append("\r\n"); + if (mI == (mMaxlines - 1)) { + break; + } + } + if (mInfos.size() > mMaxlines) { + mStringBuilder.append("查看全部评论"); + } else { + /** + * 如果不大于3条,则删除最后的换行 + */ + mStringBuilder.delete(mStringBuilder.length() - 2, mStringBuilder.length()); + } + return mStringBuilder; + } + + + public interface onCommentListener { + /** + * 点击人名的回调 + * + * @param position 第几条评论 从0开始 + * @param mInfo 评论相关信息 + */ + void onNickNameClick(int position, CommentInfo mInfo); + + /** + * 点击被评论人名的回调 + * + * @param position 第几条评论 从0开始 + * @param mInfo 评论相关信息 + */ + void onToNickNameClick(int position, CommentInfo mInfo); + + /** + * 点击评论文本回调,主要针对对谁回复操作 + * + * @param position + * @param mInfo + */ + void onCommentItemClick(int position, CommentInfo mInfo); + + /** + * 点击非文字部分 + */ + void onOtherClick(); + } + + public static class CommentInfo { + /** + * 评论ID + */ + private int ID; + /** + * 评论人名称 + */ + private String nickname; + /** + * 评论内容 + */ + private String comment; + /** + * 被评论人名称 + */ + private String tonickname; + + @Override + public String toString() { + return "CommentInfo{" + + "ID=" + ID + + ", nickname='" + nickname + '\'' + + ", comment='" + comment + '\'' + + ", tonickname='" + tonickname + '\'' + + '}'; + } + + /** + * 下面可以继续写自定义需要的属性,需要传什么写什么 + */ + + + public int getID() { + return ID; + } + + public CommentInfo setID(final int mID) { + ID = mID; + return this; + } + + public String getNickname() { + return nickname; + } + + public CommentInfo setNickname(final String mNickname) { + nickname = mNickname; + return this; + } + + public String getComment() { + return comment; + } + + public CommentInfo setComment(final String mComment) { + comment = mComment; + return this; + } + + public String getTonickname() { + return tonickname; + } + + public CommentInfo setTonickname(final String mTonickname) { + tonickname = mTonickname; + return this; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/ItemWithEditText.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/ItemWithEditText.java new file mode 100644 index 0000000..22f114a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/ItemWithEditText.java @@ -0,0 +1,25 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public class ItemWithEditText extends TextItem { + public ItemWithEditText(@NonNull Context context) { + super(context); + } + + public ItemWithEditText(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public ItemWithEditText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public ItemWithEditText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/MyDrawerBuilder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/MyDrawerBuilder.java new file mode 100644 index 0000000..b3b6cc7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/MyDrawerBuilder.java @@ -0,0 +1,27 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.app.Activity; + +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; + +import com.mikepenz.materialdrawer.DrawerBuilder; + +public class MyDrawerBuilder extends DrawerBuilder { + + public MyDrawerBuilder(@NonNull Activity activity) { + super(activity); + } + + public MyDrawerBuilder withCustomLayout(@LayoutRes int resLayout) { + if (mActivity == null) { + throw new RuntimeException("please pass an activity first to use this call"); + } + + if (resLayout != -1) { + this.mCustomView = mActivity.getLayoutInflater().inflate(resLayout, mRootView, false); + } + + return this; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollView.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollView.java new file mode 100644 index 0000000..af386e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollView.java @@ -0,0 +1,39 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.ScrollView; + +public class NoScrollView extends ScrollView { + private boolean noScroll = false; + + public NoScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public NoScrollView(Context context) { + super(context); + } + + public void setNoScroll(boolean noScroll) { + this.noScroll = noScroll; + } + + @Override + public boolean onTouchEvent(MotionEvent arg0) { + /* return false;//super.onTouchEvent(arg0); */ + if (noScroll) + return false; + else + return super.onTouchEvent(arg0); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent arg0) { + if (noScroll) + return false; + else + return super.onInterceptTouchEvent(arg0); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollViewPager.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollViewPager.java new file mode 100644 index 0000000..39b651a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollViewPager.java @@ -0,0 +1,56 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.viewpager.widget.ViewPager; + +public class NoScrollViewPager extends ViewPager { + private boolean noScroll = false; + + public NoScrollViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public NoScrollViewPager(Context context) { + super(context); + } + + public void setNoScroll(boolean noScroll) { + this.noScroll = noScroll; + } + + @Override + public void scrollTo(int x, int y) { + super.scrollTo(x, y); + } + + @Override + public boolean onTouchEvent(MotionEvent arg0) { + /* return false;//super.onTouchEvent(arg0); */ + if (noScroll) + return false; + else + return super.onTouchEvent(arg0); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent arg0) { + if (noScroll) + return false; + else + return super.onInterceptTouchEvent(arg0); + } + + @Override + public void setCurrentItem(int item, boolean smoothScroll) { + super.setCurrentItem(item, smoothScroll); + } + + @Override + public void setCurrentItem(int item) { + super.setCurrentItem(item); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/RotateLayout.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/RotateLayout.java new file mode 100644 index 0000000..1ef42a7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/RotateLayout.java @@ -0,0 +1,189 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Rect; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; + +import com.bingce.controlnetwork.R; + +import static java.lang.Math.PI; + +/** + * Rotates first view in this layout by specified angle. + *

+ * This layout is supposed to have only one view. Behaviour of the views after the first one + * is not defined. + *

+ * XML attributes + * See com.github.rongi.rotate_layout.R.styleable#RotateLayout RotateLayout Attributes, + */ +public class RotateLayout extends ViewGroup { + private float angle; + + private final Matrix rotateMatrix = new Matrix(); + + private final Rect viewRectRotated = new Rect(); + + private final RectF tempRectF1 = new RectF(); + private final RectF tempRectF2 = new RectF(); + + private final float[] viewTouchPoint = new float[2]; + private final float[] childTouchPoint = new float[2]; + + private boolean angleChanged = true; + + public RotateLayout(Context context) { + this(context, null); + } + + public RotateLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RotateLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs); + + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RotateLayout); + angle = a.getInt(R.styleable.RotateLayout_rotate_angle, 0); + a.recycle(); + + setWillNotDraw(false); + } + + /** + * Returns current angle of this layout + */ + public float getAngle() { + return angle; + } + + /** + * Sets current angle of this layout. + */ + public void setAngle(float angle) { + if (this.angle != angle) { + this.angle = angle; + angleChanged = true; + requestLayout(); + invalidate(); + } + } + + /** + * Returns this layout's child or null if there is no any + */ + public View getView() { + if (getChildCount() > 0) { + return getChildAt(0); + } else { + return null; + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final View child = getView(); + if (child != null) { + measureChild(child, widthMeasureSpec, heightMeasureSpec); + setMeasuredDimension( + resolveSize(child.getMeasuredWidth(), widthMeasureSpec), + resolveSize(child.getMeasuredHeight(), heightMeasureSpec)); +// if (abs(angle % 180) == 90) { +// //noinspection SuspiciousNameCombination +// measureChild(child, heightMeasureSpec, widthMeasureSpec); +// setMeasuredDimension( +// resolveSize(child.getMeasuredHeight(), widthMeasureSpec), +// resolveSize(child.getMeasuredWidth(), heightMeasureSpec)); +// } else if (abs(angle % 180) == 0) { +// measureChild(child, widthMeasureSpec, heightMeasureSpec); +// setMeasuredDimension( +// resolveSize(child.getMeasuredWidth(), widthMeasureSpec), +// resolveSize(child.getMeasuredHeight(), heightMeasureSpec)); +// } else { +// int childWithMeasureSpec = MeasureSpec.makeMeasureSpec(0, UNSPECIFIED); +// int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, UNSPECIFIED); +// measureChild(child, childWithMeasureSpec, childHeightMeasureSpec); +// +// int measuredWidth = (int) ceil(child.getMeasuredWidth() * abs(cos(angle_c())) + child.getMeasuredHeight() * abs(sin(angle_c()))); +// int measuredHeight = (int) ceil(child.getMeasuredWidth() * abs(sin(angle_c())) + child.getMeasuredHeight() * abs(cos(angle_c()))); +// +// setMeasuredDimension( +// resolveSize(measuredWidth, widthMeasureSpec), +// resolveSize(measuredHeight, heightMeasureSpec)); +// } + } else { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int layoutWidth = r - l; + int layoutHeight = b - t; + + if (angleChanged || changed) { + final RectF layoutRect = tempRectF1; + layoutRect.set(0, 0, layoutWidth, layoutHeight); + final RectF layoutRectRotated = tempRectF2; + rotateMatrix.setRotate(angle, layoutRect.centerX(), layoutRect.centerY()); + rotateMatrix.mapRect(layoutRectRotated, layoutRect); + layoutRectRotated.round(viewRectRotated); + angleChanged = false; + } + + final View child = getView(); + if (child != null) { + int childLeft = (layoutWidth - child.getMeasuredWidth()) / 2; + int childTop = (layoutHeight - child.getMeasuredHeight()) / 2; + int childRight = childLeft + child.getMeasuredWidth(); + int childBottom = childTop + child.getMeasuredHeight(); + child.layout(childLeft, childTop, childRight, childBottom); + } + } + + @Override + protected void dispatchDraw(Canvas canvas) { + canvas.save(); + canvas.rotate(angle, getWidth() / 2f, getHeight() / 2f); + super.dispatchDraw(canvas); + canvas.restore(); + } + + @Override + public ViewParent invalidateChildInParent(int[] location, Rect dirty) { + invalidate(); + return super.invalidateChildInParent(location, dirty); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + viewTouchPoint[0] = event.getX(); + viewTouchPoint[1] = event.getY(); + + rotateMatrix.mapPoints(childTouchPoint, viewTouchPoint); + + event.setLocation(childTouchPoint[0], childTouchPoint[1]); + boolean result = super.dispatchTouchEvent(event); + event.setLocation(viewTouchPoint[0], viewTouchPoint[1]); + + return result; + } + + /** + * Circle angle, from 0 to TAU + */ + private Double angle_c() { + // True circle constant, not that petty imposter known as "PI" + double TAU = 2 * PI; + return TAU * angle / 360; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItem.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItem.java new file mode 100644 index 0000000..b73b2f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItem.java @@ -0,0 +1,100 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.R; + +public class TextItem extends FrameLayout { + public final static int GRAVITY_TEXT_START = 0; + public final static int GRAVITY_TEXT_CENTER = 1; + public final static int GRAVITY_TEXT_END = 2; + + public final static int DIVIDER_VISIBLE = 0; + public final static int DIVIDER_INVISIBLE = 1; + + public TextItem(@NonNull Context context) { + super(context); + init(context, null); + } + + public TextItem(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public TextItem(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + public TextItem(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context, attrs); + } + + protected int contentLayout() { + return R.layout.item_with_text_layout; + } + + void init(Context context, AttributeSet attrs) { + String string = "TEXT"; + int color = Color.BLACK; + int size = -1; + int gravity = GRAVITY_TEXT_START; + int divider = DIVIDER_VISIBLE; + if (attrs != null) { + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextItem); + string = a.getString(R.styleable.TextItem_text); + color = a.getColor(R.styleable.TextItem_text_color, Color.BLACK); + size = a.getDimensionPixelSize(R.styleable.TextItem_text_size, -1); + gravity = a.getInt(R.styleable.TextItem_text_gravity, GRAVITY_TEXT_START); + divider = a.getInt(R.styleable.TextItem_dividerVisible, DIVIDER_VISIBLE); + a.recycle(); + } + View content = LayoutInflater.from(context).inflate(contentLayout(), null, false); + addView(content); + View text = content.findViewById(R.id.text); + if (text instanceof TextView) { + TextView textView = (TextView) text; + textView.setText(string); + textView.setTextColor(color); + if (size > 0) { + textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); + } + switch (gravity) { + case GRAVITY_TEXT_CENTER: + textView.setGravity(Gravity.CENTER); + break; + case GRAVITY_TEXT_END: + textView.setGravity(Gravity.END | Gravity.CENTER_VERTICAL); + break; + default: + textView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); + break; + } + } + View dividerView = content.findViewById(R.id.divider); + if (dividerView != null) { + dividerView.setVisibility(divider == DIVIDER_VISIBLE ? VISIBLE : GONE); + } + } + + public void setText(String string) { + View text = findViewById(R.id.text); + if (text instanceof TextView) { + ((TextView) text).setText(string); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithDescribe.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithDescribe.java new file mode 100644 index 0000000..b91a92a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithDescribe.java @@ -0,0 +1,58 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.R; + +public class TextItemWithDescribe extends TextItem { + public TextItemWithDescribe(@NonNull Context context) { + super(context); + } + + public TextItemWithDescribe(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public TextItemWithDescribe(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public TextItemWithDescribe(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + void init(Context context, AttributeSet attrs) { + super.init(context, attrs); + String describe = ""; + if (attrs != null) { + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextItemWithDescribe); + describe = a.getString(R.styleable.TextItemWithDescribe_describeValue); + a.recycle(); + } + setDescribeText(describe); + } + + @Override + protected int contentLayout() { + return super.contentLayout(); + } + + public void setDescribeText(String text) { + TextView describe = findViewById(R.id.describe); + if (describe != null) { + if (text == null || text.isEmpty()) { + describe.setVisibility(GONE); + } else { + describe.setVisibility(VISIBLE); + describe.setText(text); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithMore.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithMore.java new file mode 100644 index 0000000..edc6592 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithMore.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.R; + +public class TextItemWithMore extends TextItemWithDescribe { + public TextItemWithMore(@NonNull Context context) { + super(context); + } + + public TextItemWithMore(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public TextItemWithMore(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public TextItemWithMore(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected int contentLayout() { + return R.layout.item_with_more_layout; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/ViewFactory.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/ViewFactory.java new file mode 100644 index 0000000..25c8ffe --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/ViewFactory.java @@ -0,0 +1,125 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.ViewItemType; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.GroupParentViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextWithPrefixViewHolder; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyBoolViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyValueViewHolder; +import com.bingce.controlnetwork.ui.vh.StationAdjustItemViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataAloneDistanceViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolderHeightTraverse; +import com.bingce.controlnetwork.ui.vh.TextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.TitleWithSubtitleViewHolder; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.GroupParentViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextWithPrefixViewHolder; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyBoolViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyValueViewHolder; +import com.bingce.controlnetwork.ui.vh.StationAdjustItemViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataAloneDistanceViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolderHeightTraverse; +import com.bingce.controlnetwork.ui.vh.TextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.TitleWithSubtitleViewHolder; + + +public class ViewFactory { + + //生成对应的配置view + public static View generatorView(Context context, ViewGroup parent, ViewItemType viewType) { + switch (viewType) { + case indexWithName: + return LayoutInflater.from(context).inflate(R.layout.list_item_index_text_layout, parent, false); + case indexWithNameAndPrefix: + return LayoutInflater.from(context).inflate(R.layout.list_item_index_text_with_prefix_layout, parent, false); + case indexWithNameSelectable: + return LayoutInflater.from(context).inflate(R.layout.list_item_index_text_selectable_layout, parent, false); + case groupParent: + return LayoutInflater.from(context).inflate(R.layout.list_item_group_parent_layout, parent, false); + case nameWithText: + return LayoutInflater.from(context).inflate(R.layout.list_item_text_value_layout, parent, false); + case nameWithBool: + return LayoutInflater.from(context).inflate(R.layout.list_item_text_boolen_layout, parent, false); + case titleWithSubtitle: + return LayoutInflater.from(context).inflate(R.layout.list_item_title_subtitle_layout, parent, false); + case draggableItem: + return LayoutInflater.from(context).inflate(R.layout.list_item_draggable_layout, parent, false); + case surveyorStationCreateStationGroupItem: + return LayoutInflater.from(context).inflate(R.layout.list_item_surveyor_station_group_parent_with_add_layout, parent, false); + case textSelectable: + return LayoutInflater.from(context).inflate(R.layout.list_item_text_selectable_layout, parent, false); + case surveyorStationPointItem: + return LayoutInflater.from(context).inflate(R.layout.list_item_surveyor_station_point_layout, parent, false); + case stationAdjust: + return LayoutInflater.from(context).inflate(R.layout.list_item_station_adjust_layout, parent, false); + case wellItem: + return LayoutInflater.from(context).inflate(R.layout.list_item_well, parent, false); + case aloneDistanceMeasure: + return LayoutInflater.from(context).inflate(R.layout.list_item_well_measure_distance, parent, false); + case heightTraverseSurveyor: + return LayoutInflater.from(context).inflate(R.layout.list_item_surveyor_station_height_traverse, parent, false); + default: + return null; + } + } + + public static RecyclerView.ViewHolder generatorViewHolder(Context context, ViewGroup parent, ViewItemType viewType) { + View view = generatorView(context, parent, viewType); + if (view == null) { + return null; + } + switch (viewType) { + case indexWithName: + return new IndexTextViewHolder(view); + case indexWithNameAndPrefix: + return new IndexTextWithPrefixViewHolder(view); + case indexWithNameSelectable: + return new IndexTextSelectableViewHolder(view); + case groupParent: + return new GroupParentViewHolder(view); + case nameWithText: + return new KeyValueViewHolder(view); + case nameWithBool: + return new KeyBoolViewHolder(view); + case titleWithSubtitle: + return new TitleWithSubtitleViewHolder(view); + case draggableItem: + return new DraggableTextViewHolder(view); + case surveyorStationCreateStationGroupItem: + return new StationGroupItemViewHolder(view); + case textSelectable: + return new TextSelectableViewHolder(view); + case surveyorStationPointItem: + return new SurveyorDataViewHolder(context, view); + case stationAdjust: + return new StationAdjustItemViewHolder(view); + case wellItem: + return new ItemWellViewHolder(view); + case aloneDistanceMeasure: + return new SurveyorDataAloneDistanceViewHolder(context, view); + case heightTraverseSurveyor: + return new SurveyorDataViewHolderHeightTraverse(context, view); + default: + return null; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingDialog.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingDialog.java new file mode 100644 index 0000000..21fda4d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingDialog.java @@ -0,0 +1,86 @@ +package com.bingce.controlnetwork.ui.widget.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; + +import com.bingce.controlnetwork.R; + + +public class LoadingDialog extends Dialog { + + public LoadingDialog(Context context) { + super(context, R.style.loading_dialog); + } + + public static class Builder { + + private final Context context; + private String message; + private boolean isCancelable = false; + private boolean isCancelOutside = false; + + + public Builder(Context context) { + this.context = context; + } + + /** + * 设置提示信息 + * + * @param message + * @return + */ + + public Builder setMessage(String message) { + this.message = message; + return this; + } + + /** + * 设置是否可以按返回键取消 + * + * @param isCancelable + * @return + */ + + public Builder setCancelable(boolean isCancelable) { + this.isCancelable = isCancelable; + return this; + } + + /** + * 设置是否可以取消 + * + * @param isCancelOutside + * @return + */ + public Builder setCancelOutside(boolean isCancelOutside) { + this.isCancelOutside = isCancelOutside; + return this; + } + + public LoadingDialog create() { + LayoutInflater inflater = LayoutInflater.from(context); + View view = inflater.inflate(R.layout.loading_dialog, null); + LoadingDialog loadingDailog = new LoadingDialog(context); + TextView msgText = view.findViewById(R.id.tipTextView); + if (TextUtils.isEmpty(message)) { + msgText.setVisibility(View.GONE); + } else { + msgText.setText(message); + msgText.setVisibility(View.VISIBLE); + } + loadingDailog.setContentView(view); + loadingDailog.setCancelable(isCancelable); + loadingDailog.setCanceledOnTouchOutside(isCancelOutside); + return loadingDailog; + + } + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtil.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtil.java new file mode 100644 index 0000000..1b60e30 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtil.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.ui.widget.dialog; + +import android.content.Context; + +import androidx.annotation.MainThread; + +public class LoadingUtil { + private static LoadingDialog loadingDialog; + + @MainThread + public static void show(Context context, String msg) { + LoadingDialog.Builder loadBuilder = new LoadingDialog.Builder(context) + .setMessage(msg) + .setCancelable(true)//返回键是否可点击 + .setCancelOutside(false);//窗体外是否可点击 + loadingDialog = loadBuilder.create(); + loadingDialog.show(); + } + + @MainThread + public static void dismiss() { + try { + if (loadingDialog != null && loadingDialog.isShowing()) { + loadingDialog.dismiss(); + } + loadingDialog = null; + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtilKt.kt b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtilKt.kt new file mode 100644 index 0000000..4f75437 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtilKt.kt @@ -0,0 +1,33 @@ +package com.bingce.controlnetwork.ui.widget.dialog + +import android.content.Context + +object LoadingUtilKt { + + private var loadingDialog: LoadingDialog? = null + + + fun show(context: Context, msg: String?) { + val loadBuilder = LoadingDialog.Builder(context) + .setMessage(msg) + .setCancelable(true) //返回键是否可点击 + .setCancelOutside(false) //窗体外是否可点击 + + loadingDialog = loadBuilder.create() + loadingDialog!!.show() + } + + fun dismiss() { + try { + loadingDialog?.let { + if (it.isShowing) { + it.dismiss() + } + loadingDialog = null + } + } catch (e: Exception) { + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/AbstractDraggableRecycleViewAdapter.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/AbstractDraggableRecycleViewAdapter.java new file mode 100644 index 0000000..2362dc5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/AbstractDraggableRecycleViewAdapter.java @@ -0,0 +1,173 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +import android.annotation.SuppressLint; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.ViewItemType; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.ViewFactory; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +public abstract class AbstractDraggableRecycleViewAdapter + extends RecyclerView.Adapter + implements IDragSwipeChecker { + private final List items = new ArrayList<>(); + private @Nullable + IViewHolderDragDelegate viewHolderDragDelegate; + + public AbstractDraggableRecycleViewAdapter(List itemList) { + if (itemList != null) { + this.items.addAll(itemList); + } + } + + protected void replace(int start, List data) { + if (getItemCount() > start) { + items.subList(start, getItemCount()).clear(); + } + items.addAll(data); + } + + protected int indexOf(T item) { + return items.indexOf(item); + } + + protected void remove(T item) { + items.remove(item); + } + + protected void removeAll(List item) { + items.removeAll(item); + } + + protected void insert(int index, T item) { + if (items.size() <= index) { + return; + } + items.add(index, item); + } + + protected void insertAll(List item) { + items.addAll(item); + } + + protected void refreshAll(List item) { + items.clear(); + items.addAll(item); + notifyDataSetChanged(); + } + + /** + * 一井定向使用 + * + * @param index 要插入的位置 + * @param item + */ + protected void insertForWell(int index, List item) { + if (index < 0) { + return; + } + if (index == items.size()) { + items.addAll(item); + } else if (index < items.size()) { + items.addAll(index, item); + } + } + + final protected T getItem(int position) { + if (position >= items.size()) { + return null; + } + return items.get(position); + } + + final protected void setItem(int position, T item) { + if (position >= items.size() || position < 0) { + return; + } + items.set(position, item); + } + + public List getItems() { + return Collections.unmodifiableList(items); + } + + public void setViewHolderDragDelegate(@Nullable IViewHolderDragDelegate viewHolderDragDelegate) { + this.viewHolderDragDelegate = viewHolderDragDelegate; + } + + @Override + public int getItemViewType(int position) { + return ViewItemType.draggableItem.ordinal(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + return Objects.requireNonNull(ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.values()[viewType])); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void onBindViewHolder(@NonNull @NotNull RecyclerView.ViewHolder holder, int position) { + bindItem(items.get(position), holder); + View dragBar = holder.itemView.findViewById(R.id.drag_bar); + if (dragBar != null) { + dragBar.setOnTouchListener((v, event) -> { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + if (viewHolderDragDelegate != null) { + viewHolderDragDelegate.startDrag(holder); + } + } + return true; + }); + } + //原先代码注释 +// if (holder instanceof DraggableTextViewHolder) { +// DraggableTextViewHolder draggableTextViewHolder = (DraggableTextViewHolder) holder; +// draggableTextViewHolder.dragBar.setOnTouchListener((v, event) -> { +// if (event.getAction() == MotionEvent.ACTION_DOWN) { +// if (viewHolderDragDelegate != null) { +// viewHolderDragDelegate.startDrag(holder); +// } +// } +// return true; +// }); +// } + } + + @Override + public int getItemCount() { + return items.size(); + } + + //交换 + public void onItemSwap(int from, int target) { + T s = items.get(from); + items.remove(from); + items.add(target, s); + notifyItemMoved(from, target); + } + + //滑动 + public void onItemRemoved(int position) { + items.remove(position); + notifyItemRemoved(position); + } + + protected abstract void bindItem(T item, RecyclerView.ViewHolder viewHolder); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragActionDelegate.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragActionDelegate.java new file mode 100644 index 0000000..dc5d902 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragActionDelegate.java @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +public interface IDragActionDelegate { + void startDragAction(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeActionListener.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeActionListener.java new file mode 100644 index 0000000..f4ddadb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeActionListener.java @@ -0,0 +1,23 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +public interface IDragSwipeActionListener { + /** + * 左右滑动删除操作 + * + * @param adapterPosition --被滑动的item索引 + */ + void onItemSwiped(int adapterPosition); + + /** + * 上下拖拽操作进行中,没有完成,用户手指还没离开屏幕 + * + * @param from 被拖拽item原来索引 + * @param to 被拖拽item目标索引 + */ + void onItemDragging(int from, int to); + + /** + * 上下拖拽操作完成,用户手指离开屏幕 + */ + void onItemDragCompleted(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeChecker.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeChecker.java new file mode 100644 index 0000000..b1e1bbe --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeChecker.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +public interface IDragSwipeChecker { + boolean isItemSwipeAble(int position); + + boolean isItemDragAble(int position); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ISwipeDragListener.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ISwipeDragListener.java new file mode 100644 index 0000000..ae1d0a6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ISwipeDragListener.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +public interface ISwipeDragListener { + void onItemSwap(int from, int target); + + void onItemMoved(int position); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IViewHolderDragDelegate.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IViewHolderDragDelegate.java new file mode 100644 index 0000000..fa903e1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IViewHolderDragDelegate.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +import androidx.recyclerview.widget.RecyclerView; + +public interface IViewHolderDragDelegate { + void startDrag(RecyclerView.ViewHolder viewHolder); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ItemTouchHelperCallbackImpl.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ItemTouchHelperCallbackImpl.java new file mode 100644 index 0000000..992731d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ItemTouchHelperCallbackImpl.java @@ -0,0 +1,105 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import org.jetbrains.annotations.NotNull; + +public class ItemTouchHelperCallbackImpl extends ItemTouchHelper.Callback { + private final IDragSwipeActionListener listener; + private final IDragSwipeChecker dragSwipeChecker; + + public ItemTouchHelperCallbackImpl(IDragSwipeChecker dragSwipeChecker, + IDragSwipeActionListener listener) { + this.dragSwipeChecker = dragSwipeChecker; + this.listener = listener; + } + + @Override + public int getMovementFlags(@NonNull @NotNull RecyclerView recyclerView, @NonNull @NotNull RecyclerView.ViewHolder viewHolder) { + int dragFlag; //拖动标记 + int swipeFlags; //滑动标记 + //如果是表格布局,则可以上下左右的拖动,但是不能滑动 + if (recyclerView.getLayoutManager() instanceof GridLayoutManager) { + dragFlag = ItemTouchHelper.UP | + ItemTouchHelper.DOWN | + ItemTouchHelper.LEFT | + ItemTouchHelper.RIGHT; + swipeFlags = 0; + } else {//如果是线性布局,那么只能上下拖动,只能左右滑动 + dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN; + swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; + } + + int position = viewHolder.getAdapterPosition(); + if (dragSwipeChecker != null && !dragSwipeChecker.isItemDragAble(position)) { + dragFlag = 0; + } + if (dragSwipeChecker != null && !dragSwipeChecker.isItemSwipeAble(position)) { + swipeFlags = 0; + } + + //通过makeMovementFlags生成最终结果 + return makeMovementFlags(dragFlag, swipeFlags); + } + + + @Override + public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { + //被拖动的item位置 + int fromPosition = viewHolder.getLayoutPosition(); + //他的目标位置 + int targetPosition = target.getLayoutPosition(); + if (!isDragValidate(recyclerView, targetPosition, fromPosition)) { + return false; + } + if (listener != null) { + listener.onItemDragging(fromPosition, targetPosition); + } + return true; + } + + final protected boolean isDragValidate(@NonNull RecyclerView recyclerView, int targetPosition, int fromPosition) { + RecyclerView.Adapter adapter = recyclerView.getAdapter(); + if (adapter != null) { + int targetType = adapter.getItemViewType(targetPosition); + int fromType = adapter.getItemViewType(fromPosition); + return targetType == fromType && targetPosition > 1; + } + return true; + } + + @Override + public void onSwiped(@NonNull @NotNull RecyclerView.ViewHolder viewHolder, int direction) { + if (listener != null) { + listener.onItemSwiped(viewHolder.getAdapterPosition()); + } + } + + @Override + public boolean isLongPressDragEnabled() { + return false; + } + + private boolean listener2DragComplete = false; + + @Override + public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) { + super.onSelectedChanged(viewHolder, actionState); + if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) { + listener2DragComplete = true; + } else if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { + listener2DragComplete = false; + } else if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) { + if (listener2DragComplete) { + if (listener != null) { + listener.onItemDragCompleted(); + } + } + listener2DragComplete = false; + } + } +} \ 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 new file mode 100644 index 0000000..2a8f8b4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/SwipeDraggableRecyclerViewUtil.java @@ -0,0 +1,79 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +import android.content.Context; + +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; + +public class SwipeDraggableRecyclerViewUtil { + public static void setup(AbstractDraggableRecycleViewAdapter adapter, + RecyclerView recyclerView, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IStationPointOperatorListener operatorListener, + Context context) { + ItemTouchHelperCallbackImpl callback = new ItemTouchHelperCallbackImpl(adapter, new IDragSwipeActionListener() { + @Override + public void onItemSwiped(int adapterPosition) { + TipsWith2OptionFragment.tips(fragmentManager, lifecycleOwner, + null, null, + context.getString(R.string.tips_r_u_sure_delete_item), + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (adapter != null) { + adapter.onItemRemoved(adapterPosition); + } + if (operatorListener != null) { + operatorListener.onItemRemoved(adapterPosition); + } + } + + @Override + public void onOption() { + } + + @Override + public void onCancel() { + if (adapter != null) { + adapter.notifyItemChanged(adapterPosition); + } + } + + @Override + public void onIgnore() { + if (adapter != null) { + adapter.notifyItemChanged(adapterPosition); + } + } + }); + } + + @Override + public void onItemDragging(int from, int to) { + adapter.onItemSwap(from, to); + } + + @Override + public void onItemDragCompleted() { + if (operatorListener != null) { + operatorListener.onItemDragCompleted(); + } + } + }); + ItemTouchHelper helper = new ItemTouchHelper(callback); + adapter.setViewHolderDragDelegate(helper::startDrag); + helper.attachToRecyclerView(recyclerView); + } + + public interface IStationPointOperatorListener { + void onItemRemoved(int adapterPosition); + + void onItemDragCompleted(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeNode.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeNode.java new file mode 100644 index 0000000..af8c986 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeNode.java @@ -0,0 +1,231 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under. + */ + +package com.bingce.controlnetwork.ui.widget.treeview; + +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + + +/** + * Created by xinyuanzhong on 2017/4/20. + */ + +public class TreeNode { + private int level; + + private Value value; + + private TreeNode parent; + + private List children; + + private int index; + + private boolean expanded; + + private boolean selected; + + private boolean itemClickEnable = true; + + private boolean enable = true; + + public TreeNode(Value value) { + this.value = value; + this.children = new ArrayList<>(); + } + + public TreeNode(Value value, int level) { + this(value); + setLevel(level); + } + + public static TreeNode root() { + TreeNode treeNode = new TreeNode(null); + return treeNode; + } + + public void addChild(TreeNode treeNode) { + if (treeNode == null) { + return; + } + children.add(treeNode); + treeNode.setIndex(getChildren().size()); + treeNode.setParent(this); + } + + + public void removeChild(TreeNode treeNode) { + if (treeNode == null || getChildren().size() < 1) { + return; + } + if (getChildren().contains(treeNode)) { + getChildren().remove(treeNode); + } + } + + public boolean isLastChild() { + if (parent == null) { + return false; + } + List children = parent.getChildren(); + return children.size() > 0 && children.indexOf(this) == children.size() - 1; + } + + public boolean isRoot() { + return parent == null; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public Value getValue() { + return value; + } + + public void setValue(Value value) { + this.value = value; + } + + public TreeNode getParent() { + return parent; + } + + public void setParent(TreeNode parent) { + this.parent = parent; + } + + public List getChildren() { + if (children == null) { + return new ArrayList<>(); + } + return children; + } + + public List getSelectedChildren() { + List selectedChildren = new ArrayList<>(); + for (TreeNode child : getChildren()) { + if (child.isSelected()) { + selectedChildren.add(child); + } + } + return selectedChildren; + } + + public void setChildren(List children) { + if (children == null) { + return; + } + this.children = new ArrayList<>(); + for (TreeNode child : children) { + addChild(child); + } + } + + /** + * Updating the list of children while maintaining the tree structure + */ + public void updateChildren(List children) { + List expands = new ArrayList<>(); + List allNodesPre = TreeHelper.getAllNodes(this); + for (TreeNode node : allNodesPre) { + expands.add(node.isExpanded()); + } + + this.children = children; + List allNodes = TreeHelper.getAllNodes(this); + if (allNodes.size() == expands.size()) { + for (int i = 0; i < allNodes.size(); i++) { + allNodes.get(i).setExpanded(expands.get(i)); + } + } + } + + public void setExpanded(boolean expanded) { + this.expanded = expanded; + } + + public boolean isExpanded() { + return expanded; + } + + public boolean isEnable() { + return enable; + } + + public void setEnable(boolean enable) { + this.enable = enable; + } + + public boolean hasChild() { + return children.size() > 0; + } + + public boolean isItemClickEnable() { + return itemClickEnable; + } + + public void setItemClickEnable(boolean itemClickEnable) { + this.itemClickEnable = itemClickEnable; + } + + public String getId() { + return getLevel() + "," + getIndex(); + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + } + + + public static class Value { + private final Object value; + private final String id; + + public Value(Object value, String id) { + this.value = value; + this.id = id; + } + + public Object getValue() { + return value; + } + + public String getId() { + return id; + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeView.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeView.java new file mode 100644 index 0000000..92aefa7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeView.java @@ -0,0 +1,214 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under. + */ + +package com.bingce.controlnetwork.ui.widget.treeview; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.SimpleItemAnimator; + +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; +import com.bingce.controlnetwork.ui.widget.treeview.base.SelectableTreeAction; +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; +import com.bingce.controlnetwork.ui.widget.treeview.base.SelectableTreeAction; +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + + +/** + * Created by xinyuanzhong on 2017/4/20. + */ + +public class TreeView implements SelectableTreeAction { + private final TreeNode root; + + private final Context context; + + private final BaseNodeViewFactory baseNodeViewFactory; + + private RecyclerView rootView; + + private TreeViewAdapter adapter; + + private boolean itemSelectable = true; + + public TreeView(@NonNull TreeNode root, @NonNull Context context, @NonNull BaseNodeViewFactory baseNodeViewFactory) { + this.root = root; + this.context = context; + this.baseNodeViewFactory = baseNodeViewFactory; + if (baseNodeViewFactory == null) { + throw new IllegalArgumentException("You must assign a BaseNodeViewFactory!"); + } + } + + // public View getView() { +// if (rootView == null) { +// this.rootView = buildRootView(); +// } +// +// return rootView; +// } + public void setup(RecyclerView recyclerView) { + buildRootView(recyclerView); + } + + @NonNull + private void buildRootView(RecyclerView recyclerView) { +// private RecyclerView buildRootView() { +// RecyclerView recyclerView = new RecyclerView(context); + /** + * disable multi touch event to prevent terrible data set error when calculate list. + */ + recyclerView.setMotionEventSplittingEnabled(false); + ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false); +// recyclerView.setItemAnimator(null); + + recyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false)); + adapter = new TreeViewAdapter(context, root, baseNodeViewFactory); + adapter.setTreeView(this); + recyclerView.setAdapter(adapter); +// return recyclerView; + } + + @Override + public void expandAll() { + if (root == null) { + return; + } + TreeHelper.expandAll(root); + + refreshTreeView(); + } + + + public void refreshTreeView() { + if (rootView != null) { + ((TreeViewAdapter) rootView.getAdapter()).refreshView(); + } + } + + public void updateTreeView() { + if (rootView != null) { + rootView.getAdapter().notifyDataSetChanged(); + } + } + + @Override + public void expandNode(TreeNode treeNode) { + adapter.expandNode(treeNode); + } + + @Override + public void expandLevel(int level) { + TreeHelper.expandLevel(root, level); + + refreshTreeView(); + } + + @Override + public void collapseAll() { + if (root == null) { + return; + } + TreeHelper.collapseAll(root); + + refreshTreeView(); + } + + @Override + public void collapseNode(TreeNode treeNode) { + adapter.collapseNode(treeNode); + } + + @Override + public void collapseLevel(int level) { + TreeHelper.collapseLevel(root, level); + + refreshTreeView(); + } + + @Override + public void toggleNode(TreeNode treeNode) { + if (treeNode.isExpanded()) { + collapseNode(treeNode); + } else { + expandNode(treeNode); + } + } + + @Override + public void deleteNode(TreeNode node) { + adapter.deleteNode(node); + } + + @Override + public void addNode(TreeNode parent, TreeNode treeNode) { + parent.addChild(treeNode); + + refreshTreeView(); + } + + @Override + public List getAllNodes() { + return TreeHelper.getAllNodes(root); + } + + @Override + public void selectNode(TreeNode treeNode) { + if (treeNode != null) { + adapter.selectNode(true, treeNode); + } + } + + @Override + public void deselectNode(TreeNode treeNode) { + if (treeNode != null) { + adapter.selectNode(false, treeNode); + } + } + + @Override + public void selectAll() { + TreeHelper.selectNodeAndChild(root, true); + + refreshTreeView(); + } + + @Override + public void deselectAll() { + TreeHelper.selectNodeAndChild(root, false); + + refreshTreeView(); + } + + @Override + public List getSelectedNodes() { + return TreeHelper.getSelectedNodes(root); + } + + public boolean isItemSelectable() { + return itemSelectable; + } + + public void setItemSelectable(boolean itemSelectable) { + this.itemSelectable = itemSelectable; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeViewAdapter.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeViewAdapter.java new file mode 100644 index 0000000..cdd7558 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeViewAdapter.java @@ -0,0 +1,286 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under. + */ + +package com.bingce.controlnetwork.ui.widget.treeview; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Checkable; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + +/** + * Created by xinyuanzhong on 2017/4/21. + */ + +public class TreeViewAdapter extends RecyclerView.Adapter { + + private final Context context; + + private final TreeNode root; + + private final List expandedNodeList; + + private final BaseNodeViewFactory baseNodeViewFactory; + + private TreeView treeView; + + TreeViewAdapter(Context context, TreeNode root, + @NonNull BaseNodeViewFactory baseNodeViewFactory) { + this.context = context; + this.root = root; + this.baseNodeViewFactory = baseNodeViewFactory; + + this.expandedNodeList = new ArrayList<>(); + + buildExpandedNodeList(); + } + + private void buildExpandedNodeList() { + expandedNodeList.clear(); + + for (TreeNode child : root.getChildren()) { + insertNode(expandedNodeList, child); + } + } + + private void insertNode(List nodeList, TreeNode treeNode) { + nodeList.add(treeNode); + + if (!treeNode.hasChild()) { + return; + } + if (treeNode.isExpanded()) { + for (TreeNode child : treeNode.getChildren()) { + insertNode(nodeList, child); + } + } + } + + @Override + public int getItemViewType(int position) { + // return expandedNodeList.get(position).getLevel(); // this old code row used to always return the level + TreeNode treeNode = expandedNodeList.get(position); + int viewType = this.baseNodeViewFactory.getViewType(treeNode); // default implementation returns the three node level but it can be overridden + return viewType; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int level) { + View view = LayoutInflater.from(context).inflate(baseNodeViewFactory.getNodeLayoutId(level), parent, false); + + BaseNodeViewBinder nodeViewBinder = baseNodeViewFactory.getNodeViewBinder(view, level); + nodeViewBinder.setTreeView(treeView); + return nodeViewBinder; + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) { + final View nodeView = holder.itemView; + final TreeNode treeNode = expandedNodeList.get(position); + final BaseNodeViewBinder viewBinder = (BaseNodeViewBinder) holder; + + if (viewBinder.getToggleTriggerViewId() != 0) { + View triggerToggleView = nodeView.findViewById(viewBinder.getToggleTriggerViewId()); + + if (triggerToggleView != null) { + triggerToggleView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onNodeToggled(treeNode); + viewBinder.onNodeToggled(treeNode, treeNode.isExpanded()); + } + }); + } + } else if (treeNode.isItemClickEnable()) { + nodeView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onNodeToggled(treeNode); + viewBinder.onNodeToggled(treeNode, treeNode.isExpanded()); + } + }); + } + + if (viewBinder instanceof CheckableNodeViewBinder) { + setupCheckableItem(nodeView, treeNode, (CheckableNodeViewBinder) viewBinder); + } + + viewBinder.bindView(treeNode); + } + + private void setupCheckableItem(View nodeView, + final TreeNode treeNode, + final CheckableNodeViewBinder viewBinder) { + final View view = nodeView.findViewById(viewBinder.getCheckableViewId()); + + if (view instanceof Checkable) { + final Checkable checkableView = (Checkable) view; + + view.setEnabled(treeNode.isEnable()); + if (treeNode.isEnable()) { + checkableView.setChecked(treeNode.isSelected()); + + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean checked = checkableView.isChecked(); + selectNode(checked, treeNode); + viewBinder.onNodeSelectedChanged(treeNode, checked); + } + }); + } + } else { + throw new ClassCastException("The getCheckableViewId() " + + "must return a CheckBox's id"); + } + } + + void selectNode(boolean checked, TreeNode treeNode) { + treeNode.setSelected(checked); + + selectChildren(treeNode, checked); + selectParentIfNeed(treeNode, checked); + } + + private void selectChildren(TreeNode treeNode, boolean checked) { + List impactedChildren = TreeHelper.selectNodeAndChild(treeNode, checked); + int index = expandedNodeList.indexOf(treeNode); + if (index != -1 && impactedChildren.size() > 0) { + notifyItemRangeChanged(index, impactedChildren.size() + 1); + } + } + + private void selectParentIfNeed(TreeNode treeNode, boolean checked) { + List impactedParents = TreeHelper.selectParentIfNeedWhenNodeSelected(treeNode, checked); + if (impactedParents.size() > 0) { + for (TreeNode parent : impactedParents) { + int position = expandedNodeList.indexOf(parent); + if (position != -1) notifyItemChanged(position); + } + } + } + + private void onNodeToggled(TreeNode treeNode) { + treeNode.setExpanded(!treeNode.isExpanded()); + + if (treeNode.isExpanded()) { + expandNode(treeNode); + } else { + collapseNode(treeNode); + } + } + + @Override + public int getItemCount() { + return expandedNodeList == null ? 0 : expandedNodeList.size(); + } + + /** + * Refresh all,this operation is only used for refreshing list when a large of nodes have + * changed value or structure because it take much calculation. + */ + void refreshView() { + buildExpandedNodeList(); + notifyDataSetChanged(); + } + + // Insert a node list after index. + private void insertNodesAtIndex(int index, List additionNodes) { + if (index < 0 || index > expandedNodeList.size() - 1 || additionNodes == null) { + return; + } + expandedNodeList.addAll(index + 1, additionNodes); + notifyItemRangeInserted(index + 1, additionNodes.size()); + } + + //Remove a node list after index. + private void removeNodesAtIndex(int index, List removedNodes) { + if (index < 0 || index > expandedNodeList.size() - 1 || removedNodes == null) { + return; + } + expandedNodeList.removeAll(removedNodes); + notifyItemRangeRemoved(index + 1, removedNodes.size()); + } + + /** + * Expand node. This operation will keep the structure of children(not expand children) + */ + void expandNode(TreeNode treeNode) { + if (treeNode == null) { + return; + } + List additionNodes = TreeHelper.expandNode(treeNode, false); + int index = expandedNodeList.indexOf(treeNode); + + insertNodesAtIndex(index, additionNodes); + } + + + /** + * Collapse node. This operation will keep the structure of children(not collapse children) + */ + void collapseNode(TreeNode treeNode) { + if (treeNode == null) { + return; + } + List removedNodes = TreeHelper.collapseNode(treeNode, false); + int index = expandedNodeList.indexOf(treeNode); + + removeNodesAtIndex(index, removedNodes); + } + + /** + * Delete a node from list.This operation will also delete its children. + */ + void deleteNode(TreeNode node) { + if (node == null || node.getParent() == null) { + return; + } + List allNodes = TreeHelper.getAllNodes(root); + if (allNodes.contains(node)) { + node.getParent().removeChild(node); + } + + //remove children form list before delete + collapseNode(node); + + int index = expandedNodeList.indexOf(node); + if (index != -1) { + expandedNodeList.remove(node); + } + notifyItemRemoved(index); + } + + void setTreeView(TreeView treeView) { + this.treeView = treeView; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewBinder.java new file mode 100644 index 0000000..88cbd09 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewBinder.java @@ -0,0 +1,70 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.TreeView; + + +/** + * Created by zxy on 17/4/23. + */ + +public abstract class BaseNodeViewBinder extends RecyclerView.ViewHolder { + /** + * This reference of TreeView make BaseNodeViewBinder has the ability + * to expand node or select node. + */ + protected TreeView treeView; + + public BaseNodeViewBinder(View itemView) { + super(itemView); + } + + public void setTreeView(TreeView treeView) { + this.treeView = treeView; + } + + /** + * Bind your data to view,you can get the data from treeNode by getValue() + * + * @param treeNode Node data + */ + public abstract void bindView(TreeNode treeNode); + + /** + * if you do not want toggle the node when click whole item view,then you can assign a view to + * trigger the toggle action + * + * @return The assigned view id to trigger expand or collapse. + */ + public int getToggleTriggerViewId() { + return 0; + } + + /** + * Callback when a toggle action happened (only by clicked) + * + * @param treeNode The toggled node + * @param expand Expanded or collapsed + */ + public void onNodeToggled(TreeNode treeNode, boolean expand) { + //empty + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewFactory.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewFactory.java new file mode 100644 index 0000000..9c016d5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewFactory.java @@ -0,0 +1,58 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import android.view.View; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + + +/** + * Created by zxy on 17/4/23. + */ + +public abstract class BaseNodeViewFactory { + + /** + * The default implementation below behaves as in previous version when TreeViewAdapter.getItemViewType always returned the level, + * but you can override it if you want some other viewType value to become the parameter to the method getNodeViewBinder. + * + * @param treeNode + * @return + */ + public int getViewType(TreeNode treeNode) { + return treeNode.getLevel(); + } + + /** + * If you want build a tree view,you must implement this factory method + * + * @param view The parameter for BaseNodeViewBinder's constructor, do not use this for other + * purpose! + * @param viewType The viewType value is the treeNode level in the default implementation. + * @return BaseNodeViewBinder + */ + public abstract BaseNodeViewBinder getNodeViewBinder(View view, int viewType); + + + /** + * If you want build a tree view,you must implement this factory method + * + * @param level Level of view, returned from {@link #getViewType} + * @return node layout id + */ + public abstract int getNodeLayoutId(int level); + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseTreeAction.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseTreeAction.java new file mode 100644 index 0000000..7f18cdb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseTreeAction.java @@ -0,0 +1,50 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + +/** + * Created by xinyuanzhong on 2017/4/20. + */ + +public interface BaseTreeAction { + void expandAll(); + + void expandNode(TreeNode treeNode); + + void expandLevel(int level); + + void collapseAll(); + + void collapseNode(TreeNode treeNode); + + void collapseLevel(int level); + + void toggleNode(TreeNode treeNode); + + void deleteNode(TreeNode node); + + void addNode(TreeNode parent, TreeNode treeNode); + + List getAllNodes(); + + // TODO: 17/4/30 + // 1.add node at position + // 2.add slide delete or other operations + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/CheckableNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/CheckableNodeViewBinder.java new file mode 100644 index 0000000..1c80515 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/CheckableNodeViewBinder.java @@ -0,0 +1,47 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import android.view.View; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + +/** + * Created by xinyuanzhong on 2017/4/27. + */ + +public abstract class CheckableNodeViewBinder extends BaseNodeViewBinder { + + public CheckableNodeViewBinder(View itemView) { + super(itemView); + } + + /** + * Get the checkable view id. MUST BE A Checkable type! + * + * @return + */ + public abstract int getCheckableViewId(); + + /** + * Do something when a node select or deselect(only triggered by clicked) + * + * @param treeNode + * @param selected + */ + public void onNodeSelectedChanged(TreeNode treeNode, boolean selected) { + /*empty*/ + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/SelectableTreeAction.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/SelectableTreeAction.java new file mode 100644 index 0000000..1107280 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/SelectableTreeAction.java @@ -0,0 +1,35 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + +/** + * Created by xinyuanzhong on 2017/4/27. + */ + +public interface SelectableTreeAction extends BaseTreeAction { + void selectNode(TreeNode treeNode); + + void deselectNode(TreeNode treeNode); + + void selectAll(); + + void deselectAll(); + + List getSelectedNodes(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/FirstLevelNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/FirstLevelNodeViewBinder.java new file mode 100644 index 0000000..37bd6fd --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/FirstLevelNodeViewBinder.java @@ -0,0 +1,45 @@ +package com.bingce.controlnetwork.ui.widget.treeview.custom; + +import android.view.View; +import android.widget.TextView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; + +/** + * Created by zxy on 17/4/23. + */ + +public class FirstLevelNodeViewBinder extends CheckableNodeViewBinder { + TextView textView; + View imageView; + + public FirstLevelNodeViewBinder(View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.node_name_view); + imageView = itemView.findViewById(R.id.arrow_img); + } + + @Override + public int getCheckableViewId() { + return R.id.checkBox; + } + + @Override + public void bindView(final TreeNode treeNode) { + textView.setText(treeNode.getValue().getValue().toString()); + imageView.setRotation(treeNode.isExpanded() ? 90 : 0); + imageView.setVisibility(treeNode.hasChild() ? View.VISIBLE : View.INVISIBLE); + } + + @Override + public void onNodeToggled(TreeNode treeNode, boolean expand) { + if (expand) { + imageView.animate().rotation(90).setDuration(200).start(); + } else { + imageView.animate().rotation(0).setDuration(200).start(); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/MyNodeViewFactory.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/MyNodeViewFactory.java new file mode 100644 index 0000000..383e451 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/MyNodeViewFactory.java @@ -0,0 +1,43 @@ +package com.bingce.controlnetwork.ui.widget.treeview.custom; + +import android.view.View; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; + + +/** + * Created by zxy on 17/4/23. + */ + +public class MyNodeViewFactory extends BaseNodeViewFactory { + + @Override + public BaseNodeViewBinder getNodeViewBinder(View view, int level) { + switch (level) { + case 0: + return new FirstLevelNodeViewBinder(view); + case 1: + return new SecondLevelNodeViewBinder(view); + case 2: + return new ThirdLevelNodeViewBinder(view); + default: + return null; + } + } + + @Override + public int getNodeLayoutId(int level) { + switch (level) { + case 0: + return R.layout.item_first_level; + case 1: + return R.layout.item_second_level; + case 2: + return R.layout.item_third_level; + default: + return 0; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/SecondLevelNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/SecondLevelNodeViewBinder.java new file mode 100644 index 0000000..9503e02 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/SecondLevelNodeViewBinder.java @@ -0,0 +1,51 @@ +package com.bingce.controlnetwork.ui.widget.treeview.custom; + +import android.view.View; +import android.widget.TextView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; + +/** + * Created by zxy on 17/4/23. + */ + +public class SecondLevelNodeViewBinder extends CheckableNodeViewBinder { + + TextView textView; + View imageView; + + public SecondLevelNodeViewBinder(View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.node_name_view); + imageView = itemView.findViewById(R.id.arrow_img); + } + +// @Override +// public int getLayoutId() { +// return R.layout.item_second_level; +// } + + @Override + public int getCheckableViewId() { + return R.id.checkBox; + } + + @Override + public void bindView(final TreeNode treeNode) { + textView.setText(treeNode.getValue().getValue().toString()); + imageView.setRotation(treeNode.isExpanded() ? 90 : 0); + imageView.setVisibility(treeNode.hasChild() ? View.VISIBLE : View.INVISIBLE); + } + + @Override + public void onNodeToggled(TreeNode treeNode, boolean expand) { + if (expand) { + imageView.animate().rotation(90).setDuration(200).start(); + } else { + imageView.animate().rotation(0).setDuration(200).start(); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/ThirdLevelNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/ThirdLevelNodeViewBinder.java new file mode 100644 index 0000000..ae73150 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/ThirdLevelNodeViewBinder.java @@ -0,0 +1,43 @@ +package com.bingce.controlnetwork.ui.widget.treeview.custom; + +import android.view.View; +import android.widget.Checkable; +import android.widget.TextView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; + +/** + * Created by zxy on 17/4/23. + */ + +public class ThirdLevelNodeViewBinder extends CheckableNodeViewBinder { + TextView textView; + + public ThirdLevelNodeViewBinder(View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.node_name_view); + } + + @Override + public int getCheckableViewId() { + return R.id.checkBox; + } + + @Override + public void bindView(TreeNode treeNode) { + textView.setText(treeNode.getValue().getValue().toString()); + } + + @Override + public void onNodeToggled(TreeNode treeNode, boolean expand) { + final View view = itemView.findViewById(getCheckableViewId()); + if (view instanceof Checkable && treeNode.isEnable()) { + final Checkable checkableView = (Checkable) view; + checkableView.setChecked(!checkableView.isChecked()); + treeNode.setSelected(checkableView.isChecked()); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/helper/TreeHelper.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/helper/TreeHelper.java new file mode 100644 index 0000000..ada7a75 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/helper/TreeHelper.java @@ -0,0 +1,290 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.helper; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + +/** + * Created by xinyuanzhong on 2017/4/27. + */ + +public class TreeHelper { + + public static void expandAll(TreeNode node) { + if (node == null) { + return; + } + expandNode(node, true); + } + + /** + * Expand node and calculate the visible addition nodes. + * + * @param treeNode target node to expand + * @param includeChild should expand child + * @return the visible addition nodes + */ + public static List expandNode(TreeNode treeNode, boolean includeChild) { + List expandChildren = new ArrayList<>(); + + if (treeNode == null) { + return expandChildren; + } + + treeNode.setExpanded(true); + + if (!treeNode.hasChild()) { + return expandChildren; + } + + for (TreeNode child : treeNode.getChildren()) { + expandChildren.add(child); + + if (includeChild || child.isExpanded()) { + expandChildren.addAll(expandNode(child, includeChild)); + } + } + + return expandChildren; + } + + /** + * Expand the same deep(level) nodes. + * + * @param root the tree root + * @param level the level to expand + */ + public static void expandLevel(TreeNode root, int level) { + if (root == null) { + return; + } + + for (TreeNode child : root.getChildren()) { + if (child.getLevel() == level) { + expandNode(child, false); + } else { + expandLevel(child, level); + } + } + } + + public static void collapseAll(TreeNode node) { + if (node == null) { + return; + } + for (TreeNode child : node.getChildren()) { + performCollapseNode(child, true); + } + } + + /** + * Collapse node and calculate the visible removed nodes. + * + * @param node target node to collapse + * @param includeChild should collapse child + * @return the visible addition nodes before remove + */ + public static List collapseNode(TreeNode node, boolean includeChild) { + List treeNodes = performCollapseNode(node, includeChild); + node.setExpanded(false); + return treeNodes; + } + + private static List performCollapseNode(TreeNode node, boolean includeChild) { + List collapseChildren = new ArrayList<>(); + + if (node == null) { + return collapseChildren; + } + if (includeChild) { + node.setExpanded(false); + } + for (TreeNode child : node.getChildren()) { + collapseChildren.add(child); + + if (child.isExpanded()) { + collapseChildren.addAll(performCollapseNode(child, includeChild)); + } else if (includeChild) { + performCollapseNodeInner(child); + } + } + + return collapseChildren; + } + + /** + * Collapse all children node recursive + * + * @param node target node to collapse + */ + private static void performCollapseNodeInner(TreeNode node) { + if (node == null) { + return; + } + node.setExpanded(false); + for (TreeNode child : node.getChildren()) { + performCollapseNodeInner(child); + } + } + + public static void collapseLevel(TreeNode root, int level) { + if (root == null) { + return; + } + for (TreeNode child : root.getChildren()) { + if (child.getLevel() == level) { + collapseNode(child, false); + } else { + collapseLevel(child, level); + } + } + } + + public static List getAllNodes(TreeNode root) { + List allNodes = new ArrayList<>(); + + fillNodeList(allNodes, root); + allNodes.remove(root); + + return allNodes; + } + + private static void fillNodeList(List treeNodes, TreeNode treeNode) { + treeNodes.add(treeNode); + + if (treeNode.hasChild()) { + for (TreeNode child : treeNode.getChildren()) { + fillNodeList(treeNodes, child); + } + } + } + + /** + * Select the node and node's children,return the visible nodes + */ + public static List selectNodeAndChild(TreeNode treeNode, boolean select) { + List expandChildren = new ArrayList<>(); + + if (treeNode == null) { + return expandChildren; + } + + treeNode.setSelected(select); + + if (!treeNode.hasChild()) { + return expandChildren; + } + + if (treeNode.isExpanded()) { + for (TreeNode child : treeNode.getChildren()) { + expandChildren.add(child); + + if (child.isExpanded()) { + expandChildren.addAll(selectNodeAndChild(child, select)); + } else { + selectNodeInner(child, select); + } + } + } else { + selectNodeInner(treeNode, select); + } + return expandChildren; + } + + private static void selectNodeInner(TreeNode treeNode, boolean select) { + if (treeNode == null) { + return; + } + treeNode.setSelected(select); + if (treeNode.hasChild()) { + for (TreeNode child : treeNode.getChildren()) { + selectNodeInner(child, select); + } + } + } + + /** + * Select parent when all the brothers have been selected, otherwise deselect parent, + * and check the grand parent recursive. + */ + public static List selectParentIfNeedWhenNodeSelected(TreeNode treeNode, boolean select) { + List impactedParents = new ArrayList<>(); + if (treeNode == null) { + return impactedParents; + } + + //ensure that the node's level is bigger than 1(first level is 1) + TreeNode parent = treeNode.getParent(); + if (parent == null || parent.getParent() == null) { + return impactedParents; + } + + List brothers = parent.getChildren(); + int selectedBrotherCount = 0; + for (TreeNode brother : brothers) { + if (brother.isSelected()) selectedBrotherCount++; + } + + if (select && selectedBrotherCount == brothers.size()) { + parent.setSelected(true); + impactedParents.add(parent); + impactedParents.addAll(selectParentIfNeedWhenNodeSelected(parent, true)); + } else if (!select && selectedBrotherCount == brothers.size() - 1) { + // only the condition that the size of selected's brothers + // is one less than total count can trigger the deselect + parent.setSelected(false); + impactedParents.add(parent); + impactedParents.addAll(selectParentIfNeedWhenNodeSelected(parent, false)); + } + return impactedParents; + } + + /** + * Get the selected nodes under current node, include itself + */ + public static List getSelectedNodes(TreeNode treeNode) { + List selectedNodes = new ArrayList<>(); + if (treeNode == null) { + return selectedNodes; + } + + if (treeNode.isSelected() && treeNode.getParent() != null) selectedNodes.add(treeNode); + + for (TreeNode child : treeNode.getChildren()) { + selectedNodes.addAll(getSelectedNodes(child)); + } + return selectedNodes; + } + + /** + * Return true when the node has one selected child(recurse all children) at least, + * otherwise return false + */ + public static boolean hasOneSelectedNodeAtLeast(TreeNode treeNode) { + if (treeNode == null || treeNode.getChildren().size() == 0) { + return false; + } + List children = treeNode.getChildren(); + for (TreeNode child : children) { + if (child.isSelected() || hasOneSelectedNodeAtLeast(child)) { + return true; + } + } + return false; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/CheckControlUpdateUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/CheckControlUpdateUtil.java new file mode 100644 index 0000000..2148a39 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/CheckControlUpdateUtil.java @@ -0,0 +1,97 @@ +package com.bingce.controlnetwork.util; + +import android.app.Activity; +import android.content.Context; + +import androidx.appcompat.app.AlertDialog; + +import com.bingce.AppChannel; +import com.bingce.BaseApp; +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.utils.StringUtil; +import com.bingce.utils.UpdateUtils; + +import blankj.utilcode.util.AppUtils; +import blankj.utilcode.util.Utils; + +import com.bingce.controlnetwork.R; + +public class CheckControlUpdateUtil { + public static void checkUpdate(Context context, boolean forceShow) { + String queryUrl = "latestVersionCodeUrlControl"; + if (AppChannel.customChannel == AppChannel.CUSTOM_CONTROL_PRO) { + queryUrl = "latestVersionCodeUrlControlPro"; + } + LeanCloudConfigLoader.findInBackground(queryUrl, instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", queryUrl) +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (context instanceof Activity && ((Activity) context).isFinishing()) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String latestVersionCodeUrl = /*avObjects.get(0).getString("value")*/instance.value; + String updateLog = /*avObjects.get(0).getString("value2")*/instance.value2; + String specialVersions = instance.value3; + boolean isInSpecialVersions = false; + if (StringUtil.isNotEmpty(specialVersions)) { + String[] versionArr = specialVersions.split(",", -2); + int currentVersionCode = AppUtils.getAppVersionCode(); + for (String s : versionArr) { + String[] subVersionArr = s.split("-", -2); + if (subVersionArr.length == 2) { + int v1 = Integer.parseInt(subVersionArr[0]); + int v2 = Integer.parseInt(subVersionArr[1]); + if (currentVersionCode >= v1 && currentVersionCode <= v2) { + isInSpecialVersions = true; + break; + } + } + } + } + String[] arr = latestVersionCodeUrl.split(",", -2); + if (arr.length == 2 && updateLog != null && arr[1].endsWith(".apk")) { + try { + if (isInSpecialVersions) { + UpdateUtils.getInstance().showUpdate(context, updateLog, arr[0], arr[1], forceShow); + } else { + if (forceShow) { + if (Integer.parseInt(arr[0]) > AppUtils.getAppVersionCode()) { + UpdateUtils.getInstance().showUpdate(context, updateLog, arr[0], arr[1], forceShow); + } else { + new AlertDialog.Builder(context) + .setTitle(R.string.hint) + .setMessage(R.string.already_the_latest_version) + .setPositiveButton(R.string.close, null) + .show(); + } + } else { + if (Integer.parseInt(arr[0]) > AppUtils.getAppVersionCode() && Integer.parseInt(arr[0]) > ((BaseApp) Utils.getApp()).ignoredVersionCode) { + UpdateUtils.getInstance().showUpdate(context, updateLog, arr[0], arr[1], forceShow); + } + } + } + } catch (Exception ignored) { + } + } + } +// } +// +// @Override +// public void onError(Throwable e) { +// emergency();//后门,防止leancloud崩溃时会员无法登录 +// } +// +// @Override +// public void onComplete() { +// +// } + }); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/CheckRegUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/CheckRegUtil.java new file mode 100644 index 0000000..5e883a4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/CheckRegUtil.java @@ -0,0 +1,67 @@ +package com.bingce.controlnetwork.util; + +import static com.bingce.utils.RegisterUtil.getOriginalMachineCode; + +import android.Manifest; +import android.content.pm.PackageManager; +import android.os.Build; + +import androidx.core.content.ContextCompat; + +import com.bingce.AppChannel; +import com.bingce.BaseApp; +import com.bingce.utils.ActivateUtil; +import com.bingce.utils.AppUtil; + +import blankj.utilcode.util.Utils; + +public class CheckRegUtil { + /** + * 检查注册码是否有效,仅限offline调用 + * + * @return + * @reg_code 激活码 + */ + public static boolean checkReg(String reg_code) { + if (!((BaseApp) Utils.getApp()).userAgreementAgree) + return false; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {//Q=10,大于安卓10的可能是手薄,不需要检测电话权限 + if (ContextCompat.checkSelfPermission(Utils.getApp(), Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { +// ToastUtils.showShort("为了认证激活信息,请打开读取手机状态权限"); + return false; + } + } + if (AppChannel.customChannel != AppChannel.CUSTOM_INTERNATIONAL + && AppChannel.customChannel != AppChannel.CUSTOM_TERSUS_INTERNATIONAL + && AppChannel.customChannel != AppChannel.CUSTOM_PENTAX_INTERNATIONAL + && AppChannel.customChannel != AppChannel.CUSTOM_SURVEY_SPACE_INTERNATIONAL + && AppChannel.customChannel != AppChannel.CUSTOM_TUNNEL_AUTO_SCAN) { + if (!AppUtil.isZhCN())//国内发行版本在非简体中文语言下不可用 + return false; + } + if ("".equals(getOriginalMachineCode()) + || "SERIALNUMBERunknown".equals(getOriginalMachineCode()) + || "SERIALNUMBERnull".equals(getOriginalMachineCode()) + || "SERIALNUMBER".equals(getOriginalMachineCode())) { + return false; + } + //开始验证 + String machineCode = getOriginalMachineCode(); + String answer; + if (machineCode != null) { + answer = ""; + String md5 = ActivateUtil.encrypt(Utils.getApp(), machineCode, AppChannel.customChannel); + if (md5 != null) { + for (int i = 0; i < md5.length(); i++) { + if (i % 2 == 1) + answer += md5.charAt(i); + } + answer = answer.toUpperCase(); + return reg_code.equals(answer); + } else {//如果返回null,说明破解打包了 + return false; + } + } + return false; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/CrashCollectUtils.java b/app/src/main/java/com/bingce/controlnetwork/util/CrashCollectUtils.java new file mode 100644 index 0000000..e433601 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/CrashCollectUtils.java @@ -0,0 +1,101 @@ +package com.bingce.controlnetwork.util; + +import android.content.Context; + +import com.bingce.utils.FileUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.FileUtils; +import blankj.utilcode.util.Utils; + +public class CrashCollectUtils { + public static File crashLogFolder(Context context) { + File cacheFolder = context.getExternalCacheDir(); + if (!cacheFolder.exists() || cacheFolder.isFile()) { + cacheFolder.mkdir(); + } + File dir = new File(cacheFolder, "crash"); + if (!dir.exists() || dir.isFile()) { + dir.mkdir(); + } + return dir; + } + + //收集崩溃日志,在处理完成后根据结果删除 + public static void collectCrashLogInWorkerThread(ICrashLogCollectListener listener) { + File dir = crashLogFolder(Utils.getApp().getApplicationContext()); + //读取其下面的数据 + if (!dir.exists() || dir.isFile()) { + return; + } + + StringBuilder sb = new StringBuilder(); + + File[] files = dir.listFiles(); + + if (files != null) { + List needMoveFileList = new ArrayList<>(); + File lastFile = null; + for (File file : files) { + if (file == null || !file.isFile()) { + continue; + } + + if (lastFile == null) { + lastFile = file; + } else { + if (file.lastModified() > lastFile.lastModified()) { + lastFile = file; + } + } + + needMoveFileList.add(file); + } + needMoveFileList.remove(lastFile); + + for (File file : needMoveFileList) { + moveToBackedUpFolder(dir, file); + } + + if (lastFile != null) { + FileUtil.ReadFileResult readFileResult = FileUtil.readStringFrom(lastFile); + if (readFileResult.success) { + sb.append(readFileResult.string).append("\n"); + } + } + } + + String CRASH_LOG_TABLE = "CloudCrashLog"; + final String contentKey = "crash_content"; + final String fileNameKey = "file_name"; + final String appLabelKey = "app"; + final String uuidKey = "UUID"; + listener.onCollected(CRASH_LOG_TABLE, appLabelKey, fileNameKey, contentKey, uuidKey, sb.toString()); + } + + private static void moveToBackedUpFolder(File dir, File targetLogFile) { + File repeatedFolder = new File(dir, "BACKED_UP"); + if (!repeatedFolder.exists()) { + repeatedFolder.mkdirs(); + } + FileUtils.move(targetLogFile, new File(repeatedFolder, targetLogFile.getName())); + } + + public interface ICrashLogCollectListener { + void onCollected(String cloudTable, String appLabelKey, String fileNameKey, String contentKey, String uuidKey, + String content); + } + + public static class CrashItem { + public final File file; + public final String content; + + CrashItem(File file, String content) { + this.file = file; + this.content = content; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/DefaultNameUtil.kt b/app/src/main/java/com/bingce/controlnetwork/util/DefaultNameUtil.kt new file mode 100644 index 0000000..52a0cd1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/DefaultNameUtil.kt @@ -0,0 +1,29 @@ +package com.bingce.controlnetwork.util + +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +object DefaultNameUtil { + /** + * DateUtils.ymdWithCharacter(Date()) + */ + @JvmStatic + fun getDefaultProjectName(): String { + val format = Tools.getString(R.string.default_project_format) + val simpleDateFormat = SimpleDateFormat(format, Locale.getDefault()) + return simpleDateFormat.format(Date()) + } + + /** + * DateUtils.ymdHMSWithCharacter(Date()) + */ + @JvmStatic + fun getDefaultPeriodName(): String { + val format = Tools.getString(R.string.default_period_format) + val simpleDateFormat = SimpleDateFormat(format, Locale.getDefault()) + return simpleDateFormat.format(Date()) + } +} \ No newline at end of file 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/ImportPointsUtilPla.java b/app/src/main/java/com/bingce/controlnetwork/util/ImportPointsUtilPla.java new file mode 100644 index 0000000..6e771d7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/ImportPointsUtilPla.java @@ -0,0 +1,265 @@ +package com.bingce.controlnetwork.util; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.Fragment; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.BaseApp; +import com.bingce.controlapphelper.R; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.importpoint.PointLibraryUtil; +import com.bingce.surveyor.agentweb.AgentWebActivity; +import com.bingce.utils.ThreadPoolUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import ru.bartwell.exfilepicker.ExFilePicker; +import ru.bartwell.exfilepicker.data.ExFilePickerResult; + +public class ImportPointsUtilPla { + private static final int THEME = android.R.style.Theme_Material_Dialog_Alert; + // private static final int THEME = android.R.style.ThemeOverlay_Material_Dialog_Alert; + @NonNull + private final Fragment fragment; + @NonNull + private final ActivityResultLauncher activityResultLauncher; + private String projectId; + private String pointType; + private Context mContext; + private ImportFileType importFileType; + + public ImportPointsUtilPla(@NonNull Fragment fragment) { + this.fragment = fragment; + activityResultLauncher = fragment.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result != null && Activity.RESULT_OK == result.getResultCode()) { + Intent data = result.getData(); + if (data != null) { + ExFilePickerResult object = ExFilePickerResult.getFromIntent(data); + if (object != null && object.getCount() > 0) { + try { + String path = object.getPath() + object.getNames().get(0); + List list = new ArrayList<>(); + String error = null; + switch (importFileType) { + case EXCLE: + error = PointLibraryUtil.importStakingJobPointExcel(new File(path), + (name, code, x, y, z, remarks) -> addPointToList(list, projectId, pointType, name, code, x, y, z, remarks, list.size())); + break; + case TEXT: + error = PointLibraryUtil.importStakingJobPointTxt(new File(path), + (name, code, x, y, z, remarks) -> addPointToList(list, projectId, pointType, name, code, x, y, z, remarks, list.size())); + break; + case CASS: + error = PointLibraryUtil.importStakingJobPointCassDat(new File(path), isCassXY(), + (name, code, x, y, z, remarks) -> addPointToList(list, projectId, pointType, name, code, x, y, z, remarks, list.size())); + break; + } + if (!TextUtils.isEmpty(error)) { + ToastUtils.showShort(error); + } + if (!list.isEmpty()) { + saveRecord(list); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + } else { + ToastUtils.showShort(R.string.file_is_empty); + } + } + } + }); + } + + /** + * 存储数据 + * 查询是否有同名点 有同名提示是否覆盖点坐标信息,没有同名直接保存 + * + * @param list 读取的导入点列表 + */ + private void saveRecord(List list) { + Object waitObj = new Object(); + ThreadPoolUtil.execute(() -> { + //获取已有的数据点 + List pointListAgo = SurveyorDatabaseFactory.instance.getPointDataSource().getListByProjectId(projectId, pointType); + Map pointRecordAgoMap = new HashMap<>(); + for (PointRecord pointRecordAgo : pointListAgo) { + pointRecordAgoMap.put(pointRecordAgo.getName(), pointRecordAgo); + } + //遍历要导入的数据点 + for (PointRecord pointRecordImport : list) { + if (pointRecordAgoMap.containsKey(pointRecordImport.getName())) { + //存在同名 提示是否覆盖 + showOverrideDialog(waitObj, pointRecordAgoMap.get(pointRecordImport.getName()), pointRecordImport); + synchronized (waitObj) { + try { + waitObj.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } else { + savePointRecord(pointRecordImport); + } + } + }); + } + + @WorkerThread + private void savePointRecord(PointRecord pointRecord) { + SurveyorDatabaseFactory.instance.getPointDataSource().saveSync(pointRecord); + } + + private void showOverrideDialog(Object waitObj, PointRecord pointRecordAgo, PointRecord pointImport) { + ThreadPoolUtil.executeInMain(() -> { + new MaterialDialog.Builder(mContext) + .title("提示") + .content("点名:" + pointRecordAgo.getName() + "重复,是否覆盖?") + .positiveText("覆盖") + .negativeText("不覆盖") + .neutralText("取消") + .onPositive((dialog, which) -> { + ThreadPoolUtil.execute(() -> { + synchronized (waitObj) { + pointRecordAgo.x = pointImport.x; + pointRecordAgo.y = pointImport.y; + pointRecordAgo.z = pointImport.z; + pointRecordAgo.remarks = pointImport.remarks; + pointRecordAgo.code = pointImport.code; + pointRecordAgo.category = pointImport.category; + savePointRecord(pointRecordAgo); + waitObj.notify(); + } + }); + }) + .onNegative((dialog, which) -> { + synchronized (waitObj) { + waitObj.notify(); + } + }) + .show(); + }); + } + + private void addPointToList(List list, String projectId, String pointType, String name, String code, double x, double y, double z, String remarks, int orderIndex) { + PointRecord point = PointRecord.point( + projectId, pointType, name, code, + x, y, z, + remarks, list.size()); + list.add(point); + } + + /** + * 入口 + * + * @param projectId + * @param pointType + */ + public void showImportDialog(String projectId, String pointType) { + this.projectId = projectId; + this.pointType = pointType; + mContext = fragment.requireContext(); + + importFileType = null; + + new MaterialDialog.Builder(mContext) + .title(R.string.please_choose_import_format) + .items(new String[]{mContext.getString(R.string.excel_xls) + , mContext.getString(R.string.text_txt) + , mContext.getString(R.string.cass_dat_txt)}) + .itemsCallback((dialog, itemView, which, text) -> { + switch (which) { + case 0: + importFileType = ImportFileType.EXCLE; + break; + case 1: + importFileType = ImportFileType.TEXT; + break; + case 2: + importFileType = ImportFileType.CASS; + break; + } + + if (importFileType != null) { + showImportAppendOrOverideDialog(); + } + + }).show(); + } + + private void showImportAppendOrOverideDialog() { + String message = ""; + switch (importFileType) { + case EXCLE: + message = mContext.getString(R.string.import_point_excel_guide); + break; + case TEXT: + message = mContext.getString(R.string.import_point_text_guide); + break; + case CASS: + if (isCassXY()) { + message = mContext.getString(R.string.import_point_cass_xy_dat); + } else { + message = mContext.getString(R.string.import_point_cass_yx_dat); + } + break; + } + + new MaterialDialog.Builder(mContext) + .title(R.string.import_points) + .content(message) + .positiveText(R.string.import_points) + .neutralText(R.string.view_sample) + .onPositive((dialog, which) -> checkStoragePermission()) + .onNeutral((dialog, which) -> { + AgentWebActivity.navigation2(mContext, "android_url_import_point_sample"); + }) + .show(); + + } + + private void checkStoragePermission() { + CheckStorageUtil.check(mContext, this::selectFolder); + } + + private void selectFolder() { + BaseApp app = (BaseApp) Utils.getApp(); + ExFilePicker exFilePicker = new ExFilePicker(); + exFilePicker.setLandscape(app.isLandscape()); + exFilePicker.setShowOnlyExtensions(importFileType.filters); + activityResultLauncher.launch(exFilePicker.createIntent(fragment.requireContext())); + } + + private enum ImportFileType { + EXCLE(new String[]{"xls", "xlsx"}), + TEXT(new String[]{"txt"}), + CASS(new String[]{"dat", "txt"}); + + private String[] filters; + + ImportFileType(String[] filters) { + this.filters = filters; + } + } + + private boolean isCassXY() { + return false; + } + +} 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..4dafc29 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/SelectDeviceTypeUtil.java @@ -0,0 +1,47 @@ +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: + connectTsActivity(); + break; + case 1: + connectLevelActivity(); + break; + } + } + }).show(); + } + + public static void connectTsActivity() { + Intent intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); + intent.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent); + } + + public static void connectLevelActivity() { + Intent intent2 = new Intent(ActivityUtils.getTopActivity(), ConnectLevelActivity.class); + intent2.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent2); + } + + +} 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/SurveyorStationUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/SurveyorStationUtil.java new file mode 100644 index 0000000..7e0d407 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/SurveyorStationUtil.java @@ -0,0 +1,126 @@ +package com.bingce.controlnetwork.util; + +import android.content.Context; + +import androidx.annotation.MainThread; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.utils.IOnSingleGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +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; + +public class SurveyorStationUtil { + @MainThread + public static void editLine(Context context, String lineId) { + ThreadPoolUtil.execute(() -> { + LineRecord stationBatchRecord = + SurveyorDatabaseFactory.instance.getLineRecordDatabase().findById(lineId); + if (stationBatchRecord == null) { + return; + } +// //1.查询该线路下所有测站 +// List stationRecordList = +// SurveyorDatabaseFactory.instance.getSurveyorStation().getDataListByLine(stationBatchRecord.id); +// //2.遍历测站,检测是否有测量数据 +// if (stationRecordList != null) { +// for (SurveyorStationRecord record : stationRecordList) { +// if (record == null) { +// continue; +// } +// long count = SurveyorDatabaseFactory +// .instance +// .getSurveyorRecordDataSource() +// .recordCount(record.id); +// if (count > 0) {//如果有测量数据,则该导线不能编辑 +// ThreadPoolUtil.executeInMain(() -> TipsFragment.tipsOnly(fragmentManager, +// lifecycleOwner, +// context, +// context.getString(R.string.tips_forbid_edit_line_because_has_surveyor_record))); +// return; +// } +// } +// } + if (LineRecord.TYPE_LINE_SINGLE.equals(stationBatchRecord.type)) { + LineStationSingleSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_LINE_ATTACH.equals(stationBatchRecord.type)) { + LineStationAttachedSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_LINE_CLOSE.equals(stationBatchRecord.type)) { + LineStationCloseSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_LINE_RANDOM.equals(stationBatchRecord.type)) { + LineStationRandomSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_WELL.equals(stationBatchRecord.type)) { + LineStationWellSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_WELL_DOUBLE_GROUND.equals(stationBatchRecord.type)) { + LineStationWellDoubleGroundSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_WELL_DOUBLE_UNDERGROUND.equals(stationBatchRecord.type)) { + LineStationWellDoubleUnderGroundSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } + }); + } + + @MainThread + public static void getBatchItemList(String lineId, IOnSingleGetCallback callback) { + ThreadPoolUtil.execute(() -> { + LineRecord batchRecord = + SurveyorDatabaseFactory.instance.getLineRecordDatabase() + .findById(lineId); + if (batchRecord == null) { + return; + } + callback.onGet(batchRecord); + }); + } + + @MainThread + public static void updateLineRecord(LineRecord lineRecord) { + if (lineRecord == null) return; + SurveyorDatabaseFactory.instance.getLineRecordDatabase().update(lineRecord); + } + + @MainThread + public static void updateStationPointsMeasureHorAag(LineRecord lineRecord) { + if (lineRecord == null) return; + List stationDetailList = lineRecord.items; + if (stationDetailList == null) { + return; + } + + ThreadPoolUtil.execute(() -> { + List stationRecordList = SurveyorDatabaseFactory.instance.getSurveyorStation().getDataListByLine(lineRecord.id); + if (stationRecordList != null && !stationRecordList.isEmpty()) { + for (SurveyorStationRecord record : stationRecordList) { + List items = record.items; + if (items == null) { + continue; + } + for (SurveyorPoint point : items) { + for (StationDetailItem stationDetailItem : stationDetailList) { + if (point != null && point.getOriginalPointId().equals(stationDetailItem.getOriginalPointId()) + && point.isWellSteel() != point.isWellSteel()) { + // TODO: 2023/5/22 + point.setWellSteel(stationDetailItem.isWellSteel()); + SurveyorDatabaseFactory.instance.getSurveyorStation().update(record); + } + } + } + } + } + }); + + + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/config/AbstractSetConfigs.java b/app/src/main/java/com/bingce/controlnetwork/util/config/AbstractSetConfigs.java new file mode 100644 index 0000000..3399c69 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/config/AbstractSetConfigs.java @@ -0,0 +1,80 @@ +package com.bingce.controlnetwork.util.config; + +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class AbstractSetConfigs { + private final Map list = new LinkedHashMap<>(); + + protected AbstractSetConfigs() { + } + + public void foreach(IConfigItemCallback callback) { + if (callback == null) { + return; + } + for (ConfigItem configItem : list.values()) { + callback.on(configItem); + } + } + + public ConfigItem get(int id) { + return list.get(id); + } + + public String allIds() { + return ConfigItem.ids(list.values()); + } + + public String defaultIds() { + return allIds(); + } + +// private static AbstractSetConfigs instance = null; +// +// public static AbstractSetConfigs getInstance() { +// synchronized (ParameterSetConfigs.class) { +// if (instance == null) { +// instance = new ParameterSetConfigs(); +// init(); +// } +// } +// return instance; +// } + + public void init() { + init(list); + } + + protected abstract void init(final Map list);// { +// list.put(99, new ConfigItem(99, R.string.road_project_management, R.mipmap.icon_parameter_road_project, DragIconInfo.CATEGORY_ONLY)); +// list.put(100, new ConfigItem(100, R.string.road_parameter, R.mipmap.icon_parameter_road, DragIconInfo.CATEGORY_ONLY)); +// list.put(101, new ConfigItem(101, R.string.break_chain, R.mipmap.icon_parameter_breakchain, DragIconInfo.CATEGORY_ONLY)); +// list.put(102, new ConfigItem(102, R.string.hor_parameter, R.mipmap.icon_parameter_hor, DragIconInfo.CATEGORY_ONLY)); +// list.put(103, new ConfigItem(103, R.string.ver_parameter, R.mipmap.icon_parameter_ver, DragIconInfo.CATEGORY_ONLY)); +// list.put(104, new ConfigItem(104, R.string.standard_cross_section, R.mipmap.icon_parameter_stand_cross_section, DragIconInfo.CATEGORY_ONLY)); +// list.put(105, new ConfigItem(105, R.string.super_elevation, R.mipmap.icon_parameter_super, DragIconInfo.CATEGORY_ONLY)); +// list.put(106, new ConfigItem(106, R.string.widen_change, R.mipmap.icon_parameter_widen, DragIconInfo.CATEGORY_ONLY)); +// list.put(107, new ConfigItem(107, R.string.tunnel_section_library, R.mipmap.icon_parameter_tunnel_section_library, DragIconInfo.CATEGORY_ONLY)); +// list.put(108, new ConfigItem(108, R.string.tcs_matching, R.mipmap.icon_parameter_tunnel_section_matching, DragIconInfo.CATEGORY_ONLY)); +// list.put(109, new ConfigItem(109, R.string.middle_line_offset, R.mipmap.icon_parameter_middle_line_offset, DragIconInfo.CATEGORY_ONLY)); +// list.put(110, new ConfigItem(110, R.string.subway_center_up_down, R.mipmap.icon_parameter_subway_updown, DragIconInfo.CATEGORY_ONLY)); +// list.put(111, new ConfigItem(111, R.string.tcs_feature_point, R.mipmap.icon_parameter_tunnel_feanture_points, DragIconInfo.CATEGORY_ONLY)); +// list.put(112, new ConfigItem(112, R.string.tunnel_embedded_part, R.mipmap.icon_parameter_tunnel_embedded_part, DragIconInfo.CATEGORY_ONLY)); +// list.put(113, new ConfigItem(113, R.string.tcs_rotate, R.mipmap.icon_parameter_tunnel_rotate, DragIconInfo.CATEGORY_ONLY)); +// list.put(114, new ConfigItem(114, R.string.control_point, R.mipmap.icon_parameter_points, DragIconInfo.CATEGORY_ONLY)); +// list.put(115, new ConfigItem(115, R.string.side_section_library, R.mipmap.icon_parameter_side_library, DragIconInfo.CATEGORY_ONLY)); +// list.put(116, new ConfigItem(116, R.string.scs_matching, R.mipmap.icon_parameter_side_section_matching, DragIconInfo.CATEGORY_ONLY)); +// list.put(117, new ConfigItem(117, R.string.subway_common_parameters, R.mipmap.icon_parameter_subway_common_parameters, DragIconInfo.CATEGORY_ONLY)); +// list.put(118, new ConfigItem(118, R.string.tbm_reference_point, R.mipmap.icon_parameter_subway_tbm_reference_point, DragIconInfo.CATEGORY_ONLY)); +// list.put(119, new ConfigItem(119, R.string.staking_point_library, R.mipmap.icon_parameter_staking_point_library, DragIconInfo.CATEGORY_ONLY)); +// list.put(120, new ConfigItem(120, R.string.point_survey_point_library, R.mipmap.icon_program_point_survey, DragIconInfo.CATEGORY_ONLY)); +// list.put(121, new ConfigItem(121, R.string.pier_template_library, R.mipmap.icon_parameter_pier_template_library, DragIconInfo.CATEGORY_ONLY)); +// list.put(122, new ConfigItem(122, R.string.bridge_and_layout, R.mipmap.icon_parameter_pier_layout, DragIconInfo.CATEGORY_ONLY)); +// if (AppChannel.customChannel == AppChannel.CUSTOM_ZJYGJ) { +// list.put(123, new ConfigItem(123, R.string.menu_item_zjygj_project_list, R.mipmap.icon_road_project_list_zjygj, DragIconInfo.CATEGORY_ONLY)); +// } +// } + +// public abstract void onItemClick(int id, Fragment fragment); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigItem.java b/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigItem.java new file mode 100644 index 0000000..630759f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigItem.java @@ -0,0 +1,86 @@ +package com.bingce.controlnetwork.util.config; + +import android.content.Context; + +import com.wedcel.dragexpandgrid.model.DragIconInfo; + +import java.util.ArrayList; +import java.util.Collection; + +public class ConfigItem { + public ConfigItem(int id, int title, int icon, int category) { + this.id = id; + this.title = title; + this.icon = icon; + this.category = category; + } + + private int id; + private int title; + private int icon; + int category; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getTitle() { + return title; + } + + public void setTitle(int title) { + this.title = title; + } + + public int getIcon() { + return icon; + } + + public void setIcon(int icon) { + this.icon = icon; + } + + public int getCategory() { + return category; + } + + public void setCategory(int category) { + this.category = category; + } + + private static int readStringResId(Context context, String name) { + return context.getResources().getIdentifier(name, "string", context.getPackageName()); + } + + private static int readMipmapResId(Context context, String name) { + return context.getResources().getIdentifier(name, "mipmap", context.getPackageName()); + } + + private static String readStringValue(Context context, String name) { + return context.getString(readStringResId(context, name)); + } + + public DragIconInfo convert(Context context) { + return new DragIconInfo( + getId(), + context.getString(getTitle()), + getIcon(), + DragIconInfo.CATEGORY_ONLY, + false, + new ArrayList<>()); + } + + public static String ids(Collection list) { + StringBuilder builder = new StringBuilder(); + for (ConfigItem item : list) { + builder + .append(item.getId()) + .append(","); + } + return builder.toString(); + } +} 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 new file mode 100644 index 0000000..c3d761e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigsSetConfigs.java @@ -0,0 +1,90 @@ +package com.bingce.controlnetwork.util.config; + +import android.content.Context; +import android.content.Intent; + +import com.bingce.AppChannel; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.ConfigFragment; +import com.bingce.controlnetwork.fragment.PointListFragment; +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.device.ui.ConnectTSActivity; +import com.wedcel.dragexpandgrid.model.DragIconInfo; + +import java.util.Map; + +public class ConfigsSetConfigs extends AbstractSetConfigs { + + private final static int FUC_INSTRUMENTMANAGEMENT = 101; //仪器管理 + private final static int FUC_GLOBAL_CONTROL_POINT = 102;//全局控制点 + private final static int FUC_EXPORT_STATION = 103; //观测数据导出 + private final static int FUC_EXPORT_WIRE_FILE = 104;//导线文件导出 + private final static int FUC_TOLERANCE_MANAGER = 105;//自定义限差管理 + private final static int FUC_PRISM_MANAGER = 106;//棱镜管理 + private final static int FUC_HEIGHT_TRAVERSE_EXPORT = 107;//高程导线数据导出 + + @Override + protected void init(Map list) { + list.put(FUC_INSTRUMENTMANAGEMENT, + 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, + new ConfigItem(FUC_EXPORT_STATION, R.string.export, R.drawable.ic_export, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_EXPORT_WIRE_FILE, + new ConfigItem(FUC_EXPORT_WIRE_FILE, R.string.export_wire_file, R.drawable.ic_export_wire, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_TOLERANCE_MANAGER, + new ConfigItem(FUC_TOLERANCE_MANAGER, R.string.name_custom_telorance_manager, R.drawable.ic_custom_tolerance, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_PRISM_MANAGER, + new ConfigItem(FUC_PRISM_MANAGER, R.string.prism_manager, R.drawable.icon_prism_manager, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_HEIGHT_TRAVERSE_EXPORT, + new ConfigItem(FUC_HEIGHT_TRAVERSE_EXPORT, R.string.export_height_traverse, R.drawable.ic_export_height_traverse, DragIconInfo.CATEGORY_ONLY)); + } + + private static ConfigsSetConfigs instance = null; + + public static ConfigsSetConfigs getInstance() { + if (instance == null) { + synchronized (ConfigsSetConfigs.class) { + if (instance == null) { + instance = new ConfigsSetConfigs(); + instance.init(); + } + } + } + return instance; + } + + public void onItemClick(int id, ConfigFragment fragment) { + Context context = fragment.requireContext(); + switch (id) { + case FUC_INSTRUMENTMANAGEMENT://仪器管理 + Intent intent = new Intent(context, ConnectTSActivity.class); + intent.putExtra("customChannel", AppChannel.customChannel); + context.startActivity(intent); + break; + case FUC_GLOBAL_CONTROL_POINT://全局控制点 + PointListFragment.go2GlobalPointList(context); + break; + case FUC_EXPORT_STATION://观测数据导出 + SelectExportSurveyorRecordFragment.start(context, null); + break; + case FUC_EXPORT_WIRE_FILE://导线文件导出 + SelectExportSurveyorRecordWireFileFragment.start(context); + break; + case FUC_TOLERANCE_MANAGER://自定义限差管理 + ToleranceManageFragment.start(context, null); + break; + case FUC_PRISM_MANAGER://棱镜管理 + PrismManageFragment.start(context); + break; + case FUC_HEIGHT_TRAVERSE_EXPORT://高程导线数据导出 + SelectExportHeightTraverseFragment.start(context); + break; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/util/config/IConfigItemCallback.java b/app/src/main/java/com/bingce/controlnetwork/util/config/IConfigItemCallback.java new file mode 100644 index 0000000..4c23deb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/config/IConfigItemCallback.java @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.util.config; + +public interface IConfigItemCallback { + void on(ConfigItem item); +} 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/Constants.java b/app/src/main/java/com/bingce/controlnetwork/wxapi/Constants.java new file mode 100644 index 0000000..9e79cf1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/wxapi/Constants.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.wxapi; + +public class Constants { + + //appid 微信分配的ID + public static final String APP_ID = "wx8b41ad369eba83a9"; +} diff --git a/app/src/main/java/com/bingce/controlnetwork/wxapi/MD5.java b/app/src/main/java/com/bingce/controlnetwork/wxapi/MD5.java new file mode 100644 index 0000000..3357702 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/wxapi/MD5.java @@ -0,0 +1,26 @@ +package com.bingce.controlnetwork.wxapi; + +import java.security.MessageDigest; + +public class MD5 { + + public static String getMessageDigest(byte[] buffer) { + char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + try { + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(buffer); + byte[] md = mdTemp.digest(); + int j = md.length; + char[] str = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str); + } catch (Exception e) { + return null; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java new file mode 100644 index 0000000..545dc39 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java @@ -0,0 +1,109 @@ +package com.bingce.controlnetwork.wxapi; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; + +import com.bingce.controlnetwork.R; +import com.bingce.event.WxRespCodeEvent; +import com.tencent.mm.opensdk.constants.ConstantsAPI; +import com.tencent.mm.opensdk.modelbase.BaseReq; +import com.tencent.mm.opensdk.modelbase.BaseResp; +import com.tencent.mm.opensdk.modelmsg.SendAuth; +import com.tencent.mm.opensdk.openapi.IWXAPI; +import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler; +import com.tencent.mm.opensdk.openapi.WXAPIFactory; + +import org.greenrobot.eventbus.EventBus; + +import blankj.utilcode.util.ToastUtils; +import cn.leancloud.LCObject; +import cn.leancloud.LCUser; + +public class WXEntryActivity extends Activity implements IWXAPIEventHandler { + // IWXAPI 是第三方app和微信通信的openapi接口 + private IWXAPI api; + public static final String APPID = "wx8b41ad369eba83a9"; + public static final String SECRET = "de5faa683f384095d79c6a75305c2bf0"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // 通过WXAPIFactory工厂,获取IWXAPI的实例 + api = WXAPIFactory.createWXAPI(this, APPID, false); + api.handleIntent(getIntent(), this); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + api.handleIntent(intent, this); + } + + // 微信发送请求到第三方应用时,会回调到该方法 + @Override + public void onReq(BaseReq req) { + } + + @Override + public void onResp(BaseResp resp) { + if (resp.getType() == ConstantsAPI.COMMAND_SENDAUTH) { + switch (resp.errCode) { + case BaseResp.ErrCode.ERR_OK: + String code = ((SendAuth.Resp) resp).code; + EventBus.getDefault().post(new WxRespCodeEvent(code)); + break; + case BaseResp.ErrCode.ERR_USER_CANCEL: + ToastUtils.showShort("User cancel"); + break; + case BaseResp.ErrCode.ERR_AUTH_DENIED: + ToastUtils.showShort("Auth denied"); + break; + case BaseResp.ErrCode.ERR_COMM: + ToastUtils.showShort("Error Comm"); + break; + case BaseResp.ErrCode.ERR_SENT_FAILED: + ToastUtils.showShort("Send failed"); + break; + case BaseResp.ErrCode.ERR_UNSUPPORT: + ToastUtils.showShort("Error unsupported"); + break; + case BaseResp.ErrCode.ERR_BAN: + ToastUtils.showShort("Error ban"); + break; + } + } else if (resp.getType() == ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX) { + switch (resp.errCode) { + case BaseResp.ErrCode.ERR_OK: + ToastUtils.showShort(R.string.share_success); + if (LCUser.getCurrentUser() != null) { + LCObject shareLog = new LCObject("ShareLog"); + shareLog.put("user", LCUser.getCurrentUser()); + shareLog.put("shareType", "wechat"); + shareLog.saveInBackground().subscribe(); + } + break; + case BaseResp.ErrCode.ERR_USER_CANCEL: + ToastUtils.showShort(R.string.share_cancel); + break; + case BaseResp.ErrCode.ERR_AUTH_DENIED: + ToastUtils.showShort(R.string.share_denied); + break; + case BaseResp.ErrCode.ERR_COMM: + ToastUtils.showShort("Error Comm"); + break; + case BaseResp.ErrCode.ERR_SENT_FAILED: + ToastUtils.showShort("Send failed"); + break; + case BaseResp.ErrCode.ERR_UNSUPPORT: + ToastUtils.showShort("Error unsupported"); + break; + case BaseResp.ErrCode.ERR_BAN: + ToastUtils.showShort("Error ban"); + break; + } + } + finish(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/wxapi/WXPayEntryActivity.java b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXPayEntryActivity.java new file mode 100644 index 0000000..c6b8fe5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXPayEntryActivity.java @@ -0,0 +1,51 @@ +package com.bingce.controlnetwork.wxapi; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +import com.bingce.event.PayOverEvent; +import com.tencent.mm.opensdk.constants.ConstantsAPI; +import com.tencent.mm.opensdk.modelbase.BaseReq; +import com.tencent.mm.opensdk.modelbase.BaseResp; +import com.tencent.mm.opensdk.openapi.IWXAPI; +import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler; +import com.tencent.mm.opensdk.openapi.WXAPIFactory; + +import org.greenrobot.eventbus.EventBus; + +public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { + private IWXAPI api; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + api = WXAPIFactory.createWXAPI(this, Constants.APP_ID); + api.handleIntent(getIntent(), this); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + api.handleIntent(intent, this); + } + + @Override + public void onReq(BaseReq req) { + } + + @Override + public void onResp(BaseResp resp) { + if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { + if (resp.errCode == 0) { + Log.d("WXPayEntryActivity", "Wechat pay success"); + } else { + Log.d("WXPayEntryActivity", "Wechat pay failed,errorCode:" + resp.errCode); + } + EventBus.getDefault().post(new PayOverEvent()); + } + finish(); + } +} \ No newline at end of file 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/anim/fade_in_quick.xml b/app/src/main/res/anim/fade_in_quick.xml new file mode 100644 index 0000000..d418d73 --- /dev/null +++ b/app/src/main/res/anim/fade_in_quick.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/fade_out_quick.xml b/app/src/main/res/anim/fade_out_quick.xml new file mode 100644 index 0000000..f7ebe07 --- /dev/null +++ b/app/src/main/res/anim/fade_out_quick.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_left.xml b/app/src/main/res/anim/slide_in_left.xml new file mode 100644 index 0000000..3921f79 --- /dev/null +++ b/app/src/main/res/anim/slide_in_left.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_right.xml b/app/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000..105e2df --- /dev/null +++ b/app/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_left.xml b/app/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000..3375d2c --- /dev/null +++ b/app/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_right.xml b/app/src/main/res/anim/slide_out_right.xml new file mode 100644 index 0000000..1f58f97 --- /dev/null +++ b/app/src/main/res/anim/slide_out_right.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/icon_small.png b/app/src/main/res/drawable-hdpi/icon_small.png new file mode 100644 index 0000000..9b1f17e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_small.png differ diff --git a/app/src/main/res/drawable-v21/blue_bg.xml b/app/src/main/res/drawable-v21/blue_bg.xml new file mode 100644 index 0000000..c5476cd --- /dev/null +++ b/app/src/main/res/drawable-v21/blue_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v21/fab_label_background.xml b/app/src/main/res/drawable-v21/fab_label_background.xml new file mode 100644 index 0000000..bd7694d --- /dev/null +++ b/app/src/main/res/drawable-v21/fab_label_background.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v21/ic_keyboard_arrow_right_white_24px.xml b/app/src/main/res/drawable-v21/ic_keyboard_arrow_right_white_24px.xml new file mode 100644 index 0000000..8ca5856 --- /dev/null +++ b/app/src/main/res/drawable-v21/ic_keyboard_arrow_right_white_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-v23/app_background.xml b/app/src/main/res/drawable-v23/app_background.xml new file mode 100644 index 0000000..0c6828d --- /dev/null +++ b/app/src/main/res/drawable-v23/app_background.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v23/icon_control_logo.png b/app/src/main/res/drawable-v23/icon_control_logo.png new file mode 100644 index 0000000..7c6ad3b Binary files /dev/null and b/app/src/main/res/drawable-v23/icon_control_logo.png differ diff --git a/app/src/main/res/drawable-v23/icon_control_text.png b/app/src/main/res/drawable-v23/icon_control_text.png new file mode 100644 index 0000000..a59c39c Binary files /dev/null and b/app/src/main/res/drawable-v23/icon_control_text.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp__ic_file.png b/app/src/main/res/drawable-xxhdpi/efp__ic_file.png new file mode 100644 index 0000000..b16f633 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp__ic_file.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp__ic_folder.png b/app/src/main/res/drawable-xxhdpi/efp__ic_folder.png new file mode 100644 index 0000000..34d99b4 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp__ic_folder.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp__ic_up.png b/app/src/main/res/drawable-xxhdpi/efp__ic_up.png new file mode 100644 index 0000000..365dc98 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp__ic_up.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_cancel.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_cancel.png new file mode 100644 index 0000000..1882222 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_cancel.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_deselect.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_deselect.png new file mode 100644 index 0000000..d584a20 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_deselect.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_grid.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_grid.png new file mode 100644 index 0000000..7ba62af Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_grid.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_invert_selection.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_invert_selection.png new file mode 100644 index 0000000..14a209d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_invert_selection.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_list.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_list.png new file mode 100644 index 0000000..1d49459 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_list.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_new_folder.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_new_folder.png new file mode 100644 index 0000000..d40425b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_new_folder.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_ok.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_ok.png new file mode 100644 index 0000000..3121792 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_ok.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_select_all.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_select_all.png new file mode 100644 index 0000000..001be8e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_select_all.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_sort.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_sort.png new file mode 100644 index 0000000..f5576db Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_sort.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_storage.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_storage.png new file mode 100644 index 0000000..d361dd6 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_storage.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_back.png b/app/src/main/res/drawable-xxhdpi/icon_back.png new file mode 100644 index 0000000..85690e7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_back.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon.png b/app/src/main/res/drawable-xxxhdpi/icon.png new file mode 100644 index 0000000..c3623f3 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon.png differ diff --git a/app/src/main/res/drawable/app_background.xml b/app/src/main/res/drawable/app_background.xml new file mode 100644 index 0000000..c3a462d --- /dev/null +++ b/app/src/main/res/drawable/app_background.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/app_logo.xml b/app/src/main/res/drawable/app_logo.xml new file mode 100644 index 0000000..d808488 --- /dev/null +++ b/app/src/main/res/drawable/app_logo.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/baseline_reorder_grey_600_24dp.xml b/app/src/main/res/drawable/baseline_reorder_grey_600_24dp.xml new file mode 100644 index 0000000..464d5c6 --- /dev/null +++ b/app/src/main/res/drawable/baseline_reorder_grey_600_24dp.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/bg_circle_white_chatui.xml b/app/src/main/res/drawable/bg_circle_white_chatui.xml new file mode 100644 index 0000000..39f83b6 --- /dev/null +++ b/app/src/main/res/drawable/bg_circle_white_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_gray_3.xml b/app/src/main/res/drawable/bg_gray_3.xml new file mode 100644 index 0000000..ef1e19d --- /dev/null +++ b/app/src/main/res/drawable/bg_gray_3.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_spinner.xml b/app/src/main/res/drawable/bg_spinner.xml new file mode 100644 index 0000000..4a104ec --- /dev/null +++ b/app/src/main/res/drawable/bg_spinner.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_splash.xml b/app/src/main/res/drawable/bg_splash.xml new file mode 100644 index 0000000..5efe8a6 --- /dev/null +++ b/app/src/main/res/drawable/bg_splash.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_table_color1.xml b/app/src/main/res/drawable/bg_table_color1.xml new file mode 100644 index 0000000..0fba3fc --- /dev/null +++ b/app/src/main/res/drawable/bg_table_color1.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_table_color2.xml b/app/src/main/res/drawable/bg_table_color2.xml new file mode 100644 index 0000000..4d3b839 --- /dev/null +++ b/app/src/main/res/drawable/bg_table_color2.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_table_family.xml b/app/src/main/res/drawable/bg_table_family.xml new file mode 100644 index 0000000..c37ffc7 --- /dev/null +++ b/app/src/main/res/drawable/bg_table_family.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_white_3.xml b/app/src/main/res/drawable/bg_white_3.xml new file mode 100644 index 0000000..d81ac0e --- /dev/null +++ b/app/src/main/res/drawable/bg_white_3.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/clickable_blue_bg.xml b/app/src/main/res/drawable/clickable_blue_bg.xml new file mode 100644 index 0000000..86ba277 --- /dev/null +++ b/app/src/main/res/drawable/clickable_blue_bg.xml @@ -0,0 +1,5 @@ + + + + \ 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/corners_edit_white_chatui.xml b/app/src/main/res/drawable/corners_edit_white_chatui.xml new file mode 100644 index 0000000..fc471bd --- /dev/null +++ b/app/src/main/res/drawable/corners_edit_white_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/drawer_header.jpg b/app/src/main/res/drawable/drawer_header.jpg new file mode 100644 index 0000000..f54a30e Binary files /dev/null and b/app/src/main/res/drawable/drawer_header.jpg differ 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/fab_label_background.xml b/app/src/main/res/drawable/fab_label_background.xml new file mode 100644 index 0000000..f0efb9c --- /dev/null +++ b/app/src/main/res/drawable/fab_label_background.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_down.xml b/app/src/main/res/drawable/ic_arrow_down.xml new file mode 100644 index 0000000..0cace5d --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_down.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_to_right_dark.xml b/app/src/main/res/drawable/ic_arrow_to_right_dark.xml new file mode 100644 index 0000000..c854061 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_to_right_dark.xml @@ -0,0 +1,14 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_up.xml b/app/src/main/res/drawable/ic_arrow_up.xml new file mode 100644 index 0000000..7ede1fd --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_up.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_backup.xml b/app/src/main/res/drawable/ic_backup.xml new file mode 100644 index 0000000..7f36a13 --- /dev/null +++ b/app/src/main/res/drawable/ic_backup.xml @@ -0,0 +1,24 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_baseline_clear_all_24.xml b/app/src/main/res/drawable/ic_baseline_clear_all_24.xml new file mode 100644 index 0000000..54ca983 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_clear_all_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_close_black_24dp.xml b/app/src/main/res/drawable/ic_close_black_24dp.xml new file mode 100644 index 0000000..e700807 --- /dev/null +++ b/app/src/main/res/drawable/ic_close_black_24dp.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_custom_tolerance.xml b/app/src/main/res/drawable/ic_custom_tolerance.xml new file mode 100644 index 0000000..7c5abcb --- /dev/null +++ b/app/src/main/res/drawable/ic_custom_tolerance.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_export.xml b/app/src/main/res/drawable/ic_export.xml new file mode 100644 index 0000000..81bf256 --- /dev/null +++ b/app/src/main/res/drawable/ic_export.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_export_height_traverse.xml b/app/src/main/res/drawable/ic_export_height_traverse.xml new file mode 100644 index 0000000..7d86cf4 --- /dev/null +++ b/app/src/main/res/drawable/ic_export_height_traverse.xml @@ -0,0 +1,28 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_export_wire.xml b/app/src/main/res/drawable/ic_export_wire.xml new file mode 100644 index 0000000..dbd25fc --- /dev/null +++ b/app/src/main/res/drawable/ic_export_wire.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_indeterminate_check_box_black_24dp.xml b/app/src/main/res/drawable/ic_indeterminate_check_box_black_24dp.xml new file mode 100644 index 0000000..8eb1cdc --- /dev/null +++ b/app/src/main/res/drawable/ic_indeterminate_check_box_black_24dp.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_known_point_24.xml b/app/src/main/res/drawable/ic_known_point_24.xml new file mode 100644 index 0000000..3958816 --- /dev/null +++ b/app/src/main/res/drawable/ic_known_point_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_ruler_selected.xml b/app/src/main/res/drawable/ic_ruler_selected.xml new file mode 100644 index 0000000..89d5af7 --- /dev/null +++ b/app/src/main/res/drawable/ic_ruler_selected.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_ruler_unselected.xml b/app/src/main/res/drawable/ic_ruler_unselected.xml new file mode 100644 index 0000000..e752d51 --- /dev/null +++ b/app/src/main/res/drawable/ic_ruler_unselected.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_selected.xml b/app/src/main/res/drawable/ic_selected.xml new file mode 100644 index 0000000..1f7954f --- /dev/null +++ b/app/src/main/res/drawable/ic_selected.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_surveyor_24.xml b/app/src/main/res/drawable/ic_surveyor_24.xml new file mode 100644 index 0000000..42e97a5 --- /dev/null +++ b/app/src/main/res/drawable/ic_surveyor_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_switch.xml b/app/src/main/res/drawable/ic_switch.xml new file mode 100644 index 0000000..19c8834 --- /dev/null +++ b/app/src/main/res/drawable/ic_switch.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_tab_project_selected.xml b/app/src/main/res/drawable/ic_tab_project_selected.xml new file mode 100644 index 0000000..989b828 --- /dev/null +++ b/app/src/main/res/drawable/ic_tab_project_selected.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_tab_project_unselect.xml b/app/src/main/res/drawable/ic_tab_project_unselect.xml new file mode 100644 index 0000000..a00f0f2 --- /dev/null +++ b/app/src/main/res/drawable/ic_tab_project_unselect.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_tolerance_24.xml b/app/src/main/res/drawable/ic_tolerance_24.xml new file mode 100644 index 0000000..f6d7895 --- /dev/null +++ b/app/src/main/res/drawable/ic_tolerance_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_unknown_point_24.xml b/app/src/main/res/drawable/ic_unknown_point_24.xml new file mode 100644 index 0000000..3167e8a --- /dev/null +++ b/app/src/main/res/drawable/ic_unknown_point_24.xml @@ -0,0 +1,5 @@ + + + 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/icon_control_logo.png b/app/src/main/res/drawable/icon_control_logo.png new file mode 100644 index 0000000..c21729a Binary files /dev/null and b/app/src/main/res/drawable/icon_control_logo.png differ diff --git a/app/src/main/res/drawable/icon_control_text.png b/app/src/main/res/drawable/icon_control_text.png new file mode 100644 index 0000000..6dc8030 Binary files /dev/null and b/app/src/main/res/drawable/icon_control_text.png differ diff --git a/app/src/main/res/drawable/icon_parameter_points.xml b/app/src/main/res/drawable/icon_parameter_points.xml new file mode 100644 index 0000000..557f883 --- /dev/null +++ b/app/src/main/res/drawable/icon_parameter_points.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/icon_prism_manager.xml b/app/src/main/res/drawable/icon_prism_manager.xml new file mode 100644 index 0000000..8a822d5 --- /dev/null +++ b/app/src/main/res/drawable/icon_prism_manager.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/icon_ts_connecting.xml b/app/src/main/res/drawable/icon_ts_connecting.xml new file mode 100644 index 0000000..a1b4c8c --- /dev/null +++ b/app/src/main/res/drawable/icon_ts_connecting.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/src/main/res/drawable/img_request_android_data_access_permission.jpg b/app/src/main/res/drawable/img_request_android_data_access_permission.jpg new file mode 100644 index 0000000..8c01cad Binary files /dev/null and b/app/src/main/res/drawable/img_request_android_data_access_permission.jpg differ diff --git a/app/src/main/res/drawable/img_weixin_download_guide.jpg b/app/src/main/res/drawable/img_weixin_download_guide.jpg new file mode 100644 index 0000000..d29adfd Binary files /dev/null and b/app/src/main/res/drawable/img_weixin_download_guide.jpg differ diff --git a/app/src/main/res/drawable/iv_back_selector.xml b/app/src/main/res/drawable/iv_back_selector.xml new file mode 100644 index 0000000..b0d09d5 --- /dev/null +++ b/app/src/main/res/drawable/iv_back_selector.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file 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/loading_circle.xml b/app/src/main/res/drawable/loading_circle.xml new file mode 100644 index 0000000..dce7824 --- /dev/null +++ b/app/src/main/res/drawable/loading_circle.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/loading_dialog_bg_ll.xml b/app/src/main/res/drawable/loading_dialog_bg_ll.xml new file mode 100644 index 0000000..17072d0 --- /dev/null +++ b/app/src/main/res/drawable/loading_dialog_bg_ll.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/loading_dialog_bg_progress_bar.xml b/app/src/main/res/drawable/loading_dialog_bg_progress_bar.xml new file mode 100644 index 0000000..fdcbb79 --- /dev/null +++ b/app/src/main/res/drawable/loading_dialog_bg_progress_bar.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/drawable/loading_dialog_pic.png b/app/src/main/res/drawable/loading_dialog_pic.png new file mode 100644 index 0000000..38151ee Binary files /dev/null and b/app/src/main/res/drawable/loading_dialog_pic.png differ diff --git a/app/src/main/res/drawable/msg_state_fail_resend.png b/app/src/main/res/drawable/msg_state_fail_resend.png new file mode 100644 index 0000000..0dca30d Binary files /dev/null and b/app/src/main/res/drawable/msg_state_fail_resend.png differ diff --git a/app/src/main/res/drawable/record_microphone_bj_chatui.xml b/app/src/main/res/drawable/record_microphone_bj_chatui.xml new file mode 100644 index 0000000..e280578 --- /dev/null +++ b/app/src/main/res/drawable/record_microphone_bj_chatui.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/record_microphone_chatui.xml b/app/src/main/res/drawable/record_microphone_chatui.xml new file mode 100644 index 0000000..b4328ac --- /dev/null +++ b/app/src/main/res/drawable/record_microphone_chatui.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/recyclerview_divider.xml b/app/src/main/res/drawable/recyclerview_divider.xml new file mode 100644 index 0000000..111d79d --- /dev/null +++ b/app/src/main/res/drawable/recyclerview_divider.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_btn_bg.xml b/app/src/main/res/drawable/round_btn_bg.xml new file mode 100644 index 0000000..dfdc7dd --- /dev/null +++ b/app/src/main/res/drawable/round_btn_bg.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.xml b/app/src/main/res/drawable/round_white.xml new file mode 100644 index 0000000..bf751de --- /dev/null +++ b/app/src/main/res/drawable/round_white.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/drawable/select_mask.xml b/app/src/main/res/drawable/select_mask.xml new file mode 100644 index 0000000..99e9205 --- /dev/null +++ b/app/src/main/res/drawable/select_mask.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/separator_table.xml b/app/src/main/res/drawable/separator_table.xml new file mode 100644 index 0000000..6101b0a --- /dev/null +++ b/app/src/main/res/drawable/separator_table.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/separator_table_first.xml b/app/src/main/res/drawable/separator_table_first.xml new file mode 100644 index 0000000..fd06fa7 --- /dev/null +++ b/app/src/main/res/drawable/separator_table_first.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/separator_table_header.xml b/app/src/main/res/drawable/separator_table_header.xml new file mode 100644 index 0000000..c18dbe2 --- /dev/null +++ b/app/src/main/res/drawable/separator_table_header.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/separator_table_header_first.xml b/app/src/main/res/drawable/separator_table_header_first.xml new file mode 100644 index 0000000..37f083e --- /dev/null +++ b/app/src/main/res/drawable/separator_table_header_first.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_shadow.xml b/app/src/main/res/drawable/tab_shadow.xml new file mode 100644 index 0000000..6a01a85 --- /dev/null +++ b/app/src/main/res/drawable/tab_shadow.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/transparent_ripple_bg.xml b/app/src/main/res/drawable/transparent_ripple_bg.xml new file mode 100644 index 0000000..1898644 --- /dev/null +++ b/app/src/main/res/drawable/transparent_ripple_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/voice_left_chatui.xml b/app/src/main/res/drawable/voice_left_chatui.xml new file mode 100644 index 0000000..0d40788 --- /dev/null +++ b/app/src/main/res/drawable/voice_left_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/voice_right_chatui.xml b/app/src/main/res/drawable/voice_right_chatui.xml new file mode 100644 index 0000000..a1907ad --- /dev/null +++ b/app/src/main/res/drawable/voice_right_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/white_ripple_bg.xml b/app/src/main/res/drawable/white_ripple_bg.xml new file mode 100644 index 0000000..b2b79f0 --- /dev/null +++ b/app/src/main/res/drawable/white_ripple_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/wifi_chat_item_left_bg.9.png b/app/src/main/res/drawable/wifi_chat_item_left_bg.9.png new file mode 100644 index 0000000..ebbac7c Binary files /dev/null and b/app/src/main/res/drawable/wifi_chat_item_left_bg.9.png differ diff --git a/app/src/main/res/drawable/wifi_chat_item_right_bg.9.png b/app/src/main/res/drawable/wifi_chat_item_right_bg.9.png new file mode 100644 index 0000000..86fa7f7 Binary files /dev/null and b/app/src/main/res/drawable/wifi_chat_item_right_bg.9.png differ diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml new file mode 100644 index 0000000..39beb62 --- /dev/null +++ b/app/src/main/res/layout/activity_about.xml @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_activate.xml b/app/src/main/res/layout/activity_activate.xml new file mode 100644 index 0000000..2cfcd35 --- /dev/null +++ b/app/src/main/res/layout/activity_activate.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + +