Jelajahi Sumber

add tju program data to git.

yuchuli 4 tahun lalu
induk
melakukan
ef510b4485
100 mengubah file dengan 22429 tambahan dan 0 penghapusan
  1. 3 0
      天津大学/pos.txt
  2. 2 0
      天津大学/startiv.sh
  3. TEMPAT SAMPAH
      天津大学/tjuvv7-app.zip
  4. TEMPAT SAMPAH
      天津大学/tjuvv7-src.zip
  5. 57 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/build.gradle
  6. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/libs/BaiduLBS_Android.jar
  7. 21 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/proguard-rules.pro
  8. 26 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java
  9. 46 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/AndroidManifest.xml
  10. 50 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/cpp/CMakeLists.txt
  11. 163 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/cpp/md5.c
  12. 48 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/cpp/md5.h
  13. 622 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/cpp/native-lib.cpp
  14. 242 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/Apl.java
  15. 1554 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/Cloud.java
  16. 73 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/CustomDialog.java
  17. 520 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/MainActivity.java
  18. 61 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/SharePreferencesUntils.java
  19. 16 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/proto/cloud.proto
  20. 30 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  21. 170 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/drawable/ic_launcher_background.xml
  22. 186 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/layout/activity_main.xml
  23. 155 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/layout/custom.xml
  24. 5 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  25. 5 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  26. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-hdpi/ic_launcher.png
  27. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  28. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-mdpi/ic_launcher.png
  29. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  30. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  31. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  32. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  33. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  34. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  35. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  36. 6 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/values/colors.xml
  37. 3 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/values/strings.xml
  38. 10 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/values/styles.xml
  39. 17 0
      天津大学/tjuvv7-src/src/android/ADCCloud/app/src/test/java/com/example/myapplication/ExampleUnitTest.java
  40. 28 0
      天津大学/tjuvv7-src/src/android/ADCCloud/build.gradle
  41. 19 0
      天津大学/tjuvv7-src/src/android/ADCCloud/gradle.properties
  42. TEMPAT SAMPAH
      天津大学/tjuvv7-src/src/android/ADCCloud/gradle/wrapper/gradle-wrapper.jar
  43. 6 0
      天津大学/tjuvv7-src/src/android/ADCCloud/gradle/wrapper/gradle-wrapper.properties
  44. 172 0
      天津大学/tjuvv7-src/src/android/ADCCloud/gradlew
  45. 84 0
      天津大学/tjuvv7-src/src/android/ADCCloud/gradlew.bat
  46. 9 0
      天津大学/tjuvv7-src/src/android/ADCCloud/local.properties
  47. 2 0
      天津大学/tjuvv7-src/src/android/ADCCloud/settings.gradle
  48. 55 0
      天津大学/tjuvv7-src/src/common/Time_Manager/Time_Manager.pro
  49. 79 0
      天津大学/tjuvv7-src/src/common/Time_Manager/data_manager.cpp
  50. 50 0
      天津大学/tjuvv7-src/src/common/Time_Manager/data_manager.h
  51. 9 0
      天津大学/tjuvv7-src/src/common/Time_Manager/main.cpp
  52. 218 0
      天津大学/tjuvv7-src/src/common/Time_Manager/time_manager.cpp
  53. 80 0
      天津大学/tjuvv7-src/src/common/Time_Manager/time_manager.h
  54. 29 0
      天津大学/tjuvv7-src/src/common/Time_Manager/timer.cpp
  55. 26 0
      天津大学/tjuvv7-src/src/common/Time_Manager/timer.h
  56. 59 0
      天津大学/tjuvv7-src/src/common/Time_Manager/worker.cpp
  57. 44 0
      天津大学/tjuvv7-src/src/common/Time_Manager/worker.h
  58. 31 0
      天津大学/tjuvv7-src/src/common/common/VehicleParam.cpp
  59. 26 0
      天津大学/tjuvv7-src/src/common/common/VehicleParam.h
  60. 565 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Junction.cpp
  61. 470 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Junction.h
  62. 1509 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Lane.cpp
  63. 773 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Lane.h
  64. 514 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/ObjectSignal.cpp
  65. 163 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/ObjectSignal.h
  66. 307 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDrive.cpp
  67. 190 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDrive.h
  68. 1226 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDriveXmlParser.cpp
  69. 89 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDriveXmlParser.h
  70. 1175 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDriveXmlWriter.cpp
  71. 90 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDriveXmlWriter.h
  72. 90 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OtherStructures.cpp
  73. 66 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OtherStructures.h
  74. 1258 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Road.cpp
  75. 490 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Road.h
  76. 853 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/RoadGeometry.cpp
  77. 435 0
      天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/RoadGeometry.h
  78. 116 0
      天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinystr.cpp
  79. 319 0
      天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinystr.h
  80. 1856 0
      天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinyxml.cpp
  81. 1802 0
      天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinyxml.h
  82. 52 0
      天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinyxmlerror.cpp
  83. 1635 0
      天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinyxmlparser.cpp
  84. 281 0
      天津大学/tjuvv7-src/src/common/ivbacktrace/ivbacktrace.cpp
  85. 114 0
      天津大学/tjuvv7-src/src/common/ivbacktrace/ivbacktrace.h
  86. 38 0
      天津大学/tjuvv7-src/src/common/ivbacktrace/ivbacktrace.pro
  87. 122 0
      天津大学/tjuvv7-src/src/common/ivexit/ivexit.cpp
  88. 37 0
      天津大学/tjuvv7-src/src/common/ivexit/ivexit.h
  89. 40 0
      天津大学/tjuvv7-src/src/common/ivexit/ivexit.pro
  90. 16 0
      天津大学/tjuvv7-src/src/common/ivfault/ivfault.cpp
  91. 26 0
      天津大学/tjuvv7-src/src/common/ivfault/ivfault.h
  92. 53 0
      天津大学/tjuvv7-src/src/common/ivfault/ivfault.pro
  93. 56 0
      天津大学/tjuvv7-src/src/common/ivfault/ivfault_impl.cpp
  94. 41 0
      天津大学/tjuvv7-src/src/common/ivfault/ivfault_impl.h
  95. 153 0
      天津大学/tjuvv7-src/src/common/ivlog/ivlog.cpp
  96. 41 0
      天津大学/tjuvv7-src/src/common/ivlog/ivlog.h
  97. 55 0
      天津大学/tjuvv7-src/src/common/ivlog/ivlog.pro
  98. 139 0
      天津大学/tjuvv7-src/src/common/ivlog/ivlog_impl.cpp
  99. 48 0
      天津大学/tjuvv7-src/src/common/ivlog/ivlog_impl.h
  100. 9 0
      天津大学/tjuvv7-src/src/common/ivsyschange/ivsyschange.cpp

+ 3 - 0
天津大学/pos.txt

@@ -0,0 +1,3 @@
+智算学部门口	117.3076244	38.9988820
+图书馆	117.3066823	38.9963564
+

+ 2 - 0
天津大学/startiv.sh

@@ -0,0 +1,2 @@
+cd ~/newapp
+./IVSysMan &

TEMPAT SAMPAH
天津大学/tjuvv7-app.zip


TEMPAT SAMPAH
天津大学/tjuvv7-src.zip


+ 57 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/build.gradle

@@ -0,0 +1,57 @@
+apply plugin: 'com.android.application'
+
+
+
+android {
+    compileSdkVersion 30
+    buildToolsVersion "30.0.1"
+
+
+
+    dependencies {
+        api 'com.google.protobuf:protobuf-java:3.6.0'
+    }
+
+    defaultConfig {
+        applicationId "com.adc.iv"
+        minSdkVersion 16
+        targetSdkVersion 30
+        versionCode 1
+        versionName "1.0"
+
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+    externalNativeBuild {
+        cmake {
+            path file('src/main/cpp/CMakeLists.txt')
+        }
+    }
+
+    sourceSets {
+        main {
+            jniLibs.srcDir 'libs'
+        }
+    }
+
+}
+
+
+
+
+dependencies {
+    implementation fileTree(dir: "libs", include: ["*.jar"])
+    implementation 'androidx.appcompat:appcompat:1.1.0'
+    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+    implementation files('libs/BaiduLBS_Android.jar')
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+
+}

TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/libs/BaiduLBS_Android.jar


+ 21 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# 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 *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 26 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.example.myapplication;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        assertEquals("com.example.myapplication", appContext.getPackageName());
+    }
+}

+ 46 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/AndroidManifest.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.adc.iv">
+
+
+    <!-- 这个权限用于进行网络定位 -->
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <!-- 这个权限用于访问GPS定位 -->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <!-- 获取网络状态,根据网络状态切换进行数据请求网络转换 -->
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <!-- 写外置存储。如果开发者使用了离线地图,并且数据写在外置存储区域,则需要申请该权限 -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <!-- 读取外置存储。如果开发者使用了so动态加载功能并且把so文件放在了外置存储区域,则需要申请该权限,否则不需要 -->
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <!-- 访问网络,进行地图相关业务数据请求,包括地图数据,路线规划,POI检索等 -->
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application
+        android:name=".Apl"
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+
+        <meta-data
+
+            android:name="com.baidu.lbsapi.API_KEY"
+
+            android:value="qEXFLZTLtKjIttd4iunlASd7cABsgCr5">
+
+        </meta-data>
+
+        <activity android:name=".MainActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>

+ 50 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/cpp/CMakeLists.txt

@@ -0,0 +1,50 @@
+# For more information about using CMake with Android Studio, read the
+# documentation: https://d.android.com/studio/projects/add-native-code.html
+
+# Sets the minimum version of CMake required to build the native library.
+
+cmake_minimum_required(VERSION 3.4.1)
+
+include_directories(./../../../../../../../thirdpartylib/rest_rpc/include)
+
+include_directories(./../../../../../../../thirdpartylib/rest_rpc/third/msgpack/include)
+
+include_directories(/home/yuchuli/git/Boost-for-Android/build/out/arm64-v8a/include/boost-1_73)
+
+# Creates and names a library, sets it as either STATIC
+# or SHARED, and provides the relative paths to its source code.
+# You can define multiple libraries, and CMake builds them for you.
+# Gradle automatically packages shared libraries with your APK.
+
+add_library( # Sets the name of the library.
+             native-lib
+
+             # Sets the library as a shared library.
+             SHARED
+
+             # Provides a relative path to your source file(s).
+             native-lib.cpp md5.c)
+
+# Searches for a specified prebuilt library and stores the path as a
+# variable. Because CMake includes system libraries in the search path by
+# default, you only need to specify the name of the public NDK library
+# you want to add. CMake verifies that the library exists before
+# completing its build.
+
+find_library( # Sets the name of the path variable.
+              log-lib
+
+              # Specifies the name of the NDK library that
+              # you want CMake to locate.
+              log )
+
+# Specifies libraries CMake should link to your target library. You
+# can link multiple libraries, such as libraries you define in this
+# build script, prebuilt third-party libraries, or system libraries.
+
+target_link_libraries( # Specifies the target library.
+                       native-lib
+
+                       # Links the target library to the log library
+                       # included in the NDK.
+                       ${log-lib} )

+ 163 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/cpp/md5.c

@@ -0,0 +1,163 @@
+    #include <memory.h>
+    #include "md5.h"
+     
+    unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+                             
+    void MD5Init(MD5_CTX *context)
+    {
+         context->count[0] = 0;
+         context->count[1] = 0;
+         context->state[0] = 0x67452301;
+         context->state[1] = 0xEFCDAB89;
+         context->state[2] = 0x98BADCFE;
+         context->state[3] = 0x10325476;
+    }
+    void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
+    {
+        unsigned int i = 0,index = 0,partlen = 0;
+        index = (context->count[0] >> 3) & 0x3F;
+        partlen = 64 - index;
+        context->count[0] += inputlen << 3;
+        if(context->count[0] < (inputlen << 3))
+           context->count[1]++;
+        context->count[1] += inputlen >> 29;
+        
+        if(inputlen >= partlen)
+        {
+           memcpy(&context->buffer[index],input,partlen);
+           MD5Transform(context->state,context->buffer);
+           for(i = partlen;i+64 <= inputlen;i+=64)
+               MD5Transform(context->state,&input[i]);
+           index = 0;        
+        }  
+        else
+        {
+            i = 0;
+        }
+        memcpy(&context->buffer[index],&input[i],inputlen-i);
+    }
+    void MD5Final(MD5_CTX *context,unsigned char digest[16])
+    {
+        unsigned int index = 0,padlen = 0;
+        unsigned char bits[8];
+        index = (context->count[0] >> 3) & 0x3F;
+        padlen = (index < 56)?(56-index):(120-index);
+        MD5Encode(bits,context->count,8);
+        MD5Update(context,PADDING,padlen);
+        MD5Update(context,bits,8);
+        MD5Encode(digest,context->state,16);
+    }
+    void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
+    {
+        unsigned int i = 0,j = 0;
+        while(j < len)
+        {
+             output[j] = input[i] & 0xFF;  
+             output[j+1] = (input[i] >> 8) & 0xFF;
+             output[j+2] = (input[i] >> 16) & 0xFF;
+             output[j+3] = (input[i] >> 24) & 0xFF;
+             i++;
+             j+=4;
+        }
+    }
+    void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
+    {
+         unsigned int i = 0,j = 0;
+         while(j < len)
+         {
+               output[i] = (input[j]) |
+                           (input[j+1] << 8) |
+                           (input[j+2] << 16) |
+                           (input[j+3] << 24);
+               i++;
+               j+=4; 
+         }
+    }
+    void MD5Transform(unsigned int state[4],unsigned char block[64])
+    {
+         unsigned int a = state[0];
+         unsigned int b = state[1];
+         unsigned int c = state[2];
+         unsigned int d = state[3];
+         unsigned int x[64];
+         MD5Decode(x,block,64);
+         FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
+     FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
+     FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
+     FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
+     FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
+     FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
+     FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
+     FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
+     FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
+     FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
+     FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
+     FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
+     FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
+     FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
+     FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
+     FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
+     
+     /* Round 2 */
+     GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
+     GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
+     GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
+     GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
+     GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
+     GG(d, a, b, c, x[10], 9,  0x2441453); /* 22 */
+     GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
+     GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
+     GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
+     GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
+     GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
+     GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
+     GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
+     GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
+     GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
+     GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
+     
+     /* Round 3 */
+     HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
+     HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
+     HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
+     HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
+     HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
+     HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
+     HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
+     HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
+     HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
+     HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
+     HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
+     HH(b, c, d, a, x[ 6], 23,  0x4881d05); /* 44 */
+     HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
+     HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
+     HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
+     HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
+     
+     /* Round 4 */
+     II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
+     II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
+     II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
+     II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
+     II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
+     II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
+     II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
+     II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
+     II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
+     II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
+     II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
+     II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
+     II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
+     II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
+     II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
+     II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
+         state[0] += a;
+         state[1] += b;
+         state[2] += c;
+         state[3] += d;
+    }
+
+

+ 48 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/cpp/md5.h

@@ -0,0 +1,48 @@
+#ifndef MD5_H
+#define MD5_H
+ 
+typedef struct
+{
+    unsigned int count[2];
+    unsigned int state[4];
+    unsigned char buffer[64];   
+}MD5_CTX;
+ 
+                         
+#define F(x,y,z) ((x & y) | (~x & z))
+#define G(x,y,z) ((x & z) | (y & ~z))
+#define H(x,y,z) (x^y^z)
+#define I(x,y,z) (y ^ (x | ~z))
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
+#define FF(a,b,c,d,x,s,ac) \
+          { \
+          a += F(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a,s); \
+          a += b; \
+          }
+#define GG(a,b,c,d,x,s,ac) \
+          { \
+          a += G(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a,s); \
+          a += b; \
+          }
+#define HH(a,b,c,d,x,s,ac) \
+          { \
+          a += H(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a,s); \
+          a += b; \
+          }
+#define II(a,b,c,d,x,s,ac) \
+          { \
+          a += I(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a,s); \
+          a += b; \
+          }                                            
+void MD5Init(MD5_CTX *context);
+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
+void MD5Final(MD5_CTX *context,unsigned char digest[16]);
+void MD5Transform(unsigned int state[4],unsigned char block[64]);
+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
+ 
+#endif

+ 622 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/cpp/native-lib.cpp

@@ -0,0 +1,622 @@
+#include <jni.h>
+#include <string>
+
+#include <android/log.h>
+
+#include <thread>
+#include <iostream>
+#include <memory>
+
+#include "rpc_client.hpp"
+#include <mutex>          // std::mutex
+
+
+extern "C"
+{
+#include "md5.h"
+}
+
+#define  LOG_TAG    "ADC Cloud"
+#define  LOG(LEVEL,...)  __android_log_print(LEVEL, LOG_TAG, __VA_ARGS__)
+#define  LOGI(...)  LOG(ANDROID_LOG_INFO,__VA_ARGS__)
+#define LOGE(...)  LOG(ANDROID_LOG_ERROR, __VA_ARGS__)
+
+
+std::string gstrserverip =  "192.168.50.62";
+std::string gstrserverport = "9000";
+std::string gstruploadinterval = "100";
+void * gpa;
+//QMutex gMutexMsg;
+std::thread * guploadthread;
+
+std::mutex gmtx_send;
+std::shared_ptr<char> gpsend_ptr;
+bool gbneedsend = false;
+int gnsend = 0;
+
+double gmin_x,gmin_y,gmax_x,gmax_y;
+
+
+std::mutex gmtx_recv;           // mutex for critical section
+
+std::shared_ptr<char> gprecv_ptr;
+bool gbnewrecv = false;
+int gnrecv = 0;
+
+namespace iv
+{
+    class MyTime
+    {
+    private:
+        int mnsecstart;
+        int musecstart;
+        int mnlastelapsed = 0;
+        int mnbaseelapsed = 0;
+    public:
+        void start()
+        {
+            struct timeval time;
+            gettimeofday(&time,NULL);
+            mnsecstart = time.tv_sec;
+            musecstart = time.tv_usec;
+            mnlastelapsed = 0;
+            mnbaseelapsed = 0;
+
+        }
+        int elapsed()
+        {
+            int nrtn;
+            struct timeval time;
+            gettimeofday(&time,NULL);
+            if(time.tv_sec< mnsecstart)
+            {
+                mnsecstart = time.tv_sec;
+                musecstart = time.tv_usec;
+                mnbaseelapsed = mnlastelapsed;
+                return mnbaseelapsed;
+            } else
+            {
+                int elpased = (time.tv_usec - musecstart)/1000;
+                elpased = elpased + (time.tv_sec - mnsecstart)*1000 + mnbaseelapsed;
+                mnlastelapsed = elpased;
+                return elpased;
+            }
+            return 0;
+        }
+        void restart()
+        {
+            struct timeval time;
+            gettimeofday(&time,NULL);
+            mnsecstart = time.tv_sec;
+            musecstart = time.tv_usec;
+            mnlastelapsed = 0;
+            mnbaseelapsed = 0;
+        }
+    };
+}
+
+struct queryrespmsg {
+    int nres;
+    int id;
+    long long  ntime;
+    std::vector<char> xdata;
+    MSGPACK_DEFINE(nres,id, ntime,xdata);
+};
+
+class xodrobj
+{
+public:
+    double flatsrc;
+    double flonsrc;
+    double fhgdsrc;
+    double flat;
+    double flon;
+    int lane;
+};
+
+
+namespace iv {
+    struct msgunit
+    {
+        char mstrmsgname[256];
+        int mnBufferSize = 10000;
+        int mnBufferCount = 1;
+        void * mpa;
+        std::shared_ptr<char> mpstrmsgdata;
+        int mndatasize = 0;
+        bool mbRefresh = false;
+    };
+}
+
+namespace iv {
+    struct GPS_INS {
+        int valid = 0xff;
+        int index = 0;    //gps点序号
+
+        double gps_lat = 0;//纬度
+        double gps_lng = 0;//经度
+
+        double gps_x = 0;
+        double gps_y = 0;
+        double gps_z = 0;
+
+        double ins_roll_angle = 0;    //横滚角 一般定义载体的右、前、上三个方向构成右手系,绕向前的轴旋转就是横滚角,绕向右的轴旋转就是俯仰角,绕向上的轴旋转就是航向角
+        double ins_pitch_angle = 0;    //俯仰角
+        double ins_heading_angle = 0;    //航向角
+
+        int ins_status = 0;    //惯导状态 4
+        int rtk_status = 0;    //rtk状态 6 -5 -3
+        int gps_satelites_num = 0;
+
+        //-----加速度--------------
+        double accel_x = 0;
+        double accel_y = 0;
+        double accel_z = 0;
+
+        //-------角速度------------
+        double ang_rate_x = 0;
+        double ang_rate_y = 0;
+        double ang_rate_z = 0;
+
+        //-----------方向速度--------------
+        double vel_N = 0;
+        double vel_E = 0;
+        double vel_D = 0;
+
+        int speed_mode = 0;
+        int mode2 = 0;
+        double speed = 0;            //速度  若导航点则为导航预设速度  若为当前点则为当前车速
+
+        int roadMode;
+        int runMode;
+        int roadSum;
+        int roadOri;
+
+
+    };
+}
+
+namespace iv {
+    struct simpletrace
+    {
+        double gps_lat = 0;//纬度
+        double gps_lng = 0;//经度
+
+        double gps_x = 0;
+        double gps_y = 0;
+        double gps_z = 0;
+
+
+        double ins_heading_angle = 0;	//航向角
+    };
+
+}
+
+struct ctrlrespmsg {
+    int nsendid;  // 0 write to buffer
+    MSGPACK_DEFINE(nsendid);
+};
+
+std::vector<iv::msgunit> mvectormsgunit;
+
+std::vector<iv::msgunit> mvectorctrlmsgunit;
+
+
+std::string gstrVIN = "AAAAAAAAAAAAAAAAA";
+std::string gstrqueryMD5 = "5d41402abc4b2a76b9719d911017c592";
+std::string gstrctrlMD5 = "5d41402abc4b2a76b9719d911017c592";
+
+
+struct uploadresponsemsg {
+    int nres; //0 no message 1 have message
+    int id;
+    long long ntime;
+    std::string strVIN;
+    std::string strctrlMD5;
+    std::vector<char> xdata;
+    MSGPACK_DEFINE(id, ntime,strVIN, strctrlMD5,xdata);
+};
+
+int gindex = 0;
+
+
+std::string getmd5(const char * strcode)
+{
+    int i;
+ //   unsigned char encrypt[] ="hello";//21232f297a57a5a743894a0e4a801fc3
+    unsigned char decrypt[16];
+    MD5_CTX md5;
+    MD5Init(&md5);
+    MD5Update(&md5,(unsigned  char *)strcode,strlen(strcode));
+    MD5Final(&md5,decrypt);
+    //   printf("加密前:%s\n加密后:",encrypt);
+    char strout[100];
+    char strtem[30];
+    snprintf(strout,10,"");
+    for(i=0;i<16;i++)
+    {
+        printf("%02x",decrypt[i]);
+        snprintf(strtem,30,"%02x",decrypt[i]);strncat(strout,strtem,100);
+    }
+
+    LOGI("MD5 %s",strout);
+
+    std::string strrtn = strout;
+    return  strrtn;
+
+}
+
+void threadquery(std::string strserver,int nport) {
+
+
+    int nsize = mvectormsgunit.size();
+    int nctrlsize = mvectorctrlmsgunit.size();
+
+
+    int ninterval = atoi(gstruploadinterval.data());
+    if(ninterval<=0)ninterval = 100;
+
+    iv::MyTime xTime;
+    xTime.start();
+    int nlastsend = xTime.elapsed();
+
+    rest_rpc::rpc_client client;
+    long long nlasttime = 0;
+    client.enable_auto_reconnect(); //automatic reconnect
+    client.enable_auto_heartbeat(); //automatic heartbeat
+    bool r = client.connect(strserver.data(),nport);
+//    bool r = client.connect(gstrserverip, atoi(gstrserverport.data()));
+    int count = 0;
+
+
+
+
+    CT:
+    while (true) {
+        if (client.has_connected()) {
+            std::cout << "connected ok\n";
+            LOGI("connected ok\n");
+            break;
+        } else {
+            std::cout << "connected failed: " << count++ << "\n";
+            LOGI("connected failed: %d",count);
+        }
+        std::this_thread::sleep_for(std::chrono::seconds(1));
+    }
+
+    while(true)
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+        if((xTime.elapsed()-nlastsend)<ninterval)
+        {
+            continue;
+        }
+        try
+        {
+            nlastsend = xTime.elapsed();
+            queryrespmsg xqmsg = client.call<10000,queryrespmsg>("query_clientmsg",gstrVIN,
+                                                           gstrqueryMD5,nlasttime);
+
+     //       LOGI("time: %d res is %d",xTime.elapsed(),xqmsg.nres);
+            if(xqmsg.nres == 1)
+            {
+                nlasttime = xqmsg.ntime;
+                if(xqmsg.xdata.size() > 0)
+                {
+                    int ndatasize = xqmsg.xdata.size();
+                    char * strdata = new char[ndatasize];
+                    memcpy(strdata,xqmsg.xdata.data(),ndatasize);
+                    gmtx_recv.lock();
+                    gprecv_ptr.reset(strdata);
+                    gnrecv = ndatasize;
+                    gbnewrecv = true;
+                    gmtx_recv.unlock();
+                }
+//                iv::cloud::cloudmsg xmsg;
+//                if(xmsg.ParseFromArray(xqmsg.xdata.data(),xqmsg.xdata.size()))
+//                {
+//                    sharequerymsg(&xmsg);
+//                }
+            }
+
+//            iv::cloud::cloudmsg xmsg;
+//            xmsg.set_xtime(QDateTime::currentMSecsSinceEpoch());
+//            gMutexMsg.lock();
+//            for(i=0;i<nctrlsize;i++)
+//            {
+//                if(mvectorctrlmsgunit[i].mbRefresh)
+//                {
+//                    mvectorctrlmsgunit[i].mbRefresh = false;
+//                    iv::cloud::cloudunit xcloudunit;
+//                    xcloudunit.set_msgname(mvectorctrlmsgunit[i].mstrmsgname);
+//                    xcloudunit.set_data(mvectorctrlmsgunit[i].mpstrmsgdata.get(),mvectorctrlmsgunit[i].mndatasize);
+//                    iv::cloud::cloudunit * pcu = xmsg.add_xclouddata();
+//                    pcu->CopyFrom(xcloudunit);
+//                }
+//
+//            }
+//            gMutexMsg.unlock();
+//            if(xmsg.xclouddata_size()>0)
+//            {
+//                int nbytesize = xmsg.ByteSize();
+//                std::vector<char> pvectordata;
+//                pvectordata.resize(nbytesize);
+//                if(xmsg.SerializePartialToArray(pvectordata.data(),nbytesize))
+//                {
+//                    ctrlrespmsg result = client.call<ctrlrespmsg>("ctrl_client",gindex,QDateTime::currentMSecsSinceEpoch(),
+//                                                                  gstrVIN,gstrctrlMD5,pvectordata);
+//                    //                qDebug("send id : %d (sendid can be use query)",result.nsendid);
+//                    gindex++;
+//                }
+//                pvectordata.clear();
+//            }
+
+                if(gbneedsend&&(gnsend > 0)) {
+                    gmtx_send.lock();
+                                    int nbytesize = gnsend;
+                std::vector<char> pvectordata;
+                pvectordata.resize(nbytesize);
+                memcpy(pvectordata.data(),gpsend_ptr.get(),nbytesize);
+                gbneedsend = false;
+                gmtx_send.unlock();
+                    ctrlrespmsg result = client.call<10000,ctrlrespmsg>("ctrl_client", gindex, 0,
+                                                                  gstrVIN, gstrctrlMD5,
+                                                                  pvectordata);
+                    //                qDebug("send id : %d (sendid can be use query)",result.nsendid);
+                    gindex++;
+                    LOGI("SEND DATA");
+                }
+
+
+
+        }
+        catch (const std::exception & e) {
+            std::cout << e.what() << std::endl;
+            goto CT;
+        }
+    }
+
+}
+
+
+extern "C"
+JNIEXPORT jdoubleArray JNICALL
+Java_com_adc_iv_Apl_getGPSLatLonHgtHeading(JNIEnv *env, jobject thiz, jbyteArray tracedata) {
+    // TODO: implement getGPSLatLonHgtHeading()
+    jbyte *bytes;
+    bytes = env->GetByteArrayElements(tracedata, 0);
+    int chars_len = env->GetArrayLength(tracedata);
+    char * chars = new char[chars_len ];
+    memset(chars,0,chars_len );
+    memcpy(chars, bytes, chars_len);
+    env->ReleaseByteArrayElements(tracedata, bytes, 0);
+
+    iv::simpletrace * pins = (iv::simpletrace *)chars;
+    int ncount = chars_len/(sizeof(iv::simpletrace));
+    int i;
+    double * drtn = new double[ncount*4];
+    LOGI("COUNT IS %d",ncount);
+    for(i=0;i<ncount;i++)
+    {
+        drtn[i*4] = pins[i].gps_lat;
+        drtn[i*4+1] = pins[i].gps_lng;
+        drtn[i*4+2] = pins[i].gps_z;
+        drtn[i*4+3] = pins[i].ins_heading_angle;
+    }
+    delete  chars;
+
+    jdoubleArray  data = 0;
+
+
+    data= env->NewDoubleArray(ncount *4);
+    env->SetDoubleArrayRegion(data,0,ncount*4,(jdouble *)drtn);
+
+    delete drtn;
+    return data;
+}
+
+extern "C"
+JNIEXPORT jdoubleArray JNICALL
+Java_com_adc_iv_Apl_getGPSXY(JNIEnv *env, jobject thiz, jbyteArray tracedata) {
+    // TODO: implement getGPSXY()
+
+    jbyte *bytes;
+    bytes = env->GetByteArrayElements(tracedata, 0);
+    int chars_len = env->GetArrayLength(tracedata);
+    char * chars = new char[chars_len ];
+    memset(chars,0,chars_len );
+    memcpy(chars, bytes, chars_len);
+    env->ReleaseByteArrayElements(tracedata, bytes, 0);
+
+ //   iv::GPS_INS * pins = (iv::GPS_INS *)chars;
+ //   int ncount = chars_len/(sizeof(iv::GPS_INS));
+
+    iv::simpletrace * pins = (iv::simpletrace *)chars;
+    int ncount = chars_len/(sizeof(iv::simpletrace));
+    int i;
+    double min_x,min_y,max_x,max_y;
+    min_x = pow(10,20);
+    min_y =pow(10,20);
+    max_x = min_x*(-1);
+    max_y = min_y*(-1);
+    double * drtn = new double[ncount*2 +4];
+    LOGI("COUNT IS %d",ncount);
+    for(i=0;i<ncount;i++)
+    {
+        if(pins[i].gps_x<min_x)min_x = pins[i].gps_x;
+        if(pins[i].gps_y<min_y)min_y = pins[i].gps_y;
+        if(pins[i].gps_x>max_x)max_x = pins[i].gps_x;
+        if(pins[i].gps_y>max_y)max_y = pins[i].gps_y;
+        drtn[i*2] = pins[i].gps_x;
+        drtn[i*2+1] = pins[i].gps_y;
+    }
+    delete  chars;
+
+    jdoubleArray  data = 0;
+
+    drtn[2*ncount + 0] = min_x;
+    drtn[2*ncount + 1] = min_y;
+    drtn[2*ncount + 2] = max_x;
+    drtn[2*ncount + 3] = max_y;
+    data= env->NewDoubleArray(ncount *2+4);
+    env->SetDoubleArrayRegion(data,0,ncount*2+4,(jdouble *)drtn);
+
+    LOGI("MIN:%f %f MAX %f %f %f",min_x,min_y,max_x,max_y);
+    delete drtn;
+    return data;
+
+
+}
+
+
+jstring str2jstring(JNIEnv* env,const char* pat)
+{
+    //定义java String类 strClass
+    jclass strClass = (env)->FindClass("Ljava/lang/String;");
+    //获取String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
+    jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
+    //建立byte数组
+    jbyteArray bytes = (env)->NewByteArray(strlen(pat));
+    //将char* 转换为byte数组
+    (env)->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
+    // 设置String, 保存语言类型,用于byte数组转换至String时的参数
+    jstring encoding = (env)->NewStringUTF("GB2312");
+    //将byte数组转换为java String,并输出
+    return (jstring)(env)->NewObject(strClass, ctorID, bytes, encoding);
+}
+
+
+std::string jstring2str(JNIEnv* env, jstring jstr)
+{
+    char*   rtn   =   NULL;
+    jclass   clsstring   =   env->FindClass("java/lang/String");
+    jstring   strencode   =   env->NewStringUTF("GB2312");
+    jmethodID   mid   =   env->GetMethodID(clsstring,   "getBytes",   "(Ljava/lang/String;)[B");
+    jbyteArray   barr=   (jbyteArray)env->CallObjectMethod(jstr,mid,strencode);
+    jsize   alen   =   env->GetArrayLength(barr);
+    jbyte*   ba   =   env->GetByteArrayElements(barr,JNI_FALSE);
+    if(alen   >   0)
+    {
+        rtn   =   (char*)malloc(alen+1);
+        memcpy(rtn,ba,alen);
+        rtn[alen]=0;
+    }
+    env->ReleaseByteArrayElements(barr,ba,0);
+    std::string stemp(rtn);
+    free(rtn);
+    return   stemp;
+}
+
+extern "C"
+JNIEXPORT jstring JNICALL
+Java_com_adc_iv_Apl_stringFromJNI(JNIEnv *env, jobject thiz) {
+    LOGI("hello");
+//    std::thread * pthread = new std::thread(threadquery);
+    std::string hello = "Hello from C++ ADC";
+    return env->NewStringUTF(hello.c_str());
+}
+
+
+extern "C"
+JNIEXPORT jint JNICALL
+Java_com_adc_iv_Apl_startconnet(JNIEnv *env, jobject thiz) {
+    // TODO: implement startconnet()
+
+    LOGI("hello");
+    std::thread * pthread = new std::thread(threadquery,"192.168.50.62",9000);
+    std::string hello = "Hello from C++ ADC";
+    return 0;
+}
+
+extern "C"
+JNIEXPORT jint JNICALL
+Java_com_adc_iv_Apl_startconnect(JNIEnv *env, jobject thiz, jstring server,
+                                                jint nport) {
+    // TODO: implement startconnect()
+
+    std::string strserver = jstring2str(env,server);
+
+    std::thread * pthread = new std::thread(threadquery,strserver,nport);
+    return 0;
+
+
+}
+
+extern "C"
+JNIEXPORT jbyteArray JNICALL
+Java_com_adc_iv_Apl_getByteData(JNIEnv *env, jobject thiz) {
+    // TODO: implement getByteData()
+    jbyteArray  data = env->NewByteArray(100);
+    char xdata[100];
+    xdata[0] = 0;
+    env->SetByteArrayRegion(data,0,100,(jbyte *)xdata);
+    return data;
+}
+
+extern "C"
+JNIEXPORT jbyteArray JNICALL
+Java_com_adc_iv_Apl_makexodrobjdata(JNIEnv *env, jobject thiz, jdouble flat,
+                                                   jdouble flon) {
+    // TODO: implement makexodrobjdata()
+    jbyteArray  data = env->NewByteArray(sizeof(xodrobj));
+
+    xodrobj xo;
+    xo.flat = flat;
+    xo.flon = flon;
+    env->SetByteArrayRegion(data,0,sizeof(xodrobj),(jbyte *)&xo);
+    return data;
+}
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_com_adc_iv_Apl_setsenddata(JNIEnv *env, jobject thiz, jbyteArray xsend) {
+    // TODO: implement setsenddata()
+
+    jbyte *bytes;
+    bytes = env->GetByteArrayElements(xsend, 0);
+    int chars_len = env->GetArrayLength(xsend);
+    char * chars = new char[chars_len ];
+    memset(chars,0,chars_len );
+    memcpy(chars, bytes, chars_len);
+    gmtx_send.lock();
+    gpsend_ptr.reset(chars);
+        gnsend = chars_len;
+        gbneedsend = true;
+        gmtx_send.unlock();
+        env->ReleaseByteArrayElements(xsend, bytes, 0);
+
+}
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_com_adc_iv_Apl_setVINMD5(JNIEnv *env, jobject thiz, jstring vin,
+                                             jstring querymd5, jstring ctrlmd5) {
+    // TODO: implement setVINMD5()
+    std::string strqueryMD5,strctrlMD5;
+    gstrVIN = jstring2str(env,vin);
+    strqueryMD5 = jstring2str(env,querymd5);
+    strctrlMD5 = jstring2str(env,ctrlmd5);
+
+    gstrqueryMD5  = getmd5(strqueryMD5.data());
+    gstrctrlMD5 = getmd5(strctrlMD5.data());
+
+
+}
+
+extern "C"
+JNIEXPORT jbyteArray JNICALL
+Java_com_adc_iv_Apl_getrecvdata(JNIEnv *env, jobject thiz) {
+    // TODO: implement getrecvdata()
+    jbyteArray  data = 0;
+    if(gbnewrecv == false)
+    {
+        return  data;
+    }
+    gmtx_recv.lock();
+    data= env->NewByteArray(gnrecv);
+    env->SetByteArrayRegion(data,0,gnrecv,(jbyte *)gprecv_ptr.get());
+    gbnewrecv = false;
+    gmtx_recv.unlock();
+    return data;
+}
+

+ 242 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/Apl.java

@@ -0,0 +1,242 @@
+package com.adc.iv;
+
+import android.app.Application;
+import android.content.Context;
+import android.content.res.Configuration;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import com.adc.iv.Cloud;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+
+public class Apl extends Application {
+
+    private static Context context;
+
+    private  static String TAG = "Apl";
+
+    private int mnpos = 0;
+
+    static {
+        System.loadLibrary("native-lib");
+    }
+
+    public native String stringFromJNI();
+
+    public  native  int startconnet();
+
+    public native  int startconnect(String server,int nport);
+
+    public native  byte[] getByteData();
+
+    public native  void setVINMD5(String VIN,String querymd5,String ctrlmd5);
+
+    public native  byte[] makexodrobjdata(double flat,double flon);
+
+    public native void  setsenddata(byte[] xsend);
+
+    public native  byte[] getrecvdata();
+
+    public native  double[] getGPSXY(byte[] tracedata);
+
+    public native  double[] getGPSLatLonHgtHeading(byte[] tracedata);
+
+
+    public boolean mbStop = false;
+
+    private Handler handler;
+
+
+    public double [] mGPSXY = null;
+    public double [] mGPSLatLon = null;
+
+
+
+    //获取上下文
+    public static Context getAppContext(){
+        return context.getApplicationContext();
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        context = this;
+
+        String strVIN,strQuery,strCtrl,strip,strport;
+
+        strVIN = SharePreferencesUntils.getString("VIN","AAAAAAAAAAAAAAAAA");
+        strQuery = SharePreferencesUntils.getString("QueryCode","hello");
+        strCtrl = SharePreferencesUntils.getString("CtrlCode","hello");
+        strip = SharePreferencesUntils.getString("ServerIP","192.168.1.1");
+        strport = SharePreferencesUntils.getString("ServerPort","9000");
+
+        setVINMD5(strVIN,strQuery,strCtrl);
+
+        startconnect(strip,Integer.valueOf(strport));
+        byte[] x = getByteData();
+        Log.i(TAG, "data length: "+Integer.toString(x.length));
+
+        handler = new Handler() {
+
+            @Override
+
+            public void handleMessage(Message msg) {
+
+                if (msg.what == 1){
+
+                    decoderecvdata(getrecvdata());
+          //          mv.invalidate();
+
+                    //定时时间到,do something
+                    //               Log.i("ok", "handleMessage: ");
+
+                }
+
+            }
+
+        };
+
+        new Apl.timerThread().start();
+
+    }
+
+    public  void decoderecvdata(byte [] recvdata)
+    {
+        if(recvdata == null)
+        {
+ //           Log.i(TAG,"data recv is NULL");
+            return;
+        }
+
+        Cloud.cloudmsg xmsg = null;
+        try {
+            xmsg = Cloud.cloudmsg.parseFrom(recvdata);
+        } catch (InvalidProtocolBufferException e) {
+
+            e.printStackTrace();
+            return;
+        }
+        if(xmsg == null)
+        {
+            return;
+        }
+
+        if(xmsg.getXclouddataCount() == 0)
+        {
+            return;
+        }
+
+ //       Log.i(TAG,"COUNT");
+        int ncount = xmsg.getXclouddataCount();
+        int i;
+        for(i=0;i<ncount;i++)
+        {
+            Cloud.cloudunit xunit = xmsg.getXclouddata(i);
+            Log.i(TAG,xunit.getMsgname());
+            if(xunit.getMsgname().equals("simpletrace"))
+            {
+                ByteString ba = xunit.getData();
+                synchronized(this) {
+                    mGPSXY = getGPSXY(ba.toByteArray());
+                    mGPSLatLon = getGPSLatLonHgtHeading(ba.toByteArray());
+                }
+
+  //             Log.i(TAG, "receive trace map size is %d"+Integer.toString(ba.size()));
+            }
+        }
+    }
+
+    public void setplan(double flat,double flon)
+    {
+        Cloud.cloudunit.Builder xbuildder = Cloud.cloudunit.newBuilder();
+        xbuildder.setMsgname("xodrreq");
+        byte[] x = makexodrobjdata(flat,flon);
+        ByteString xbs = ByteString.copyFrom(x);
+        xbuildder.setData(xbs);
+
+        Cloud.cloudunit xunit = xbuildder.build();
+        Cloud.cloudmsg.Builder xmsgbuilder = Cloud.cloudmsg.newBuilder();
+        xmsgbuilder.addXclouddata(xunit);
+        xmsgbuilder.setXtime(0);
+        Cloud.cloudmsg xmsg = xmsgbuilder.build();
+        byte[] xsend = xmsg.toByteArray();
+
+        setsenddata(xsend);
+
+//        xbuildder.setData()
+    }
+
+
+
+    public String getAbc() {
+        return abc;
+    }
+
+    public void setAbc(String abc) {
+        this.abc = abc;
+    }
+    String abc;
+
+
+
+
+
+    /*
+    系统配置发生变更 的时候被调用 如:屏幕方向更改 、系统语言更改
+     */
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+    }
+    /*
+    系统内存吃紧时被调用,用于释放内存
+     */
+    @Override
+    public void onLowMemory() {
+        super.onLowMemory();
+    }
+
+    public int  getpos()
+    {
+        mnpos++;
+        return mnpos;
+    }
+
+    class timerThread extends Thread {
+
+        //       publicbStop=false;         // 通过给bStop设置true而停止定时操作
+
+        @Override
+        public void run() {
+
+            while(! mbStop)
+
+            {
+
+                try{
+
+                    Thread.sleep(1);//每隔1s执行一次
+
+                    Message msg = new Message();
+
+                    msg.what= 1;
+
+                    handler.sendMessage(msg);
+
+                }catch (InterruptedException e) {
+
+                    e.printStackTrace();
+
+                }
+
+            }
+
+        }
+
+    }
+
+}

+ 1554 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/Cloud.java

@@ -0,0 +1,1554 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: cloud.proto
+
+package com.adc.iv;
+
+public final class Cloud {
+  private Cloud() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  public interface cloudunitOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:com.adc.iv.cloudunit)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>required string msgname = 1;</code>
+     */
+    boolean hasMsgname();
+    /**
+     * <code>required string msgname = 1;</code>
+     */
+    java.lang.String getMsgname();
+    /**
+     * <code>required string msgname = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getMsgnameBytes();
+
+    /**
+     * <code>optional bytes data = 2;</code>
+     */
+    boolean hasData();
+    /**
+     * <code>optional bytes data = 2;</code>
+     */
+    com.google.protobuf.ByteString getData();
+  }
+  /**
+   * Protobuf type {@code com.adc.iv.cloudunit}
+   */
+  public  static final class cloudunit extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:com.adc.iv.cloudunit)
+      cloudunitOrBuilder {
+    // Use cloudunit.newBuilder() to construct.
+    private cloudunit(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private cloudunit() {
+      msgname_ = "";
+      data_ = com.google.protobuf.ByteString.EMPTY;
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private cloudunit(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              com.google.protobuf.ByteString bs = input.readBytes();
+              bitField0_ |= 0x00000001;
+              msgname_ = bs;
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              data_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudunit_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudunit_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.adc.iv.Cloud.cloudunit.class, com.adc.iv.Cloud.cloudunit.Builder.class);
+    }
+
+    private int bitField0_;
+    public static final int MSGNAME_FIELD_NUMBER = 1;
+    private volatile java.lang.Object msgname_;
+    /**
+     * <code>required string msgname = 1;</code>
+     */
+    public boolean hasMsgname() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string msgname = 1;</code>
+     */
+    public java.lang.String getMsgname() {
+      java.lang.Object ref = msgname_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          msgname_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string msgname = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getMsgnameBytes() {
+      java.lang.Object ref = msgname_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        msgname_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int DATA_FIELD_NUMBER = 2;
+    private com.google.protobuf.ByteString data_;
+    /**
+     * <code>optional bytes data = 2;</code>
+     */
+    public boolean hasData() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional bytes data = 2;</code>
+     */
+    public com.google.protobuf.ByteString getData() {
+      return data_;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      if (!hasMsgname()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, msgname_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, data_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, msgname_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, data_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof com.adc.iv.Cloud.cloudunit)) {
+        return super.equals(obj);
+      }
+      com.adc.iv.Cloud.cloudunit other = (com.adc.iv.Cloud.cloudunit) obj;
+
+      boolean result = true;
+      result = result && (hasMsgname() == other.hasMsgname());
+      if (hasMsgname()) {
+        result = result && getMsgname()
+            .equals(other.getMsgname());
+      }
+      result = result && (hasData() == other.hasData());
+      if (hasData()) {
+        result = result && getData()
+            .equals(other.getData());
+      }
+      result = result && unknownFields.equals(other.unknownFields);
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasMsgname()) {
+        hash = (37 * hash) + MSGNAME_FIELD_NUMBER;
+        hash = (53 * hash) + getMsgname().hashCode();
+      }
+      if (hasData()) {
+        hash = (37 * hash) + DATA_FIELD_NUMBER;
+        hash = (53 * hash) + getData().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static com.adc.iv.Cloud.cloudunit parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.adc.iv.Cloud.cloudunit parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.adc.iv.Cloud.cloudunit parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.adc.iv.Cloud.cloudunit parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.adc.iv.Cloud.cloudunit parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static com.adc.iv.Cloud.cloudunit parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static com.adc.iv.Cloud.cloudunit parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static com.adc.iv.Cloud.cloudunit parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static com.adc.iv.Cloud.cloudunit parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static com.adc.iv.Cloud.cloudunit parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(com.adc.iv.Cloud.cloudunit prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code com.adc.iv.cloudunit}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:com.adc.iv.cloudunit)
+        com.adc.iv.Cloud.cloudunitOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudunit_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudunit_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                com.adc.iv.Cloud.cloudunit.class, com.adc.iv.Cloud.cloudunit.Builder.class);
+      }
+
+      // Construct using com.adc.iv.Cloud.cloudunit.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        msgname_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        data_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudunit_descriptor;
+      }
+
+      public com.adc.iv.Cloud.cloudunit getDefaultInstanceForType() {
+        return com.adc.iv.Cloud.cloudunit.getDefaultInstance();
+      }
+
+      public com.adc.iv.Cloud.cloudunit build() {
+        com.adc.iv.Cloud.cloudunit result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public com.adc.iv.Cloud.cloudunit buildPartial() {
+        com.adc.iv.Cloud.cloudunit result = new com.adc.iv.Cloud.cloudunit(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.msgname_ = msgname_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.data_ = data_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof com.adc.iv.Cloud.cloudunit) {
+          return mergeFrom((com.adc.iv.Cloud.cloudunit)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(com.adc.iv.Cloud.cloudunit other) {
+        if (other == com.adc.iv.Cloud.cloudunit.getDefaultInstance()) return this;
+        if (other.hasMsgname()) {
+          bitField0_ |= 0x00000001;
+          msgname_ = other.msgname_;
+          onChanged();
+        }
+        if (other.hasData()) {
+          setData(other.getData());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasMsgname()) {
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        com.adc.iv.Cloud.cloudunit parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (com.adc.iv.Cloud.cloudunit) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.lang.Object msgname_ = "";
+      /**
+       * <code>required string msgname = 1;</code>
+       */
+      public boolean hasMsgname() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string msgname = 1;</code>
+       */
+      public java.lang.String getMsgname() {
+        java.lang.Object ref = msgname_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            msgname_ = s;
+          }
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string msgname = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getMsgnameBytes() {
+        java.lang.Object ref = msgname_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          msgname_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string msgname = 1;</code>
+       */
+      public Builder setMsgname(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        msgname_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string msgname = 1;</code>
+       */
+      public Builder clearMsgname() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        msgname_ = getDefaultInstance().getMsgname();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string msgname = 1;</code>
+       */
+      public Builder setMsgnameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        msgname_ = value;
+        onChanged();
+        return this;
+      }
+
+      private com.google.protobuf.ByteString data_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>optional bytes data = 2;</code>
+       */
+      public boolean hasData() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional bytes data = 2;</code>
+       */
+      public com.google.protobuf.ByteString getData() {
+        return data_;
+      }
+      /**
+       * <code>optional bytes data = 2;</code>
+       */
+      public Builder setData(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        data_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bytes data = 2;</code>
+       */
+      public Builder clearData() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        data_ = getDefaultInstance().getData();
+        onChanged();
+        return this;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:com.adc.iv.cloudunit)
+    }
+
+    // @@protoc_insertion_point(class_scope:com.adc.iv.cloudunit)
+    private static final com.adc.iv.Cloud.cloudunit DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new com.adc.iv.Cloud.cloudunit();
+    }
+
+    public static com.adc.iv.Cloud.cloudunit getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    @java.lang.Deprecated public static final com.google.protobuf.Parser<cloudunit>
+        PARSER = new com.google.protobuf.AbstractParser<cloudunit>() {
+      public cloudunit parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new cloudunit(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<cloudunit> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<cloudunit> getParserForType() {
+      return PARSER;
+    }
+
+    public com.adc.iv.Cloud.cloudunit getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface cloudmsgOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:com.adc.iv.cloudmsg)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional int64 xtime = 1;</code>
+     */
+    boolean hasXtime();
+    /**
+     * <code>optional int64 xtime = 1;</code>
+     */
+    long getXtime();
+
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    java.util.List<com.adc.iv.Cloud.cloudunit> 
+        getXclouddataList();
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    com.adc.iv.Cloud.cloudunit getXclouddata(int index);
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    int getXclouddataCount();
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    java.util.List<? extends com.adc.iv.Cloud.cloudunitOrBuilder> 
+        getXclouddataOrBuilderList();
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    com.adc.iv.Cloud.cloudunitOrBuilder getXclouddataOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code com.adc.iv.cloudmsg}
+   */
+  public  static final class cloudmsg extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:com.adc.iv.cloudmsg)
+      cloudmsgOrBuilder {
+    // Use cloudmsg.newBuilder() to construct.
+    private cloudmsg(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private cloudmsg() {
+      xtime_ = 0L;
+      xclouddata_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private cloudmsg(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              xtime_ = input.readInt64();
+              break;
+            }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+                xclouddata_ = new java.util.ArrayList<com.adc.iv.Cloud.cloudunit>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              xclouddata_.add(
+                  input.readMessage(com.adc.iv.Cloud.cloudunit.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+          xclouddata_ = java.util.Collections.unmodifiableList(xclouddata_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudmsg_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudmsg_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.adc.iv.Cloud.cloudmsg.class, com.adc.iv.Cloud.cloudmsg.Builder.class);
+    }
+
+    private int bitField0_;
+    public static final int XTIME_FIELD_NUMBER = 1;
+    private long xtime_;
+    /**
+     * <code>optional int64 xtime = 1;</code>
+     */
+    public boolean hasXtime() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional int64 xtime = 1;</code>
+     */
+    public long getXtime() {
+      return xtime_;
+    }
+
+    public static final int XCLOUDDATA_FIELD_NUMBER = 2;
+    private java.util.List<com.adc.iv.Cloud.cloudunit> xclouddata_;
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    public java.util.List<com.adc.iv.Cloud.cloudunit> getXclouddataList() {
+      return xclouddata_;
+    }
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    public java.util.List<? extends com.adc.iv.Cloud.cloudunitOrBuilder> 
+        getXclouddataOrBuilderList() {
+      return xclouddata_;
+    }
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    public int getXclouddataCount() {
+      return xclouddata_.size();
+    }
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    public com.adc.iv.Cloud.cloudunit getXclouddata(int index) {
+      return xclouddata_.get(index);
+    }
+    /**
+     * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+     */
+    public com.adc.iv.Cloud.cloudunitOrBuilder getXclouddataOrBuilder(
+        int index) {
+      return xclouddata_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      for (int i = 0; i < getXclouddataCount(); i++) {
+        if (!getXclouddata(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt64(1, xtime_);
+      }
+      for (int i = 0; i < xclouddata_.size(); i++) {
+        output.writeMessage(2, xclouddata_.get(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(1, xtime_);
+      }
+      for (int i = 0; i < xclouddata_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, xclouddata_.get(i));
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof com.adc.iv.Cloud.cloudmsg)) {
+        return super.equals(obj);
+      }
+      com.adc.iv.Cloud.cloudmsg other = (com.adc.iv.Cloud.cloudmsg) obj;
+
+      boolean result = true;
+      result = result && (hasXtime() == other.hasXtime());
+      if (hasXtime()) {
+        result = result && (getXtime()
+            == other.getXtime());
+      }
+      result = result && getXclouddataList()
+          .equals(other.getXclouddataList());
+      result = result && unknownFields.equals(other.unknownFields);
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasXtime()) {
+        hash = (37 * hash) + XTIME_FIELD_NUMBER;
+        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+            getXtime());
+      }
+      if (getXclouddataCount() > 0) {
+        hash = (37 * hash) + XCLOUDDATA_FIELD_NUMBER;
+        hash = (53 * hash) + getXclouddataList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static com.adc.iv.Cloud.cloudmsg parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.adc.iv.Cloud.cloudmsg parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.adc.iv.Cloud.cloudmsg parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.adc.iv.Cloud.cloudmsg parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.adc.iv.Cloud.cloudmsg parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static com.adc.iv.Cloud.cloudmsg parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static com.adc.iv.Cloud.cloudmsg parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static com.adc.iv.Cloud.cloudmsg parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static com.adc.iv.Cloud.cloudmsg parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static com.adc.iv.Cloud.cloudmsg parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(com.adc.iv.Cloud.cloudmsg prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code com.adc.iv.cloudmsg}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:com.adc.iv.cloudmsg)
+        com.adc.iv.Cloud.cloudmsgOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudmsg_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudmsg_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                com.adc.iv.Cloud.cloudmsg.class, com.adc.iv.Cloud.cloudmsg.Builder.class);
+      }
+
+      // Construct using com.adc.iv.Cloud.cloudmsg.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getXclouddataFieldBuilder();
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        xtime_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        if (xclouddataBuilder_ == null) {
+          xclouddata_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+        } else {
+          xclouddataBuilder_.clear();
+        }
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return com.adc.iv.Cloud.internal_static_com_adc_iv_cloudmsg_descriptor;
+      }
+
+      public com.adc.iv.Cloud.cloudmsg getDefaultInstanceForType() {
+        return com.adc.iv.Cloud.cloudmsg.getDefaultInstance();
+      }
+
+      public com.adc.iv.Cloud.cloudmsg build() {
+        com.adc.iv.Cloud.cloudmsg result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public com.adc.iv.Cloud.cloudmsg buildPartial() {
+        com.adc.iv.Cloud.cloudmsg result = new com.adc.iv.Cloud.cloudmsg(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.xtime_ = xtime_;
+        if (xclouddataBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) == 0x00000002)) {
+            xclouddata_ = java.util.Collections.unmodifiableList(xclouddata_);
+            bitField0_ = (bitField0_ & ~0x00000002);
+          }
+          result.xclouddata_ = xclouddata_;
+        } else {
+          result.xclouddata_ = xclouddataBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof com.adc.iv.Cloud.cloudmsg) {
+          return mergeFrom((com.adc.iv.Cloud.cloudmsg)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(com.adc.iv.Cloud.cloudmsg other) {
+        if (other == com.adc.iv.Cloud.cloudmsg.getDefaultInstance()) return this;
+        if (other.hasXtime()) {
+          setXtime(other.getXtime());
+        }
+        if (xclouddataBuilder_ == null) {
+          if (!other.xclouddata_.isEmpty()) {
+            if (xclouddata_.isEmpty()) {
+              xclouddata_ = other.xclouddata_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+            } else {
+              ensureXclouddataIsMutable();
+              xclouddata_.addAll(other.xclouddata_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.xclouddata_.isEmpty()) {
+            if (xclouddataBuilder_.isEmpty()) {
+              xclouddataBuilder_.dispose();
+              xclouddataBuilder_ = null;
+              xclouddata_ = other.xclouddata_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+              xclouddataBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getXclouddataFieldBuilder() : null;
+            } else {
+              xclouddataBuilder_.addAllMessages(other.xclouddata_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getXclouddataCount(); i++) {
+          if (!getXclouddata(i).isInitialized()) {
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        com.adc.iv.Cloud.cloudmsg parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (com.adc.iv.Cloud.cloudmsg) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private long xtime_ ;
+      /**
+       * <code>optional int64 xtime = 1;</code>
+       */
+      public boolean hasXtime() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional int64 xtime = 1;</code>
+       */
+      public long getXtime() {
+        return xtime_;
+      }
+      /**
+       * <code>optional int64 xtime = 1;</code>
+       */
+      public Builder setXtime(long value) {
+        bitField0_ |= 0x00000001;
+        xtime_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 xtime = 1;</code>
+       */
+      public Builder clearXtime() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        xtime_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      private java.util.List<com.adc.iv.Cloud.cloudunit> xclouddata_ =
+        java.util.Collections.emptyList();
+      private void ensureXclouddataIsMutable() {
+        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+          xclouddata_ = new java.util.ArrayList<com.adc.iv.Cloud.cloudunit>(xclouddata_);
+          bitField0_ |= 0x00000002;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          com.adc.iv.Cloud.cloudunit, com.adc.iv.Cloud.cloudunit.Builder, com.adc.iv.Cloud.cloudunitOrBuilder> xclouddataBuilder_;
+
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public java.util.List<com.adc.iv.Cloud.cloudunit> getXclouddataList() {
+        if (xclouddataBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(xclouddata_);
+        } else {
+          return xclouddataBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public int getXclouddataCount() {
+        if (xclouddataBuilder_ == null) {
+          return xclouddata_.size();
+        } else {
+          return xclouddataBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public com.adc.iv.Cloud.cloudunit getXclouddata(int index) {
+        if (xclouddataBuilder_ == null) {
+          return xclouddata_.get(index);
+        } else {
+          return xclouddataBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public Builder setXclouddata(
+          int index, com.adc.iv.Cloud.cloudunit value) {
+        if (xclouddataBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureXclouddataIsMutable();
+          xclouddata_.set(index, value);
+          onChanged();
+        } else {
+          xclouddataBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public Builder setXclouddata(
+          int index, com.adc.iv.Cloud.cloudunit.Builder builderForValue) {
+        if (xclouddataBuilder_ == null) {
+          ensureXclouddataIsMutable();
+          xclouddata_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          xclouddataBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public Builder addXclouddata(com.adc.iv.Cloud.cloudunit value) {
+        if (xclouddataBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureXclouddataIsMutable();
+          xclouddata_.add(value);
+          onChanged();
+        } else {
+          xclouddataBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public Builder addXclouddata(
+          int index, com.adc.iv.Cloud.cloudunit value) {
+        if (xclouddataBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureXclouddataIsMutable();
+          xclouddata_.add(index, value);
+          onChanged();
+        } else {
+          xclouddataBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public Builder addXclouddata(
+          com.adc.iv.Cloud.cloudunit.Builder builderForValue) {
+        if (xclouddataBuilder_ == null) {
+          ensureXclouddataIsMutable();
+          xclouddata_.add(builderForValue.build());
+          onChanged();
+        } else {
+          xclouddataBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public Builder addXclouddata(
+          int index, com.adc.iv.Cloud.cloudunit.Builder builderForValue) {
+        if (xclouddataBuilder_ == null) {
+          ensureXclouddataIsMutable();
+          xclouddata_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          xclouddataBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public Builder addAllXclouddata(
+          java.lang.Iterable<? extends com.adc.iv.Cloud.cloudunit> values) {
+        if (xclouddataBuilder_ == null) {
+          ensureXclouddataIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, xclouddata_);
+          onChanged();
+        } else {
+          xclouddataBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public Builder clearXclouddata() {
+        if (xclouddataBuilder_ == null) {
+          xclouddata_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+          onChanged();
+        } else {
+          xclouddataBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public Builder removeXclouddata(int index) {
+        if (xclouddataBuilder_ == null) {
+          ensureXclouddataIsMutable();
+          xclouddata_.remove(index);
+          onChanged();
+        } else {
+          xclouddataBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public com.adc.iv.Cloud.cloudunit.Builder getXclouddataBuilder(
+          int index) {
+        return getXclouddataFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public com.adc.iv.Cloud.cloudunitOrBuilder getXclouddataOrBuilder(
+          int index) {
+        if (xclouddataBuilder_ == null) {
+          return xclouddata_.get(index);  } else {
+          return xclouddataBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public java.util.List<? extends com.adc.iv.Cloud.cloudunitOrBuilder> 
+           getXclouddataOrBuilderList() {
+        if (xclouddataBuilder_ != null) {
+          return xclouddataBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(xclouddata_);
+        }
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public com.adc.iv.Cloud.cloudunit.Builder addXclouddataBuilder() {
+        return getXclouddataFieldBuilder().addBuilder(
+            com.adc.iv.Cloud.cloudunit.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public com.adc.iv.Cloud.cloudunit.Builder addXclouddataBuilder(
+          int index) {
+        return getXclouddataFieldBuilder().addBuilder(
+            index, com.adc.iv.Cloud.cloudunit.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .com.adc.iv.cloudunit xclouddata = 2;</code>
+       */
+      public java.util.List<com.adc.iv.Cloud.cloudunit.Builder> 
+           getXclouddataBuilderList() {
+        return getXclouddataFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          com.adc.iv.Cloud.cloudunit, com.adc.iv.Cloud.cloudunit.Builder, com.adc.iv.Cloud.cloudunitOrBuilder> 
+          getXclouddataFieldBuilder() {
+        if (xclouddataBuilder_ == null) {
+          xclouddataBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              com.adc.iv.Cloud.cloudunit, com.adc.iv.Cloud.cloudunit.Builder, com.adc.iv.Cloud.cloudunitOrBuilder>(
+                  xclouddata_,
+                  ((bitField0_ & 0x00000002) == 0x00000002),
+                  getParentForChildren(),
+                  isClean());
+          xclouddata_ = null;
+        }
+        return xclouddataBuilder_;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:com.adc.iv.cloudmsg)
+    }
+
+    // @@protoc_insertion_point(class_scope:com.adc.iv.cloudmsg)
+    private static final com.adc.iv.Cloud.cloudmsg DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new com.adc.iv.Cloud.cloudmsg();
+    }
+
+    public static com.adc.iv.Cloud.cloudmsg getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    @java.lang.Deprecated public static final com.google.protobuf.Parser<cloudmsg>
+        PARSER = new com.google.protobuf.AbstractParser<cloudmsg>() {
+      public cloudmsg parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new cloudmsg(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<cloudmsg> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<cloudmsg> getParserForType() {
+      return PARSER;
+    }
+
+    public com.adc.iv.Cloud.cloudmsg getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_com_adc_iv_cloudunit_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_com_adc_iv_cloudunit_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_com_adc_iv_cloudmsg_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_com_adc_iv_cloudmsg_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\013cloud.proto\022\ncom.adc.iv\"*\n\tcloudunit\022\017" +
+      "\n\007msgname\030\001 \002(\t\022\014\n\004data\030\002 \001(\014\"D\n\010cloudms" +
+      "g\022\r\n\005xtime\030\001 \001(\003\022)\n\nxclouddata\030\002 \003(\0132\025.c" +
+      "om.adc.iv.cloudunit"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+    internal_static_com_adc_iv_cloudunit_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_com_adc_iv_cloudunit_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_com_adc_iv_cloudunit_descriptor,
+        new java.lang.String[] { "Msgname", "Data", });
+    internal_static_com_adc_iv_cloudmsg_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_com_adc_iv_cloudmsg_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_com_adc_iv_cloudmsg_descriptor,
+        new java.lang.String[] { "Xtime", "Xclouddata", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}

+ 73 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/CustomDialog.java

@@ -0,0 +1,73 @@
+package com.adc.iv;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.view.Gravity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.EditText;
+
+public class CustomDialog extends Dialog {
+
+    private Context context;
+
+    private EditText metVIN;
+    private  EditText metQuery;
+    private  EditText metCtrl;
+    private EditText metserverip;
+    private EditText metport;
+
+    public CustomDialog(Context context) {
+        super(context);
+//        super(context, R.style.custom_dialog2_style);
+        init(context);
+    }
+
+    public void init(Context context) {
+        this.context = context;
+        setContentView(R.layout.custom);
+
+        Window window = getWindow();
+ //       window.setBackgroundDrawableResource(R.drawable.custom_dialog1_bg);//设置window的背景色
+        WindowManager.LayoutParams lp = window.getAttributes();
+        window.setGravity(Gravity.BOTTOM);
+
+        lp.x = 40;
+        lp.y = 40;
+        lp.width = 1000;
+        lp.height = 1000;
+        lp.alpha = 0.6f;
+        window.setAttributes(lp);
+
+        setCanceledOnTouchOutside(true);//设置点击Dialog外部任意区域关闭Dialog
+
+        metVIN = (EditText)findViewById(R.id.editTextTextPersonNameSetVIN);
+        metQuery = (EditText)findViewById(R.id.editTextTextPasswordSetQuery);
+        metCtrl = (EditText)findViewById(R.id.editTextTextPasswordSetCtrl);
+        metserverip = (EditText)findViewById(R.id.editTextTextPersonNameSetIP);
+        metport = (EditText)findViewById(R.id.editTextNumberSetPort);
+
+        metVIN.setText(SharePreferencesUntils.getString("VIN","AAAAAAAAAAAAAAAAA"));
+        metQuery.setText(SharePreferencesUntils.getString("QueryCode","hello"));
+        metCtrl.setText(SharePreferencesUntils.getString("CtrlCode","hello"));
+        metserverip.setText(SharePreferencesUntils.getString("ServerIP","192.168.1.1"));
+        metport.setText(SharePreferencesUntils.getString("ServerPort","9000"));
+
+        Button bt = findViewById(R.id.button_set);
+        bt.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                SharePreferencesUntils.putString("VIN",metVIN.getText().toString());
+                SharePreferencesUntils.putString("QueryCode",metQuery.getText().toString());
+                SharePreferencesUntils.putString("CtrlCode",metCtrl.getText().toString());
+                SharePreferencesUntils.putString("ServerIP",metserverip.getText().toString());
+                SharePreferencesUntils.putString("ServerPort",metport.getText().toString());
+
+            }
+        });
+
+
+    }
+}

+ 520 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/MainActivity.java

@@ -0,0 +1,520 @@
+package com.adc.iv;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.PackageManager;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.location.Location;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.baidu.mapapi.SDKInitializer;
+import com.baidu.mapapi.map.BaiduMap;
+import com.baidu.mapapi.map.MapStatus;
+import com.baidu.mapapi.map.MapStatusUpdate;
+import com.baidu.mapapi.map.MapStatusUpdateFactory;
+import com.baidu.mapapi.map.MapView;
+import com.baidu.mapapi.map.OverlayOptions;
+import com.baidu.mapapi.map.Polyline;
+import com.baidu.mapapi.map.PolylineOptions;
+import com.baidu.mapapi.model.LatLng;
+import com.baidu.mapapi.utils.CoordinateConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MainActivity extends AppCompatActivity {
+
+
+    private MapView mMapView;
+    private BaiduMap mMap;
+    private MyView mv;
+    private boolean mbStop = false;
+    private Handler handler;
+    private int mindex = 0;
+
+    private final String TAG = "Main";
+
+    private EditText metStationName;
+    private EditText metLon;
+    private EditText metLat;
+    private Spinner mSpinner;
+    private ArrayAdapter<String> madapter;
+    private static final int STATIONMAX = 1000;
+
+    private Apl mapl;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+
+        mapl = (Apl) getApplication();
+
+        setContentView(R.layout.activity_main);
+
+        LinearLayout lx = findViewById(R.id.mainll);
+
+        try {
+
+            SDKInitializer.initialize(getApplicationContext());
+
+        } catch (Exception e) {
+
+            Log.e("Error", e.getMessage());
+
+        }
+
+
+        mMapView = new MapView(this);
+        lx.addView(mMapView);
+        mMapView.setMinimumHeight(1920);
+
+        mMap = mMapView.getMap();
+
+        LatLng x = new LatLng(39, 117);
+        MapStatus mapStatus = new MapStatus.Builder()
+                .target(x)
+                .zoom(15)
+                .build();
+        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);
+        mMap.setMapStatus(mapStatusUpdate);
+
+
+        LocationManager locationManager;
+        //获取地理位置管理器
+        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+        //获取所有可用的位置提供器
+        List<String> providers = locationManager.getProviders(true);
+        String locationProvider;
+        if (providers.contains(LocationManager.GPS_PROVIDER)) {
+            //如果是GPS
+            locationProvider = LocationManager.GPS_PROVIDER;
+        } else if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
+            //如果是Network
+            locationProvider = LocationManager.NETWORK_PROVIDER;
+        } else {
+            Toast.makeText(this, "没有可用的位置提供器", Toast.LENGTH_SHORT).show();
+            return;
+        }
+
+
+        //获取Location
+        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+            // TODO: Consider calling
+            //    ActivityCompat#requestPermissions
+            // here to request the missing permissions, and then overriding
+            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
+            //                                          int[] grantResults)
+            // to handle the case where the user grants the permission. See the documentation
+            // for ActivityCompat#requestPermissions for more details.
+            Toast.makeText(this, "没有定位权限", Toast.LENGTH_SHORT).show();
+            return;
+        }
+        Location location = locationManager.getLastKnownLocation(locationProvider);
+        if(location!=null) {
+            //不为空,显示地理位置经纬度
+            //           showLocation(location);
+            x = new LatLng(location.getLatitude(), location.getLongitude());
+            mapStatus = new MapStatus.Builder()
+                    .target(x)
+                    .zoom(15)
+                    .build();
+            mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);
+            mMap.setMapStatus(mapStatusUpdate);
+        }
+        else
+        {
+
+            locationProvider = LocationManager.NETWORK_PROVIDER;
+            location = locationManager.getLastKnownLocation(locationProvider);
+            if(location!=null) {
+                //不为空,显示地理位置经纬度
+                //           showLocation(location);
+                x = new LatLng(location.getLatitude(), location.getLongitude());
+                mapStatus = new MapStatus.Builder()
+                        .target(x)
+                        .zoom(15)
+                        .build();
+                mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);
+                mMap.setMapStatus(mapStatusUpdate);
+            }
+        }
+        //监视地理位置变化
+ //       locationManager.requestLocationUpdates(locationProvider, 3000, 1, locationListener);
+
+
+
+        mv = new MyView(this);
+        lx.addView(mv);
+        mv.setMinimumHeight(1000);
+
+        metStationName = (EditText)findViewById(R.id.editTextTextStation);
+        metLon = (EditText)findViewById(R.id.editTextTextPersonName2);
+        metLat = (EditText)findViewById(R.id.editTextTextPersonName3);
+        mSpinner = (Spinner)findViewById(R.id.spinner);
+
+
+
+
+
+        handler = new Handler() {
+
+            @Override
+
+            public void handleMessage(Message msg) {
+
+                if (msg.what == 1){
+
+                    mv.invalidate();
+
+                    //定时时间到,do something
+     //               Log.i("ok", "handleMessage: ");
+
+                }
+
+            }
+
+        };
+
+        new timerThread().start();
+
+        EditText et1 = (EditText)findViewById(R.id.editTextTextPersonName2);
+        String str = SharePreferencesUntils.getString("lat","39");
+        et1.setText(str);
+
+        Button bt = (Button)findViewById(R.id.button2);
+        bt.setOnClickListener(new View.OnClickListener() {
+                                  @Override
+                                  public void onClick(View view) {
+                                      double flat = Double.parseDouble(metLat.getText().toString());
+                                     double flon = Double.parseDouble(metLon.getText().toString()) ;
+                                      mapl.setplan(flat,flon);
+                       //               mapl.setplan(-0.0001643,0.0002258);
+
+                                  }
+                              }
+        );
+
+        Button btAddStation = (Button)findViewById(R.id.buttonaddstation);
+        btAddStation.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                String strname = metStationName.getText().toString();
+                String strlon = metLon.getText().toString();
+                String strlat = metLat.getText().toString();
+                String strstationkey = GetNewStationKey();
+                SharePreferencesUntils.putString(strstationkey+".name",strname);
+                SharePreferencesUntils.putString(strstationkey+".lon",strlon);
+                SharePreferencesUntils.putString(strstationkey+".lat",strlat);
+                updatestationlist();
+            }
+        });
+
+
+        mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
+                metStationName.setText(madapter.getItem(i));
+
+                String strselstationname = madapter.getItem(i);
+                for(i=0;i<1000;i++)
+                {
+                    String strstationkey = "station"+Integer.toString(i);
+                    String strstationame;
+
+                    strstationame = SharePreferencesUntils.getString(strstationkey+".name","nostation");
+                    if(strstationame == strselstationname) {
+                        String strlon = SharePreferencesUntils.getString(strstationkey+".lon","119");
+                        String strlat = SharePreferencesUntils.getString(strstationkey+".lat","39");
+
+                        metLon.setText(strlon);
+                        metLat.setText(strlat);
+                        break;
+
+
+                    }
+
+
+                }
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> adapterView) {
+
+            }
+        });
+
+
+        Button btLoadFile = (Button)findViewById(R.id.button_loadfile);
+        btLoadFile.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                //Create FileOpenDialog and register a callback
+                /////////////////////////////////////////////////////////////////////////////////////////////////
+                CustomDialog xcd = new CustomDialog(MainActivity.this);
+                xcd.show();
+
+            }
+        });
+
+        updatestationlist();
+
+
+    }
+
+    private  void updatestationlist()
+    {
+        int i;
+        madapter=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item);
+        for(i=0;i<1000;i++)
+        {
+            String strstationkey = "station"+Integer.toString(i);
+            String strstationame;
+
+            strstationame = SharePreferencesUntils.getString(strstationkey+".name","nostation");
+            if(strstationame != "nostation") {
+                String strlon = SharePreferencesUntils.getString(strstationkey+".lon","119");
+                String strlat = SharePreferencesUntils.getString(strstationkey+".lat","39");
+
+                madapter.add(strstationame);
+
+
+            }
+
+
+        }
+        madapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+//绑定 Adapter到控件
+        mSpinner.setAdapter(madapter);
+    }
+
+    private  String GetNewStationKey()
+    {
+        int i;
+        String strrtn = "hello";
+        for(i=0;i<1000;i++)
+        {
+            String strstationkey = "station"+Integer.toString(i);
+            String strstationame;
+            strstationame = SharePreferencesUntils.getString(strstationkey+".name","nostation");
+            if(strstationame == "nostation") {
+                strrtn = strstationkey;
+                break;
+            }
+        }
+        return  strrtn;
+    }
+
+
+
+
+    class timerThread extends Thread {
+
+ //       publicbStop=false;         // 通过给bStop设置true而停止定时操作
+
+        @Override
+        public void run() {
+
+            while(! mbStop)
+
+            {
+
+                try{
+
+                    Thread.sleep(1000);//每隔1s执行一次
+
+                    Message msg = new Message();
+
+                    msg.what= 1;
+
+                    handler.sendMessage(msg);
+
+                }catch (InterruptedException e) {
+
+                    e.printStackTrace();
+
+                }
+
+            }
+
+        }
+
+    }
+
+    public class MyView extends View {
+
+        MyView(Context context) {
+            super(context);
+        }
+
+        double[] mgpsxy = null;
+        double[] mgpslatlon = null;
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            // TODO Auto-generated method stub
+            super.onDraw(canvas);
+
+
+            Apl apl= (Apl) getApplication();
+
+            double[] xgpsxy = null;
+            double[] xgpslatlon = null;
+            synchronized(this) {
+                xgpsxy = apl.mGPSXY;
+                xgpslatlon = apl.mGPSLatLon;
+
+            }
+
+            boolean bNeedUpdateLatLon = false;
+            if(xgpslatlon != null)
+            {
+                if(mgpslatlon == null)
+                {
+                    mgpslatlon = xgpslatlon.clone();
+                    bNeedUpdateLatLon = true;
+                }
+                else
+                {
+                    if(mgpslatlon.length != xgpslatlon.length)
+                    {
+                        mgpslatlon = xgpslatlon;
+                        bNeedUpdateLatLon = true;
+                    }
+                    else
+                    {
+                        if((mgpslatlon[0] != xgpslatlon[0])||(mgpslatlon[mgpslatlon.length -1] != xgpslatlon[xgpslatlon.length-1]))
+                        {
+                            mgpslatlon = xgpslatlon;
+                            bNeedUpdateLatLon = true;
+                        }
+                    }
+                }
+            }
+
+            if(bNeedUpdateLatLon)
+            {
+
+                CoordinateConverter converter  = new CoordinateConverter();
+
+                /**
+                 * 设置需要转化的坐标类型
+                 CoordType.COMMON:google地图、腾讯地图、高德地图所用坐标
+                 CoordType.GPS:设备采集的原始GPS坐标
+                 */
+  //              converter.from(CoordinateConverter.CoordType.COMMON);
+
+                converter.from(CoordinateConverter.CoordType.GPS);
+
+                LatLng x = new LatLng(xgpslatlon[0],xgpslatlon[1]);
+
+                //                        .zoom(19)
+                converter.coord(x);  //需要转化的坐标点
+                LatLng y = converter.convert();  //转化成百度坐标点
+                MapStatus mapStatus = new MapStatus.Builder()
+                        .target(y)
+                        .build();
+                MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);
+                mMap.setMapStatus(mapStatusUpdate);
+
+                List<LatLng>  xlistlatlon = new ArrayList<>();
+                int ncount = xgpslatlon.length/4;
+
+                int i;
+                for(i=0;i<ncount;i++)
+                {
+                    double lat = xgpslatlon[i*4+0];
+                    double lon = xgpslatlon[i*4+1];
+
+                    LatLng sourceLatLng = new LatLng(lat,lon);
+                    converter.coord(sourceLatLng);  //需要转化的坐标点
+                    LatLng desLatLng = converter.convert();  //转化成百度坐标点
+                    xlistlatlon.add(desLatLng);
+                }
+
+                OverlayOptions ooPolyline = new PolylineOptions().width(13).color(0xAAFF0000).points(xlistlatlon);
+
+                mMap.clear();
+                //在地图上画出线条图层,mPolyline:线条图层
+                Polyline mPolyline = (Polyline) mMap.addOverlay(ooPolyline);
+
+                mPolyline.setZIndex(3);
+            }
+
+
+            // 首先定义一个paint
+            Paint paint = new Paint();
+            // 绘制矩形区域-实心矩形
+            // 设置颜色
+            paint.setColor(Color.BLUE);
+            // 设置样式-填充
+            paint.setStyle(Paint.Style.FILL);
+
+            if(bNeedUpdateLatLon)
+            {
+
+            }
+
+
+            if(xgpsxy != null)
+            {
+                int ncount = xgpsxy.length/2 -2;
+                double minx,miny,maxx,maxy;
+                minx = xgpsxy[ncount*2+0];
+                miny = xgpsxy[ncount*2+1];
+                maxx = xgpsxy[ncount*2+2];
+                maxy = xgpsxy[ncount*2+3];
+                double xdiff = maxx - minx;
+                double ydiff = maxy - miny;
+                double ddiff = xdiff;
+                if(ydiff>ddiff)ddiff = ydiff;
+                int psize = 1000;
+    //            Log.i(TAG,"COUTNG  + "+ Integer.toString(ncount));
+                if(ddiff > 0)
+                {
+                    Log.i(TAG,"DIFF "+ Double.toString(ddiff));
+                    double x,y;
+                    int i;
+                    for(i=0;i<ncount;i++)
+                    {
+                        x = xgpsxy[i*2 ];
+                        y = xgpsxy[i*2 +1];
+                        x = (x-minx)*psize/ddiff + 40;
+                        y = (y-miny)*psize/ddiff;
+                        y = psize - y;
+                        canvas.drawPoint((int)x,(int)y,paint);
+                    }
+                }
+   //             Log.i(TAG,"min "+Double.toString(minx)+" " + Double.toString(miny)+" max:"+Double.toString(maxx)+" "+Double.toString(maxy));
+            }
+            // 绘制一个矩形
+        //    canvas.drawRect(new Rect(0, 0,100, 100), paint);
+
+ //           int i;
+ //           int nsize  = apl.getpos();
+ //           for(i=0;i<nsize;i++)
+  //          canvas.drawPoint(200+i,200,paint);
+   //         mindex++;
+        }
+    }
+}

+ 61 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/java/com/adc/iv/SharePreferencesUntils.java

@@ -0,0 +1,61 @@
+package com.adc.iv;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public class SharePreferencesUntils {
+
+    public static final String NAME = "user";
+
+    //存入:String类型
+    public static void putString(String key, String value){
+
+
+        SharedPreferences sp =  Apl.getAppContext().getSharedPreferences(NAME,Context.MODE_PRIVATE);
+        sp.edit().putString(key,value).apply();
+    }
+
+    //获取:String类型
+    public static String getString(String key, String defValue){
+        SharedPreferences sp =  Apl.getAppContext().getSharedPreferences(NAME,Context.MODE_PRIVATE);
+        return sp.getString(key,defValue);
+    }
+
+    //存入:int类型
+    public static void putInt(String key, int value){
+        SharedPreferences sp =  Apl.getAppContext().getSharedPreferences(NAME,Context.MODE_PRIVATE);
+        sp.edit().putInt(key,value).apply();
+    }
+
+    //获取:int类型
+    public static int getInt(String key, int defValue){
+        SharedPreferences sp =  Apl.getAppContext().getSharedPreferences(NAME,Context.MODE_PRIVATE);
+        return sp.getInt(key,defValue);
+    }
+
+    //存入:boolean类型
+    public static void putBoolean(String key, boolean value){
+        SharedPreferences sp =  Apl.getAppContext().getSharedPreferences(NAME,Context.MODE_PRIVATE);
+        sp.edit().putBoolean(key,value).apply();
+    }
+
+    //获取:boolean类型
+    public static boolean getBoolean(String key, boolean defValue){
+        SharedPreferences sp =  Apl.getAppContext().getSharedPreferences(NAME,Context.MODE_PRIVATE);
+        return sp.getBoolean(key,defValue);
+    }
+
+    //刪除 单个
+    public static void deleShare(String key){
+        SharedPreferences sp =  Apl.getAppContext().getSharedPreferences(NAME,Context.MODE_PRIVATE);
+        sp.edit().remove(key).apply();
+    }
+
+    //刪除 全部
+    public static void deleAll(){
+        SharedPreferences sp =  Apl.getAppContext().getSharedPreferences(NAME,Context.MODE_PRIVATE);
+        sp.edit().clear().apply();
+    }
+
+}
+

+ 16 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/proto/cloud.proto

@@ -0,0 +1,16 @@
+syntax = "proto2";
+
+package com.adc.iv;
+
+message cloudunit
+{
+  required string msgname = 1;
+  optional bytes data = 2;
+};
+
+message cloudmsg
+{
+  optional int64 xtime = 1;
+  repeated cloudunit xclouddata = 2; 
+};
+

+ 30 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/drawable-v24/ic_launcher_foreground.xml

@@ -0,0 +1,30 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                android:endX="85.84757"
+                android:endY="92.4963"
+                android:startX="42.9492"
+                android:startY="49.59793"
+                android:type="linear">
+                <item
+                    android:color="#44000000"
+                    android:offset="0.0" />
+                <item
+                    android:color="#00000000"
+                    android:offset="1.0" />
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillType="nonZero"
+        android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+</vector>

+ 170 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/drawable/ic_launcher_background.xml

@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillColor="#3DDC84"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+</vector>

+ 186 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/layout/activity_main.xml

@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity">
+
+
+    <LinearLayout
+        android:id="@+id/mainll"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <Spinner
+                android:id="@+id/spinner"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+
+            <EditText
+                android:id="@+id/editTextTextStation"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:ems="10"
+                android:inputType="textPersonName"
+                android:text="Station"
+                android:textSize="15sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="10dp"
+            android:orientation="horizontal"></LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <LinearLayout
+                android:layout_width="20dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:orientation="horizontal"></LinearLayout>
+
+            <Button
+                android:id="@+id/buttonaddstation"
+                android:layout_width="200dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:background="#8BC34A"
+                android:text="添加站点"
+                android:textSize="15sp" />
+
+            <LinearLayout
+                android:layout_width="30dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:orientation="horizontal"></LinearLayout>
+
+            <Button
+                android:id="@+id/buttondelstation"
+                android:layout_width="200dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:background="#E91E63"
+                android:text="删除站点"
+                android:textSize="15sp" />
+
+            <LinearLayout
+                android:layout_width="20dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:orientation="horizontal"></LinearLayout>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/textView"
+                android:layout_width="100dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="2"
+                android:text="   经度:"
+                android:textSize="15sp" />
+
+            <EditText
+                android:id="@+id/editTextTextPersonName2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="2"
+                android:ems="10"
+                android:inputType="numberSigned|numberDecimal"
+                android:text="Name"
+                android:textSize="15sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/textView2"
+                android:layout_width="100dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="   纬度:"
+                android:textSize="15sp" />
+
+            <EditText
+                android:id="@+id/editTextTextPersonName3"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:ems="10"
+                android:inputType="numberSigned|number|numberDecimal"
+                android:text="38"
+                android:textSize="15sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <LinearLayout
+                android:layout_width="20dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:orientation="horizontal"></LinearLayout>
+
+            <Button
+                android:id="@+id/button_call"
+                android:layout_width="200dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:background="#8BC34A"
+                android:text="到当前位置" />
+
+            <LinearLayout
+                android:layout_width="30dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:orientation="horizontal"></LinearLayout>
+
+            <Button
+                android:id="@+id/button2"
+                android:layout_width="200dp"
+                android:layout_height="wrap_content"
+                android:background="#009688"
+                android:text="设置目标坐标" />
+
+            <LinearLayout
+                android:layout_width="20dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:orientation="horizontal"></LinearLayout>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <Button
+                android:id="@+id/button_loadfile"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="Setting" />
+        </LinearLayout>
+
+    </LinearLayout>
+</ScrollView>

+ 155 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/layout/custom.xml

@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="30dp"
+            android:orientation="horizontal">
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/textView_vin"
+                android:layout_width="80dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="VIN" />
+
+            <EditText
+                android:id="@+id/editTextTextPersonNameSetVIN"
+                android:layout_width="230dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:ems="10"
+                android:inputType="textPersonName"
+                android:text="Name" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/textView4"
+                android:layout_width="80dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="查询码:" />
+
+            <EditText
+                android:id="@+id/editTextTextPasswordSetQuery"
+                android:layout_width="230dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:ems="10"
+                android:inputType="textPassword" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/textView5"
+                android:layout_width="80dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="控制码" />
+
+            <EditText
+                android:id="@+id/editTextTextPasswordSetCtrl"
+                android:layout_width="230dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:ems="10"
+                android:inputType="textPassword" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/textView6"
+                android:layout_width="80dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="服务器ip" />
+
+            <EditText
+                android:id="@+id/editTextTextPersonNameSetIP"
+                android:layout_width="230dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:ems="10"
+                android:inputType="textUri|number|textPersonName"
+                android:text="192.168.1.1" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/textView7"
+                android:layout_width="80dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="服务器端口" />
+
+            <EditText
+                android:id="@+id/editTextNumberSetPort"
+                android:layout_width="230dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:ems="10"
+                android:inputType="number"
+                android:text="9000" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <Button
+                android:id="@+id/button_set"
+                android:layout_width="100dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="应用" />
+
+            <LinearLayout
+                android:layout_width="100dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:orientation="horizontal"></LinearLayout>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal"></LinearLayout>
+    </LinearLayout>
+</ScrollView>

+ 5 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

+ 5 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-hdpi/ic_launcher.png


TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-hdpi/ic_launcher_round.png


TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-mdpi/ic_launcher.png


TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-mdpi/ic_launcher_round.png


TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xhdpi/ic_launcher.png


TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png


TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png


TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png


+ 6 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#6200EE</color>
+    <color name="colorPrimaryDark">#3700B3</color>
+    <color name="colorAccent">#03DAC5</color>
+</resources>

+ 3 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">ADCIV Cloud</string>
+</resources>

+ 10 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/main/res/values/styles.xml

@@ -0,0 +1,10 @@
+<resources>
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+</resources>

+ 17 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/app/src/test/java/com/example/myapplication/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.example.myapplication;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 28 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/build.gradle

@@ -0,0 +1,28 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+    dependencies {
+        classpath "com.android.tools.build:gradle:4.0.1"
+        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.6'
+
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 19 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/gradle.properties

@@ -0,0 +1,19 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true

TEMPAT SAMPAH
天津大学/tjuvv7-src/src/android/ADCCloud/gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Mon Sep 07 10:11:14 CST 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

+ 172 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/gradlew

@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"

+ 84 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/gradlew.bat

@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 9 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/local.properties

@@ -0,0 +1,9 @@
+## This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# Location of the SDK. This is only used by Gradle.
+# For customization when using a Version Control System, please read the
+# header note.
+#Tue Sep 08 14:30:04 CST 2020
+ndk.dir=/home/yuchuli/Android/Sdk/ndk/21.3.6528147
+sdk.dir=/home/yuchuli/Android/Sdk

+ 2 - 0
天津大学/tjuvv7-src/src/android/ADCCloud/settings.gradle

@@ -0,0 +1,2 @@
+include ':app'
+rootProject.name = "My Application"

+ 55 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/Time_Manager.pro

@@ -0,0 +1,55 @@
+QT       -= gui
+
+QT += dbus
+
+TARGET = datamanager
+TEMPLATE = lib
+
+DEFINES += DATAMANAGER_LIBRARY
+
+CONFIG += plugin
+
+DEFINES += QT_DEPRECATED_WARNINGS
+
+SOURCES += \
+#        ../../include/msgtype/cameraobject.pb.cc \
+#        ../../include/msgtype/cameraobjectarray.pb.cc \
+        ../../include/msgtype/object.pb.cc \
+        ../../include/msgtype/objectarray.pb.cc \
+        ../../include/msgtype/obstacles.pb.cc \
+        ../../include/msgtype/radarobject.pb.cc \
+        ../../include/msgtype/radarobjectarray.pb.cc \
+        ../../include/msgtype/rawpic.pb.cc \
+        data_manager.cpp \
+        time_manager.cpp \
+        timer.cpp \
+        worker.cpp
+
+HEADERS += \
+#    ../../include/msgtype/cameraobject.pb.h \
+#    ../../include/msgtype/cameraobjectarray.pb.h \
+    ../../include/msgtype/object.pb.h \
+    ../../include/msgtype/objectarray.pb.h \
+    ../../include/msgtype/obstacles.pb.h \
+    ../../include/msgtype/radarobject.pb.h \
+    ../../include/msgtype/radarobjectarray.pb.h \
+    ../../include/msgtype/rawpic.pb.h \
+#    ../../include/msgtype/uradar.pb.h \
+    data_manager.h \
+    time_manager.h \
+    timer.h \
+    worker.h
+
+unix {
+    target.path = /usr/lib
+    INSTALLS += target
+}
+
+INCLUDEPATH += $$PWD/../../include/msgtype
+
+#INCLUDEPATH += $$PWD/../../common/Time_Manager_0714
+
+LIBS += -lprotobuf
+
+INCLUDEPATH += $$PWD/../../../include/
+LIBS += -L$$PWD/../../../bin/ -lxmlparam -lmodulecomm -ldatamanager

+ 79 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/data_manager.cpp

@@ -0,0 +1,79 @@
+#include "data_manager.h"
+
+namespace iv{
+
+//void DataManager::init()
+//{
+//    data_manager_ptr_ = std::make_shared<iv::TimeManager>(10);
+//};
+
+void DataManager::SetDataCallback(DataCallback callback)
+{
+    data_manager_ptr_ = std::make_shared<iv::TimeManager>(10);
+    if(data_manager_ptr_)
+    {
+        data_manager_ptr_->SetDataCallback(callback);
+    }
+}
+
+void DataManager::SetRVCallback(RVCallback rvcallback)
+{
+    rv_manager_ptr_ = std::make_shared<iv::TimeManager>(30);
+    if(rv_manager_ptr_)
+    {
+        rv_manager_ptr_->SetRVCallback(rvcallback);
+    }
+}
+
+
+
+
+
+void DataManager::SetCamera(iv::vision::ObstacleInfo &vision_object_array)
+{
+    if(data_manager_ptr_)
+    {
+        data_manager_ptr_->CacheCameraData(vision_object_array);
+    }
+    if(rv_manager_ptr_)
+    {
+        rv_manager_ptr_->CacheCameraData(vision_object_array);
+    }
+
+}
+
+void DataManager::SetLidar(iv::lidar::objectarray &lidar_object_array)
+{
+    if(data_manager_ptr_)
+    {
+        data_manager_ptr_->CacheLidarData(lidar_object_array);
+    }
+}
+
+void DataManager::SetRadar(iv::radar::radarobjectarray &radar_object_array)
+{
+    if(data_manager_ptr_)
+    {
+        data_manager_ptr_->CacheRadarData(radar_object_array);
+    }
+    if(rv_manager_ptr_)
+    {
+        rv_manager_ptr_->CacheRadarData(radar_object_array);
+    }
+}
+
+
+
+void DataManager::Ready()
+{
+    if(data_manager_ptr_)
+    {
+        data_manager_ptr_->Run();
+    }
+    if(rv_manager_ptr_)
+    {
+        rv_manager_ptr_->Run();
+    }
+}
+
+}

+ 50 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/data_manager.h

@@ -0,0 +1,50 @@
+#ifndef DATA_MANAGER_H
+#define DATA_MANAGER_H
+#include <QtCore/qglobal.h>
+
+#include <stdarg.h>
+#include "time_manager.h"
+#if defined(DATAMANAGER_LIBRARY)
+#  define DATAMANAGERSHARED_EXPORT Q_DECL_EXPORT
+#else
+#  define DATAMANAGERSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+
+namespace iv {
+
+class DATAMANAGERSHARED_EXPORT DataManager
+{
+public:
+    typedef  iv::radar::radarobjectarray RadarDataType;
+    typedef  iv::lidar::objectarray LidarDataType;
+//    typedef  iv::vision::cameraobjectarray CameraDataType;
+    typedef  iv::vision::ObstacleInfo VisionDataType;
+    typedef  std::chrono::system_clock::time_point TimeType;
+//    typedef  std::function<void(RadarDataType&, LidarDataType&,CameraDataType&)> DataCallback;
+//    typedef  std::function<void(RadarDataType&,CameraDataType&)> RVCallback;
+    typedef  std::function<void(RadarDataType&, LidarDataType&,VisionDataType&)> DataCallback;
+
+    typedef  std::function<void(RadarDataType&,VisionDataType&)> RVCallback;
+
+public:
+//    void init();
+    void SetLidar(iv::lidar::objectarray& lidar_object_array);
+    void SetRadar(iv::radar::radarobjectarray& radar_object_array);
+    void SetCamera(iv::vision::ObstacleInfo& vision_object_array);
+
+    void Ready();
+
+    void SetDataCallback(DataCallback callback);
+    void SetRVCallback(RVCallback rvcallback);
+
+private:
+    std::shared_ptr<iv::TimeManager> data_manager_ptr_;
+    std::shared_ptr<iv::TimeManager> rv_manager_ptr_;
+
+};
+
+}
+
+
+#endif // DATA_MANAGER_H

+ 9 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/main.cpp

@@ -0,0 +1,9 @@
+#include <iostream>
+
+using namespace std;
+
+int main()
+{
+    cout << "Hello World!" << endl;
+    return 0;
+}

+ 218 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/time_manager.cpp

@@ -0,0 +1,218 @@
+#include "time_manager.h"
+#include <iostream>
+
+namespace iv {
+
+TimeManager::TimeManager(const float hz):Worker(hz)
+{
+    data_call_back_ = NULL;
+    rv_call_back_ = NULL;
+
+}
+
+void TimeManager::SetDataCallback(DataCallback callback)
+{
+    data_call_back_ =callback;
+}
+
+void TimeManager::SetRVCallback(RVCallback rvcallback)
+{
+    rv_call_back_ = rvcallback;
+}
+
+
+void TimeManager::CacheLidarData(const iv::lidar::objectarray& lidar_object_array)
+{
+    std::lock_guard<std::mutex> mutex_lidar_data(mutex_data_);
+    lidar_cache_.push_back(lidar_object_array);
+    while(lidar_cache_.size() > lidarCacheSize)
+    {
+        lidar_cache_.erase(lidar_cache_.begin());
+    }
+//    std::cout<<"lidar_cache_size:  "<<lidar_cache_.size()<<std::endl;
+}
+
+void TimeManager::CacheRadarData(const iv::radar::radarobjectarray &radar_object_array)
+{
+    std::lock_guard<std::mutex> mutex_radar_data(mutex_data_);
+    radar_cache_.push_back(radar_object_array);
+    while(radar_cache_.size() > radarCacheSzie)
+    {
+        radar_cache_.erase(radar_cache_.begin());
+    }
+
+//    std::cout<<"radar_cache_size:  "<<radar_cache_.size()<<std::endl;
+}
+
+void TimeManager::CacheCameraData(const iv::vision::ObstacleInfo& vision_object_array)
+{
+    std::lock_guard<std::mutex> mutex_camera_data(mutex_data_);
+    vision_cache_.push_back(vision_object_array);
+    while (vision_cache_.size() > cameraCacheSzie)
+    {
+        vision_cache_.erase(vision_cache_.begin());
+    }
+//    std::cout<<"camera_cache_size:  "<<camera_cache_.size()<<std::endl;
+}
+
+double TimeDiff(double time_point1, double time_point2)
+{
+    return (abs(time_point2-time_point1));
+
+}
+
+void TimeManager::GetDataRLV(void)
+{
+    std::lock_guard<std::mutex> mutex_get_data(mutex_data_);
+    double lidar_t,camer_t,radar_t;
+    lidar_t = lidar_cache_.begin()->timestamp();
+    radar_t = radar_cache_.begin()->mstime();
+    camer_t = vision_cache_.begin()->time();
+    if(lidar_t>=camer_t&&lidar_t>=radar_t)
+    {
+       lidar_objects_.CopyFrom(*lidar_cache_.begin());
+       lidar_cache_.erase(lidar_cache_.begin());
+
+       std::vector<double> time_diffs1,time_diffs2;
+       for(std::vector<iv::radar::radarobjectarray>::iterator radars = radar_cache_.begin();
+           radars != radar_cache_.end(); radars++)
+       {
+           time_diffs1.push_back(TimeDiff(radars->mstime(),lidar_t));
+       }
+       auto smallest1 = std::min_element(std::begin(time_diffs1),std::end(time_diffs1));
+       int index1 = std::distance(std::begin(time_diffs1),smallest1);
+       radar_objects_.CopyFrom(radar_cache_[index1]);
+       radar_cache_.erase(radar_cache_.begin(),radar_cache_.begin()+index1);
+
+       for(std::vector<iv::vision::ObstacleInfo>::iterator cameraobjs = vision_cache_.begin();
+           cameraobjs != vision_cache_.end(); cameraobjs++)
+       {
+           time_diffs2.push_back(TimeDiff(cameraobjs->time(),lidar_t));
+       }
+       auto smallest2 = std::min_element(std::begin(time_diffs2),std::end(time_diffs2));
+       int index2 = std::distance(std::begin(time_diffs2),smallest2);
+       vision_objects_.CopyFrom(vision_cache_[index2]);
+       vision_cache_.erase(vision_cache_.begin(),vision_cache_.begin()+index2);
+       time_diffs1.clear();
+       time_diffs2.clear();
+    } else if (radar_t>=camer_t&&radar_t>lidar_t) {
+        radar_objects_.CopyFrom(*radar_cache_.begin());
+        radar_cache_.erase(radar_cache_.begin());
+        std::vector<double> time_dif1,time_dif2;
+        for(std::vector<iv::lidar::objectarray>::iterator lidars = lidar_cache_.begin();
+            lidars != lidar_cache_.end(); lidars++)
+        {
+            time_dif1.push_back(TimeDiff(lidars->timestamp(),radar_t));
+        }
+        auto small1 = std::min_element(std::begin(time_dif1),std::end(time_dif1));
+        int idx1 = std::distance(std::begin(time_dif1),small1);
+        lidar_objects_.CopyFrom(lidar_cache_[idx1]);
+        lidar_cache_.erase(lidar_cache_.begin(),lidar_cache_.begin()+idx1);
+
+        for(std::vector<iv::vision::ObstacleInfo>::iterator cameraobjs = vision_cache_.begin();
+            cameraobjs != vision_cache_.end(); cameraobjs++)
+        {
+            time_dif2.push_back(TimeDiff(cameraobjs->time(),radar_t));
+        }
+        auto small2 = std::min_element(std::begin(time_dif2),std::end(time_dif2));
+        int idx2 = std::distance(std::begin(time_dif2),small2);
+        vision_objects_.CopyFrom(vision_cache_[idx2]);
+        vision_cache_.erase(vision_cache_.begin(),vision_cache_.begin()+idx2);
+        time_dif1.clear();
+        time_dif2.clear();
+}else {
+        vision_objects_.CopyFrom(*vision_cache_.begin());
+        vision_cache_.erase(vision_cache_.begin());
+        std::vector<double> time_df1,time_df2;
+        for(std::vector<iv::lidar::objectarray>::iterator lidars = lidar_cache_.begin();
+            lidars != lidar_cache_.end(); lidars++)
+        {
+            time_df1.push_back(TimeDiff(lidars->timestamp(),camer_t));
+        }
+        auto smalltime1 = std::min_element(std::begin(time_df1),std::end(time_df1));
+        int smallidx1 = std::distance(std::begin(time_df1),smalltime1);
+        lidar_objects_.CopyFrom(lidar_cache_[smallidx1]);
+        lidar_cache_.erase(lidar_cache_.begin(),lidar_cache_.begin()+smallidx1);
+
+        for(std::vector<iv::radar::radarobjectarray>::iterator radarobjs = radar_cache_.begin();
+            radarobjs != radar_cache_.end(); radarobjs++)
+        {
+            time_df2.push_back(TimeDiff(radarobjs->mstime(),radar_t));
+        }
+        auto smalltime2 = std::min_element(std::begin(time_df2),std::end(time_df2));
+        int smallidx2 = std::distance(std::begin(time_df2),smalltime2);
+        radar_objects_.CopyFrom(radar_cache_[smallidx2]);
+        radar_cache_.erase(radar_cache_.begin(),radar_cache_.begin()+smallidx2);
+        time_df1.clear();
+        time_df2.clear();
+}
+
+}
+
+void TimeManager::GetDataRV(void)
+{
+    double camer_t,radar_t;
+    radar_t = radar_cache_.begin()->mstime();
+    camer_t = vision_cache_.begin()->time();
+    if(radar_t>=camer_t)
+    {
+        radar_objects_.CopyFrom(*radar_cache_.begin());
+        radar_cache_.erase(radar_cache_.begin());
+        std::vector<double> time_dif;
+        for(std::vector<iv::vision::ObstacleInfo>::iterator cameraobjs = vision_cache_.begin();
+            cameraobjs != vision_cache_.end(); cameraobjs++)
+        {
+            time_dif.push_back(TimeDiff(cameraobjs->time(),radar_t));
+        }
+        auto small = std::min_element(std::begin(time_dif),std::end(time_dif));
+        int idx = std::distance(std::begin(time_dif),small);
+        vision_objects_.CopyFrom(vision_cache_[idx]);
+        vision_cache_.erase(vision_cache_.begin(),vision_cache_.begin()+idx);
+        time_dif.clear();
+    }else {
+        vision_objects_.CopyFrom(*vision_cache_.begin());
+        vision_cache_.erase(vision_cache_.begin());
+        std::vector<double> time_diff;
+        for(std::vector<iv::radar::radarobjectarray>::iterator radars = radar_cache_.begin();
+            radars != radar_cache_.end(); radars++)
+        {
+            time_diff.push_back(TimeDiff(radars->mstime(),camer_t));
+        }
+        auto smallest = std::min_element(std::begin(time_diff),std::end(time_diff));
+        int index = std::distance(std::begin(time_diff),smallest);
+        radar_objects_.CopyFrom(radar_cache_[index]);
+        radar_cache_.erase(radar_cache_.begin(),radar_cache_.begin()+index);
+        time_diff.clear();
+}
+//    for(int i = 0; i<radar_objects_.obj_size(); i++)
+//    {
+//        std::cout<<"x   :"<<radar_objects_.obj(i).x()<<"     y   :"<<radar_objects_.obj(i).y()<<std::endl;
+//    }
+
+
+}
+
+void TimeManager::DoWork()
+{
+
+    if((!(radar_cache_.empty()))&&(!(vision_cache_.empty()))&&(!(lidar_cache_.empty())))
+    {
+        const auto t1 = std::chrono::system_clock::now();
+        GetDataRLV();
+        const auto t2 = std::chrono::system_clock::now();
+        const auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
+        const auto fps = 1e6 / duration;
+
+        if(NULL != data_call_back_)
+        {
+            data_call_back_(radar_objects_,lidar_objects_,vision_objects_);
+        }
+    }else if ((!(radar_cache_.empty()))&&(!(vision_cache_.empty()))&&(lidar_cache_.empty())) {
+        GetDataRV();
+        if(NULL != rv_call_back_)
+        {
+            rv_call_back_(radar_objects_,vision_objects_);
+        }
+}
+}
+}

+ 80 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/time_manager.h

@@ -0,0 +1,80 @@
+#ifndef TIME_MANAGER_H
+#define TIME_MANAGER_H
+#include "radarobjectarray.pb.h"
+//#include "cameraobjectarray.pb.h"
+#include "objectarray.pb.h"
+#include "obstacles.pb.h"
+#include "worker.h"
+#include <memory>
+#include <chrono>
+#include <mutex>
+#include <algorithm>
+
+
+namespace iv {
+
+class TimeManager: public Worker
+{
+public:
+    typedef  iv::radar::radarobjectarray RadarDataType;
+    typedef  iv::lidar::objectarray LidarDataType;
+//    typedef  iv::vision::cameraobjectarray CameraDataType;
+    typedef  iv::vision::ObstacleInfo VisionDataType;
+    typedef  std::chrono::system_clock::time_point TimeType;
+//    typedef  std::function<void(RadarDataType&, LidarDataType&,CameraDataType&)> DataCallback;
+
+//    typedef  std::function<void(RadarDataType&,CameraDataType&)> RVCallback;
+
+     typedef  std::function<void(RadarDataType&, LidarDataType&,VisionDataType&)> DataCallback;
+
+     typedef  std::function<void(RadarDataType&,VisionDataType&)> RVCallback;
+
+
+    TimeManager(const float hz);
+
+    void SetDataCallback(DataCallback rlvcallback);
+    void SetRVCallback(RVCallback rvcallback);
+
+    void DoWork();
+
+    void CacheRadarData(const iv::radar::radarobjectarray& radar_object_array);
+    void CacheLidarData(const iv::lidar::objectarray& lidar_object_array);
+//    void CacheCameraData(const iv::vision::cameraobjectarray& camera_object_array);
+    void CacheCameraData(const iv::vision::ObstacleInfo& vision_object_array);
+
+    void GetDataRLV(void);
+
+    void GetDataRV(void);
+
+private:
+    std::mutex mutex_data_;
+
+
+private:
+    ///cache data
+    std::vector<iv::lidar::objectarray> lidar_cache_;
+    std::vector<iv::radar::radarobjectarray> radar_cache_;
+    std::vector<iv::vision::ObstacleInfo> vision_cache_;
+
+private:
+    iv::lidar::objectarray lidar_objects_;
+    iv::radar::radarobjectarray radar_objects_;
+    iv::vision::ObstacleInfo vision_objects_;
+
+
+static const int lidarCacheSize = 10;
+static const int radarCacheSzie = 30;
+static const int cameraCacheSzie = 20;
+
+private:
+    DataCallback data_call_back_;
+    RVCallback  rv_call_back_;
+
+
+};
+
+}
+
+
+
+#endif // TIME_MANAGER_H

+ 29 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/timer.cpp

@@ -0,0 +1,29 @@
+#include "timer.h"
+
+namespace iv
+{
+    Timer::Timer(const float& hz):
+        duration_{std::chrono::duration<float>(1.0 / hz)},
+        start_ {},
+        elapsed_{}
+
+    {
+
+    }
+
+    void Timer::Start()
+    {
+        start_ = std::chrono::system_clock::now();
+    }
+
+    void Timer::Stop()
+    {
+        elapsed_ = std::chrono::system_clock::now() - start_;
+
+        if( elapsed_ < duration_)
+        {
+            std::this_thread::sleep_for(duration_ - elapsed_);
+        }
+
+    }
+}

+ 26 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/timer.h

@@ -0,0 +1,26 @@
+#ifndef TIMER_H
+#define TIMER_H
+#include <chrono>
+#include <thread>
+
+namespace iv {
+
+class Timer{
+
+public:
+    Timer(const float& hz);
+
+    void Start();
+    void Stop();
+
+private:
+    std::chrono::duration<float> duration_;
+    std::chrono::system_clock::time_point start_;
+    std::chrono::duration<float> elapsed_;
+
+};
+
+}
+
+
+#endif // TIMER_H

+ 59 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/worker.cpp

@@ -0,0 +1,59 @@
+#include "worker.h"
+
+namespace iv {
+
+Worker::Worker(float hz):
+        timer_(hz),
+        worker_state_(WS_INIT)
+{
+    main_thread_ = std::thread(&Worker::MainThread, this);
+}
+Worker::~Worker()
+{
+    worker_state_ = WS_TERMINATE;
+    main_thread_.join();
+}
+
+void Worker::Run()
+{
+    worker_state_ = WS_RUN;
+}
+
+void Worker::Suspend()
+{
+    worker_state_ = WS_SUSPEND;
+}
+
+void Worker::Terminate()
+{
+    worker_state_ = WS_TERMINATE;
+}
+
+void Worker::MainThread()
+{
+    while (true)
+    {
+        timer_.Start();
+        if (WS_RUN == worker_state_)
+        {
+            DoWork();
+        }
+        else if (WS_INIT == worker_state_ || WS_SUSPEND == worker_state_)
+        {
+            continue;
+        }
+        else if (WS_TERMINATE == worker_state_)
+        {
+            break;
+        }
+        else
+        {
+            std::cerr<< "worker state is absolutely wrong."<<std::endl;
+        }
+
+        timer_.Stop();
+    }
+}
+
+
+}

+ 44 - 0
天津大学/tjuvv7-src/src/common/Time_Manager/worker.h

@@ -0,0 +1,44 @@
+#ifndef WORKER_H
+#define WORKER_H
+
+#include "timer.h"
+#include <iostream>
+namespace iv {
+
+class Worker
+{
+
+public:
+    enum
+    {
+        WS_INIT         = 0x001,
+        WS_RUN          = 0x002,
+        WS_SUSPEND      = 0x003,
+        WS_TERMINATE    = 0x004,
+    };
+
+public:
+    Worker(float hz=20);
+
+    virtual ~Worker();
+
+    virtual void DoWork() = 0;
+
+    void Run();
+
+    void Suspend();
+
+    void Terminate();
+
+protected:
+    void MainThread();
+
+protected:
+    std::thread main_thread_;
+    Timer timer_;
+    std::uint16_t worker_state_;
+};
+
+}
+
+#endif // WORKER_H

+ 31 - 0
天津大学/tjuvv7-src/src/common/common/VehicleParam.cpp

@@ -0,0 +1,31 @@
+
+#include "VehicleParam.h"
+
+using namespace iv;
+
+
+VehicleParam::VehicleParam()
+{
+
+
+}
+
+std::string VehicleParam::getvehicletype()
+{
+    return mstrvehicletype;
+}
+
+std::string VehicleParam::getversion()
+{
+    return mstrversion;
+}
+
+std::string VehicleParam::getvin()
+{
+    return mstrvin;
+}
+
+
+
+
+

+ 26 - 0
天津大学/tjuvv7-src/src/common/common/VehicleParam.h

@@ -0,0 +1,26 @@
+#ifndef VEHICLEPARAM_H
+#define VEHICLEPARAM_H
+
+#include <string>
+
+namespace iv {
+
+class VehicleParam
+{
+public:
+    VehicleParam();
+
+private:
+    std::string mstrvin;
+    std::string mstrversion;
+    std::string mstrvehicletype;
+
+public:
+    std::string getvin();
+    std::string getversion();
+    std::string getvehicletype();
+};
+}
+
+
+#endif

+ 565 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Junction.cpp

@@ -0,0 +1,565 @@
+#include "Junction.h"
+
+/**
+* Junction class. Holds all the junction information
+*
+*
+*
+*
+*/
+
+/**
+* Constructor. Sets basic junction parameters
+* @param name Name of the junction
+* @param id Unique ID of the junction
+*/
+Junction::Junction(	string name, string id)
+{
+	mName=name;
+	mId=id;
+}
+
+/**
+* Sets the name parameter
+*/
+void Junction::SetName(string name)
+{	mName=name;	}
+
+/**
+* Sets the ID parameter
+*/
+void Junction::SetId(string id)
+{	mId=id;	}
+
+
+/**
+* Adds a junction connection to the junction
+* @param id ID within the junction
+* @param incomingRoad ID of the incoming road
+* @param connectingRoad ID of the connecting path
+* @param contactPoint Contact point on the connecting road (start or end)
+*/
+unsigned int Junction::AddJunctionConnection(	string id,	string incomingRoad, string connectingRoad, string contactPoint)
+{	
+	// Adds a new junction connection
+	mJunctionConnectionVector.push_back(JunctionConnection(id, incomingRoad, connectingRoad, contactPoint));	
+	// Saves the index of the newly added junction connection
+	mLastAddedJunctionConnection = mJunctionConnectionVector.size()-1;
+	return mLastAddedJunctionConnection;
+}
+
+
+/**
+* Adds a priority parameter to the junction
+* @param high ID of the connecting road with higher priority
+* @param low ID of the connecting road with lower priority
+*/
+unsigned int Junction::AddJunctionPriority ( string high, string low)
+{	
+	// Check the first method in the group for details
+
+	mJunctionPriorityVector.push_back(JunctionPriorityRoad(high,low));	
+	mLastAddedJunctionPriority = mJunctionPriorityVector.size()-1;
+	return mLastAddedJunctionPriority;
+}
+
+/**
+* Adds a controller to the junction
+* @param id ID of the controller to add
+* @param type Type of control
+*/
+unsigned int Junction::AddJunctionController ( string id, string type)
+{	
+	mJunctionControllerVector.push_back(JunctionController(id,type));	
+	mLastAddedJunctionController = mJunctionControllerVector.size()-1;
+	return mLastAddedJunctionController;
+}
+//--------------
+
+/**
+ * Methods used to clone child records in the respective vectors
+ */
+unsigned int Junction::CloneJunctionConnection(unsigned int index)
+{
+	// Clone the object and insert it in the middle of the vector
+	if(index<mJunctionConnectionVector.size()-1)
+		mJunctionConnectionVector.insert(mJunctionConnectionVector.begin()+index+1, mJunctionConnectionVector[index]);
+	// or just push it to the back
+	else if(index==mJunctionConnectionVector.size()-1)
+		mJunctionConnectionVector.push_back(mJunctionConnectionVector[index]);
+	// Save the last added record index
+	mLastAddedJunctionConnection=index+1;
+	return mLastAddedJunctionConnection;
+}
+unsigned int Junction::CloneJunctionPriority(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mJunctionPriorityVector.size()-1)
+		mJunctionPriorityVector.insert(mJunctionPriorityVector.begin()+index+1, mJunctionPriorityVector[index]);
+	else if(index==mJunctionPriorityVector.size()-1)
+		mJunctionPriorityVector.push_back(mJunctionPriorityVector[index]);
+	mLastAddedJunctionPriority=index+1;
+	return mLastAddedJunctionPriority;
+}
+unsigned int Junction::CloneJunctionController(unsigned int index)
+{
+	if(index<mJunctionControllerVector.size()-1)
+		mJunctionControllerVector.insert(mJunctionControllerVector.begin()+index+1, mJunctionControllerVector[index]);
+	else if(index==mJunctionControllerVector.size()-1)
+		mJunctionControllerVector.push_back(mJunctionControllerVector[index]);
+	mLastAddedJunctionController=index+1;
+	return mLastAddedJunctionController;
+}
+
+/**
+ * Methods used to delete child records from the respective vectors
+ */
+void Junction::DeleteJunctionConnection(unsigned int index)
+{
+	mJunctionConnectionVector.erase(mJunctionConnectionVector.begin()+index);
+}
+void Junction::DeleteJunctionPriority(unsigned int index)
+{
+	mJunctionPriorityVector.erase(mJunctionPriorityVector.begin()+index);
+}
+void Junction::DeleteJunctionController(unsigned int index)
+{
+	mJunctionControllerVector.erase(mJunctionControllerVector.begin()+index);
+}
+
+/**
+* Return the name of the junction
+*/
+string Junction::GetName()
+{	return mName;	}
+
+/**
+* Return the id of the junction
+*/
+string Junction::GetId()
+{	return mId;	}
+
+/**
+* Return the vector that stores junction connections
+* @return A pointer to std::vector of JunctionConnection type that stores junction connections
+*/
+std::vector<JunctionConnection>* Junction::GetJunctionConnectionVector ()
+{	return &mJunctionConnectionVector;	}
+
+/**
+* Return the number of junction connections
+* @return An unsigned int that stores the number of junction connections
+*/
+unsigned int Junction::GetJunctionConnectionCount()
+{	return mJunctionConnectionVector.size();	}
+
+/**
+* Return the pointer to a junction connection at provided index
+* @param i Index to the junction connection that is returned
+* @return A pointer to JunctionConnection object
+*/
+JunctionConnection* Junction::GetJunctionConnection(unsigned int i)
+{	return &mJunctionConnectionVector.at(i);	}
+
+/**
+* Return the pointer to the last junction connection
+* @return A pointer to JunctionConnection object
+*/
+JunctionConnection* Junction::GetLastJunctionConnection()
+{	
+	if(mJunctionConnectionVector.size()>0)
+		return &mJunctionConnectionVector.at(mJunctionConnectionVector.size()-1);	
+	else
+		return NULL;
+}
+/**
+* Return the pointer to the last added junction connection (which might not be the one from the end of the vector)
+* @return A pointer to JunctionConnection object
+*/
+JunctionConnection* Junction::GetLastAddedJunctionConnection()
+{	
+	if(mLastAddedJunctionConnection<mJunctionConnectionVector.size())
+		return &mJunctionConnectionVector.at(mLastAddedJunctionConnection);
+	else
+		return NULL;
+}
+
+/**
+* Return the vector that stores junction priority records
+* @return A pointer to std::vector of JunctionPriorityRoad type that stores junction priority records
+*/
+std::vector<JunctionPriorityRoad>* Junction::GetJunctionPriorityVector()
+{	return &mJunctionPriorityVector;	}
+
+/**
+* Return the number of junction priority records
+* @return An unsigned int that stores the number of junction priority records
+*/
+unsigned int Junction::GetJunctionPriorityCount()
+{	return mJunctionPriorityVector.size();	}
+
+/**
+* Return the pointer to a junction priority record at provided index
+* @param i Index to the junction priority record that is returned
+* @return A pointer to JunctionPriorityRoad object
+*/
+JunctionPriorityRoad* Junction::GetJunctionPriority(unsigned int i)
+{	return &mJunctionPriorityVector.at(i);	}
+
+/**
+* Return the pointer to the last junction priority record
+* @return A pointer to JunctionPriorityRoad object
+*/
+JunctionPriorityRoad* Junction::GetLastJunctionPriority()
+{	
+	if(mJunctionPriorityVector.size()>0)
+		return &mJunctionPriorityVector.at(mJunctionPriorityVector.size()-1);	
+	else 
+		return NULL;
+}
+
+/**
+* Return the pointer to the last added junction priority record (which might not be the one from the end of the vector)
+* @return A pointer to JunctionPriorityRoad object
+*/
+JunctionPriorityRoad* Junction::GetLastAddedJunctionPriority()
+{	
+	if(mLastAddedJunctionPriority<mJunctionPriorityVector.size())
+		return &mJunctionPriorityVector.at(mLastAddedJunctionPriority);
+	else
+		return NULL;
+}
+
+
+/**
+* Return the vector that stores junction controller records
+* @return A pointer to std::vector of JunctionController type that stores junction controller records
+*/
+std::vector<JunctionController>* Junction::GetJunctionControllerVector()
+{	return &mJunctionControllerVector;	}
+
+/**
+* Return the number of junction controller records
+* @return An unsigned int that stores the number of junction controller records
+*/
+unsigned int  Junction::GetJunctionControllerCount()
+{	return mJunctionControllerVector.size();	}
+
+/**
+* Return the pointer to a junction controller record at provided index
+* @param i Index to the junction controller record that is returned
+* @return A pointer to JunctionController object
+*/
+JunctionController* Junction::GetJunctionController(unsigned int i)
+{	return &mJunctionControllerVector.at(i);	}
+
+/**
+* Return the pointer to the last junction controller record
+* @return A pointer to JunctionController object
+*/
+JunctionController* Junction::GetLastJunctionController()
+{	
+	if(mJunctionControllerVector.size()>0)
+		return &mJunctionControllerVector.at(mJunctionControllerVector.size()-1);	
+	else
+		return NULL;
+}
+
+/**
+* Return the pointer to the last added junction controller record (which might not be the one from the end of the vector)
+* @return A pointer to JunctionController object
+*/
+JunctionController* Junction::GetLastAddedJunctionController()
+{	
+	if(mLastAddedJunctionController<mJunctionControllerVector.size())
+		return &mJunctionControllerVector.at(mLastAddedJunctionController);
+	else
+		return NULL;
+}
+//--------------
+
+
+/**
+* Junction connection class. Holds all the information for a connection record
+*
+*
+*
+*
+*/
+
+/**
+* Constructor. Sets basic junction connection parameters
+* @param id ID within the junction
+* @param incomingRoad ID of the incoming road
+* @param connectingRoad ID of the connecting path
+* @param contactPoint Contact point on the connecting road (start / end)
+*/
+JunctionConnection::JunctionConnection(	string id, string incomingRoad, string connectingRoad, string contactPoint	)
+{
+	mId=id;
+	mIncomingRoad=incomingRoad;
+	mConnectingRoad=connectingRoad;
+	mContactPoint=contactPoint;	
+}
+
+/**
+* Set the ID parameter
+*/
+void JunctionConnection::SetId(string id)
+{	mId=id;	}
+
+/**
+* Set the ID of the incoming road 
+*/
+void JunctionConnection::SetIncomingRoad(string incomingRoad)
+{	mIncomingRoad=incomingRoad;	}
+
+/**
+* Set the ID of the connecting path
+*/
+void JunctionConnection::SetConnectingRoad(string connectingRoad)
+{	mConnectingRoad=connectingRoad;	}
+
+/**
+* Set the contact point parameter
+* @param contactPoint Contact point of the connecting road. Can be either start or end
+*/
+void JunctionConnection::SetContactPoint(string contactPoint)
+{	mContactPoint=contactPoint;	}
+
+/**
+* Add a lane link record
+* @param from ID of the incoming lane
+* @param to ID of the connecting lane
+*/
+unsigned int JunctionConnection::AddJunctionLaneLink(int from, int to)
+{	
+	mJunctionLaneLinkVector.push_back(JunctionLaneLink(from, to));	
+	mLastAddedJunctionLaneLink = mJunctionLaneLinkVector.size()-1;
+	return mLastAddedJunctionLaneLink;
+}
+//--------------
+
+/**
+ * Method used to clone child record in the respective vectors
+ */
+unsigned int JunctionConnection::CloneJunctionLaneLink(unsigned int index)
+{
+	// Clone the object and insert it in the middle of the vector
+	if(index<mJunctionLaneLinkVector.size()-1)
+		mJunctionLaneLinkVector.insert(mJunctionLaneLinkVector.begin()+index+1, mJunctionLaneLinkVector[index]);
+	// or just push it to the back
+	else if(index==mJunctionLaneLinkVector.size()-1)
+		mJunctionLaneLinkVector.push_back(mJunctionLaneLinkVector[index]);
+	// Save the last added record index
+	mLastAddedJunctionLaneLink=index+1;
+	return mLastAddedJunctionLaneLink;
+}
+
+/**
+* Delete the lane link parameter at the provided index
+*/
+void JunctionConnection::DeleteJunctionLaneLink(unsigned int index)
+{
+	mJunctionLaneLinkVector.erase(mJunctionLaneLinkVector.begin()+index);
+}
+
+
+/**
+* Get the ID parameter
+*/
+string JunctionConnection::GetId()
+{	return mId;	}
+
+/**
+* Get the ID fo the incoming road
+*/
+string JunctionConnection::GetIncomingRoad()
+{	return mIncomingRoad;	}
+
+/**
+* Get the ID of the connecting road
+*/
+string JunctionConnection::GetConnectingRoad()
+{	return mConnectingRoad;	}
+
+/**
+* Get the contact point parameter
+*/
+string JunctionConnection::GetContactPoint()
+{	return mContactPoint;	}
+
+/**
+* Return the vector that stores junction lane link records
+* @return A pointer to std::vector of JunctionLaneLink type that stores junction lane link records
+*/
+std::vector<JunctionLaneLink>* JunctionConnection::GetJunctionLaneLinkVector()
+{	return &mJunctionLaneLinkVector;	}
+
+/**
+* Return the number of junction lane link records
+* @return An unsigned int that stores the number of junction lane link records
+*/
+unsigned int JunctionConnection::GetJunctionLaneLinkCount()
+{	return mJunctionLaneLinkVector.size();	}
+
+/**
+* Return the pointer to a junction lane link record at provided index
+* @param i Index to the junction lane link record that is returned
+* @return A pointer to JunctionLaneLink object
+*/
+JunctionLaneLink* JunctionConnection::GetJunctionLaneLink(unsigned int i)
+{	return &mJunctionLaneLinkVector.at(i);	}
+
+/**
+* Return the pointer to the last junction lane link record
+* @return A pointer to JunctionLaneLink object
+*/
+JunctionLaneLink* JunctionConnection::GetLastJunctionLaneLink()
+{	
+	if(mJunctionLaneLinkVector.size()>0)
+		return &mJunctionLaneLinkVector.at(mJunctionLaneLinkVector.size()-1);	
+	else
+		return NULL;
+}
+
+/**
+* Return the pointer to the last added junction lane link record (which might not be the one from the end of the vector)
+* @return A pointer to JunctionLaneLink object
+*/
+JunctionLaneLink* JunctionConnection::GetLastAddedJunctionLaneLink()
+{	
+	if(mLastAddedJunctionLaneLink<mJunctionLaneLinkVector.size())
+		return &mJunctionLaneLinkVector.at(mLastAddedJunctionLaneLink);
+	else
+		return NULL;
+}
+
+
+
+/**
+* Junction lane link class. Holds all the information for a lane link record
+*
+*
+*
+*
+*/
+
+/**
+* Constructor. Initializes the parameters
+* @param from ID of the incoming lane
+* @param to ID of the connecting lane
+*/
+JunctionLaneLink::JunctionLaneLink(int from, int to)
+{	mFrom=from; mTo=to;	}
+
+
+/**
+* Set the ID of the incoming lane
+*/
+void JunctionLaneLink::SetFrom (int from)
+{	mFrom=from;	}
+
+/**
+* Set the ID of the connecting lane
+*/
+void JunctionLaneLink::SetTo (int to)
+{	mTo=to;	}
+
+/**
+* Get the ID of the incoming lane
+*/
+int JunctionLaneLink::GetFrom()
+{	return mFrom;	}
+
+/**
+* Get the ID of the connecting lane
+*/
+int JunctionLaneLink::GetTo()
+{	return mTo;	}
+
+
+/**
+* Junction priority class. Holds all the information for a priority record
+*
+*
+*
+*
+*/
+
+/**
+* Constructor. Initializes the parameters
+* @param high ID of the connecting road with higher priority
+* @param low ID of the connecting road with lower priority
+*/
+JunctionPriorityRoad::JunctionPriorityRoad(string high, string low)
+{
+	mHigh=high;
+	mLow=low;
+}
+
+/**
+* Set the ID of the connecting road with higher priority
+*/
+void JunctionPriorityRoad::SetHigh (string high)
+{	mHigh=high;	}
+
+/**
+* Set the ID of the connecting road with lower priority
+*/
+void JunctionPriorityRoad::SetLow (string low)
+{	mLow=low;	}
+
+/**
+* Get the ID of the connecting road with higher priority
+*/
+string JunctionPriorityRoad::GetHigh()
+{	return mHigh;	}
+
+/**
+* Get the ID of the connecting road with lower priority
+*/
+string JunctionPriorityRoad::GetLow()
+{	return mLow;	}
+
+
+/**
+* Junction controller class. Holds all the information for a priority record
+*
+*
+*
+*
+*/
+
+/**
+* Constructor. Initializes the parameters
+* @param id ID of the controller to add
+* @param type Type of control
+*/
+JunctionController::JunctionController(string id, string type)
+{	mId=id; mType=type;	}
+
+/**
+* Set the ID of the controller to add
+*/
+void JunctionController::SetId (string id)
+{	mId=id;	}
+
+/**
+* Set the type of control
+*/
+void JunctionController::SetType (string type)
+{	mType=type;	}
+
+/**
+* Get the ID of the controller to add
+*/
+string JunctionController::GetId()
+{	return mId;	}
+
+/**
+* Get the type of control
+*/
+string JunctionController::GetType()
+{	return mType;	}

+ 470 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Junction.h

@@ -0,0 +1,470 @@
+#ifndef JUNCTION_H
+#define JUNCTION_H
+
+#include <string>
+#include <vector>
+using std::string;
+
+//Prototypes
+class Junction;
+class JunctionConnection;
+class JunctionLaneLink;
+class JunctionController;
+class JunctionPriorityRoad;
+
+/**
+ * Junction class. Holds all the junction information
+ *
+ *
+ *
+ *
+ */
+class Junction
+{
+private:
+	/**
+	 * Junction parameters
+	 */
+	std::string mName;
+	std::string mId;
+
+	/**
+	 * Vector based parameters of the junction
+	 */
+	std::vector<JunctionConnection> mJunctionConnectionVector;
+	std::vector<JunctionPriorityRoad> mJunctionPriorityVector;
+	std::vector<JunctionController> mJunctionControllerVector;
+
+public:
+
+	/**
+	 * Indices of the last added records
+	 */
+	unsigned int mLastAddedJunctionConnection;
+	unsigned int mLastAddedJunctionPriority;
+	unsigned int mLastAddedJunctionController;
+
+	/**
+	 * Constructor. Sets basic junction parameters
+	 * @param name Name of the junction
+	 * @param id Unique ID of the junction
+	 */
+	Junction(string name, string id);
+
+	/**
+	 * Sets the name parameter
+	 */
+	void SetName(string name);
+	/**
+	 * Sets the ID parameter
+	 */
+	void SetId(string id);
+
+	/**
+	 * Adds a junction connection to the junction
+	 * @param id ID within the junction
+	 * @param incomingRoad ID of the incoming road
+	 * @param connectingRoad ID of the connecting path
+	 * @param contactPoint Contact point on the connecting road (start or end)
+	 */
+	unsigned int AddJunctionConnection(string id,	string incomingRoad, string connectingRoad, string contactPoint);
+
+	/**
+	 * Adds a priority parameter to the junction
+	 * @param high ID of the connecting road with higher priority
+	 * @param low ID of the connecting road with lower priority
+	 */
+	unsigned int AddJunctionPriority(string high, string low);
+
+	/**
+	 * Adds a controller to the junction
+	 * @param id ID of the controller to add
+	 * @param type Type of control
+	 */
+	unsigned int AddJunctionController(string id, string type);
+
+	/**
+	 * Clone the connection record
+	 * @param index Index of the record to clone
+	 */
+	unsigned int CloneJunctionConnection(unsigned int index);
+	unsigned int CloneJunctionPriority(unsigned int index);
+	unsigned int CloneJunctionController(unsigned int index);
+
+
+	void DeleteJunctionConnection(unsigned int index);
+	void DeleteJunctionPriority(unsigned int index);
+	void DeleteJunctionController(unsigned int index);
+
+	/**
+	 * Return the name of the junction
+	 */
+	string GetName();
+
+	/**
+	 * Return the id of the junction
+	 */
+	string GetId();
+
+	/**
+	 * Return the vector that stores junction connections
+	 * @return A pointer to std::vector of JunctionConnection type that stores junction connections
+	 */
+	std::vector<JunctionConnection>* GetJunctionConnectionVector ();
+
+	/**
+	 * Return the number of junction connections
+	 * @return An unsigned int that stores the number of junction connections
+	 */
+	unsigned int GetJunctionConnectionCount();
+
+	/**
+	 * Return the pointer to a junction connection at provided index
+	 * @param i Index to the junction connection that is returned
+	 * @return A pointer to JunctionConnection object
+	 */
+	JunctionConnection* GetJunctionConnection(unsigned int i);
+
+	/**
+	 * Return the pointer to the last junction connection
+	 * @return A pointer to JunctionConnection object
+	 */
+    JunctionConnection* GetLastJunctionConnection();
+
+	/**
+	 * Return the pointer to the last added junction connection (which might not be the one from the end of the vector)
+	 * @return A pointer to JunctionConnection object
+	 */
+    JunctionConnection* GetLastAddedJunctionConnection();
+	
+	/**
+	 * Return the vector that stores junction priority records
+	 * @return A pointer to std::vector of JunctionPriorityRoad type that stores junction priority records
+	 */
+	std::vector<JunctionPriorityRoad>* GetJunctionPriorityVector();
+
+	/**
+	 * Return the number of junction priority records
+	 * @return An unsigned int that stores the number of junction priority records
+	 */
+	unsigned int GetJunctionPriorityCount();
+
+	/**
+	 * Return the pointer to a junction priority record at provided index
+	 * @param i Index to the junction priority record that is returned
+	 * @return A pointer to JunctionPriorityRoad object
+	 */
+	JunctionPriorityRoad* GetJunctionPriority(unsigned int i);
+
+	/**
+	 * Return the pointer to the last junction priority record
+	 * @return A pointer to JunctionPriorityRoad object
+	 */
+    JunctionPriorityRoad* GetLastJunctionPriority();
+
+	
+	/**
+	 * Return the pointer to the last added junction priority record (which might not be the one from the end of the vector)
+	 * @return A pointer to JunctionPriorityRoad object
+	 */
+    JunctionPriorityRoad* GetLastAddedJunctionPriority();
+
+	/**
+	 * Return the vector that stores junction controller records
+	 * @return A pointer to std::vector of JunctionController type that stores junction controller records
+	 */
+	std::vector<JunctionController>* GetJunctionControllerVector();
+
+	/**
+	 * Return the number of junction controller records
+	 * @return An unsigned int that stores the number of junction controller records
+	 */
+	unsigned int  GetJunctionControllerCount();
+
+	/**
+	 * Return the pointer to a junction controller record at provided index
+	 * @param i Index to the junction controller record that is returned
+	 * @return A pointer to JunctionController object
+	 */
+	JunctionController* GetJunctionController(unsigned int i);
+
+	/**
+	 * Return the pointer to the last junction controller record
+	 * @return A pointer to JunctionController object
+	 */
+    JunctionController* GetLastJunctionController();
+
+	/**
+	 * Return the pointer to the last added junction controller record (which might not be the one from the end of the vector)
+	 * @return A pointer to JunctionController object
+	 */
+    JunctionController* GetLastAddedJunctionController();
+
+};
+
+
+/**
+ * Junction connection class. Holds all the information for a connection record
+ *
+ *
+ *
+ *
+ */
+class JunctionConnection
+{
+private:
+	/**
+	 * Connection parameters
+	 */
+	string mId;
+	string mIncomingRoad;
+	string mConnectingRoad;
+	string mContactPoint;	//Possible values: start / end
+
+	/**
+	 * Lane linkage parameters vector
+	 */
+	std::vector<JunctionLaneLink> mJunctionLaneLinkVector;
+public:
+	
+	unsigned int mLastAddedJunctionLaneLink;
+
+	/**
+	 * Constructor. Sets basic junction connection parameters
+	 * @param id ID within the junction
+	 * @param incomingRoad ID of the incoming road
+	 * @param connectingRoad ID of the connecting path
+	 * @param contactPoint Contact point on the connecting road (start / end)
+	 */
+	JunctionConnection(	string id, string incomingRoad, string connectingRoad, string contactPoint);
+
+	/**
+	 * Set the ID parameter
+	 */
+	void SetId(string id);
+
+	/**
+	 * Set the ID of the incoming road 
+	 */
+	void SetIncomingRoad(string incomingRoad);
+
+	/**
+	 * Set the ID of the connecting path
+	 */
+	void SetConnectingRoad(string connectingRoad);
+
+	/**
+	 * Set the contact point parameter
+	 * @param contactPoint Contact point of the connecting road. Can be either start or end
+	 */
+	void SetContactPoint(string contactPoint);
+
+	/**
+	 * Add a lane link record
+	 * @param from ID of the incoming lane
+	 * @param to ID of the connecting lane
+	 */
+	unsigned int AddJunctionLaneLink(int from, int to);
+
+	//clone elements
+	unsigned int CloneJunctionLaneLink(unsigned int index);
+
+	/**
+	 * Delete the lane link parameter at the provided index
+	 */
+	void DeleteJunctionLaneLink(unsigned int index);
+
+	/**
+	 * Get the ID parameter
+	 */
+	string GetId();
+
+	/**
+	 * Get the ID fo the incoming road
+	 */
+	string GetIncomingRoad();
+	
+	/**
+	 * Get the ID of the connecting road
+	 */
+	string GetConnectingRoad();
+	
+	/**
+	 * Get the contact point parameter
+	 */
+	string GetContactPoint();
+
+	/**
+	 * Return the vector that stores junction lane link records
+	 * @return A pointer to std::vector of JunctionLaneLink type that stores junction lane link records
+	 */
+	std::vector<JunctionLaneLink>* GetJunctionLaneLinkVector();
+	
+	/**
+	 * Return the number of junction lane link records
+	 * @return An unsigned int that stores the number of junction lane link records
+	 */
+	unsigned int GetJunctionLaneLinkCount();
+
+	/**
+	 * Return the pointer to a junction lane link record at provided index
+	 * @param i Index to the junction lane link record that is returned
+	 * @return A pointer to JunctionLaneLink object
+	 */
+	JunctionLaneLink* GetJunctionLaneLink(unsigned int);
+
+	/**
+	 * Return the pointer to the last junction lane link record
+	 * @return A pointer to JunctionLaneLink object
+	 */
+	JunctionLaneLink* GetLastJunctionLaneLink();
+
+	/**
+	 * Return the pointer to the last added junction lane link record (which might not be the one from the end of the vector)
+	 * @return A pointer to JunctionLaneLink object
+	 */
+	JunctionLaneLink* GetLastAddedJunctionLaneLink();
+
+
+};
+
+/**
+ * Junction lane link class. Holds all the information for a lane link record
+ *
+ *
+ *
+ *
+ */
+class JunctionLaneLink
+{
+private:
+	/**
+	 * Record parameters
+	 */
+	int mFrom;
+	int mTo;
+
+public:
+	/**
+	 * Constructor. Initializes the parameters
+	 * @param from ID of the incoming lane
+	 * @param to ID of the connecting lane
+	 */
+	JunctionLaneLink(int from, int to);
+
+	/**
+	 * Set the ID of the incoming lane
+	 */
+	void SetFrom (int from);
+
+	/**
+	 * Set the ID of the connecting lane
+	 */
+	void SetTo (int to);
+
+	/**
+	 * Get the ID of the incoming lane
+	 */
+	int GetFrom();
+
+	/**
+	 * Get the ID of the connecting lane
+	 */
+	int GetTo();
+};
+
+
+/**
+ * Junction priority class. Holds all the information for a priority record
+ *
+ *
+ *
+ *
+ */
+class JunctionPriorityRoad
+{
+private:
+	/**
+	 * Record parameters
+	 */
+	string mHigh;
+	string mLow;
+public:
+
+	/**
+	 * Constructor. Initializes the parameters
+	 * @param high ID of the connecting road with higher priority
+	 * @param low ID of the connecting road with lower priority
+	 */
+	JunctionPriorityRoad(string high, string low);
+
+	/**
+	 * Set the ID of the connecting road with higher priority
+	 */
+	void SetHigh (string high);
+
+	/**
+	 * Set the ID of the connecting road with lower priority
+	 */
+	void SetLow (string low);
+
+	/**
+	 * Get the ID of the connecting road with higher priority
+	 */
+	string GetHigh();
+
+	/**
+	 * Get the ID of the connecting road with lower priority
+	 */
+	string GetLow();
+
+};
+
+
+
+/**
+ * Junction controller class. Holds all the information for a priority record
+ *
+ *
+ *
+ *
+ */
+class JunctionController
+{
+private:
+	/**
+	 * Record parameters
+	 */
+	string mId;
+	string mType;
+public:
+	/**
+	 * Constructor. Initializes the parameters
+	 * @param id ID of the controller to add
+	 * @param type Type of control
+	 */
+	JunctionController(string id, string type);
+
+	/**
+	 * Set the ID of the controller to add
+	 */
+	void SetId (string id);
+
+	/**
+	 * Set the type of control
+	 */
+	void SetType (string type);
+
+	/**
+	 * Get the ID of the controller to add
+	 */
+	string GetId();
+
+	/**
+	 * Get the type of control
+	 */
+	string GetType();
+
+};
+
+#endif

+ 1509 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Lane.cpp

@@ -0,0 +1,1509 @@
+#include "Lane.h"
+
+
+
+
+/**
+* Lane section class. Holds all the lane section information
+*
+*
+*
+*
+*/
+
+/**
+* Constructor. Sets basic lane section parameters
+* @param s s-offset of the lane section
+*/
+LaneSection::LaneSection (double s)
+{	mS=s;	}
+
+/**
+* Add a lane to the lane section
+* @param side the side of the road to which the lane will be added
+* @param id ID of the lane
+* @param type Type of the lane (Section 6.5 of the OpenDRIVE specification) 
+* @param level Level parameter of the road
+* @param sort Defines if the lanes should be sorted when added. True by default
+*/
+unsigned int LaneSection::AddLane(short int side, int id, string type, bool level, bool sort)
+{	
+	unsigned int index=0;
+	//if lanes are sorted, add the lane to the correct side
+	if(sort)
+	{
+		if(side<0)
+		{
+			index=GetLaneCount();
+			mLaneVector.push_back(Lane(side,id,type,level));	
+			mLastAddedLane=index;
+		}
+		else if(side==0)
+		{
+			int sz=GetLaneCount();
+			if(sz>0)
+			{
+				for(int i=0; i<sz; i++)
+				{
+					if(mLaneVector[i].GetId()<0)
+					{
+						index=i;
+						mLaneVector.insert(mLaneVector.begin()+index, Lane(side,id,type,level));
+						mLastAddedLane=index;
+						break;
+					}
+				}
+			}
+			else
+			{
+				index=0;
+				mLaneVector.push_back(Lane(side,id,type,level));
+				mLastAddedLane=index;
+			}
+		}
+		else
+		{
+			index=0;
+			mLaneVector.insert(mLaneVector.begin(), Lane(side,id,type,level));
+			mLastAddedLane=index;
+		}
+
+		return index;
+	}
+	else
+	{
+		index=GetLaneCount();
+		mLaneVector.push_back(Lane(side,id,type,level));	
+		mLastAddedLane=index;
+		return index;
+	}	
+}
+
+/**
+* Delete the lane at the provided index
+*/
+void LaneSection::DeleteLane(unsigned int index)
+{
+	mLaneVector.erase(mLaneVector.begin()+index);
+}
+
+/**
+* Delete the outside left or right lane 
+*/
+void LaneSection::DeleteLeftLane()
+{
+	mLaneVector.erase(mLaneVector.begin());
+}
+void LaneSection::DeleteRigthLane()
+{
+	mLaneVector.pop_back();
+}
+
+/**
+* Get the last lane
+* @return A pointer to Lane object
+*/
+Lane* LaneSection::GetLastLane()
+{
+	if (mLaneVector.size()>0)
+		return &mLaneVector.at(mLaneVector.size()-1);
+	else
+		return NULL;
+}
+
+/**
+* Get the last added lane (which might not be the one from the end of the vector)
+* @return A pointer to Lane object
+*/
+Lane* LaneSection::GetLastAddedLane()
+{
+	if(mLastAddedLane<mLaneVector.size())
+		return &mLaneVector.at(mLastAddedLane);
+	else
+		return NULL;
+}
+
+/**
+* Get the last left lane
+* @return A pointer to Lane object
+*/
+Lane* LaneSection::GetLastLeftLane()
+{
+	if(mLaneVector.size()>0)
+	{
+		if(mLaneVector.at(0).GetSide()>0)
+			return &mLaneVector.at(0);
+		else
+			return NULL;
+	}
+	else
+		return NULL;
+}
+
+/**
+* Get the last center lane
+* @return A pointer to Lane object
+*/
+Lane* LaneSection::GetLastCenterLane()
+{
+	int sz=GetLaneCount();
+	for(int i=0; i<sz; i++)
+	{
+		if(mLaneVector[i].GetSide()==0)
+		{
+			return &mLaneVector.at(i);
+		}
+	}
+	return NULL;
+}
+
+/**
+* Get the last right lane
+* @return A pointer to Lane object
+*/
+Lane* LaneSection::GetLastRightLane()
+{
+	if(mLaneVector.size()>0)
+	{
+		int indexLast=mLaneVector.size()-1;
+		if(mLaneVector.at(indexLast).GetSide()<0)
+			return &mLaneVector.at(indexLast);
+		else
+			return NULL;
+	}
+	else return NULL;
+}
+/**
+* Get the lane vector
+* @return A pointer to a vector of type Lane
+*/
+vector<Lane>* LaneSection::GetLaneVector()
+{
+	return &mLaneVector;
+}
+
+/**
+* Get the lane by providing its index
+* @param i Index of the lane to be returned
+* @return A pointer to Lane object
+*/
+Lane* LaneSection::GetLane(unsigned int i)
+{
+	if ((mLaneVector.size()>0)&&(i<mLaneVector.size()))
+		return &mLaneVector.at(i);
+	else
+		return NULL;
+}
+
+/**
+* Get the lane number
+* @return Unsigned int with that stores the number of lanes
+*/
+unsigned int LaneSection::GetLaneCount()
+{
+	return mLaneVector.size();
+}
+
+/**
+* Get the lane section s-offset
+*/
+double LaneSection::GetS()
+{
+	return mS;
+}
+
+/**
+* Get the lane section final s-offset which is the s-offset of the last record of the lane section
+*/
+double LaneSection::GetS2()
+{
+	double lHighestS=0;
+
+	int sz=GetLaneCount();
+	for(int i=0; i<sz; i++)
+	{
+		Lane *lLane = GetLane(i);
+
+		//width
+		LaneWidth *lWidth = lLane->GetLaneWidth(lLane->GetLaneWidthCount()-1);
+		if(lWidth!=NULL) 
+		{
+			if(lWidth->GetS()>lHighestS) lHighestS=lWidth->GetS();
+		}
+
+		//road mark
+		LaneRoadMark *lRoadMark = lLane->GetLaneRoadMark(lLane->GetLaneRoadMarkCount()-1);
+		if(lRoadMark!=NULL) 
+		{
+			if(lRoadMark->GetS()>lHighestS) lHighestS=lRoadMark->GetS();
+		}
+
+		//material
+		LaneMaterial *lMaterial = lLane->GetLaneMaterial(lLane->GetLaneMaterialCount()-1);
+		if(lMaterial!=NULL) 
+		{
+			if(lMaterial->GetS()>lHighestS) lHighestS=lMaterial->GetS();
+		}
+
+		//visibility
+		LaneVisibility *lVisibility = lLane->GetLaneVisibility(lLane->GetLaneVisibilityCount()-1);
+		if(lVisibility!=NULL) 
+		{
+			if(lVisibility->GetS()>lHighestS) lHighestS=lVisibility->GetS();
+		}
+
+		//speed
+		LaneSpeed *lSpeed = lLane->GetLaneSpeed(lLane->GetLaneSpeedCount()-1);
+		if(lSpeed!=NULL) 
+		{
+			if(lSpeed->GetS()>lHighestS) lHighestS=lSpeed->GetS();
+		}
+
+		//access
+		LaneAccess *lAccess = lLane->GetLaneAccess(lLane->GetLaneAccessCount()-1);
+		if(lAccess!=NULL) 
+		{
+			if(lAccess->GetS()>lHighestS) lHighestS=lAccess->GetS();
+		}
+
+		//height
+		LaneHeight *lHeight = lLane->GetLaneHeight(lLane->GetLaneHeightCount()-1);
+		if(lHeight!=NULL) 
+		{
+			if(lHeight->GetS()>lHighestS) lHighestS=lHeight->GetS();
+		}
+	}
+
+	return mS+lHighestS;
+
+}
+
+/**
+* Set the lane section s-offset
+*/
+void LaneSection::SetS(double value)
+{
+	mS=value;
+}
+
+
+/**
+* Check if the tested s-offset is inside the lane section interval
+* @param A double s-offset value that has to be checked
+* @return Return true if the s-offset value belongs to current lane section, false otherwise
+*/
+bool LaneSection::CheckInterval(double s_check)
+{
+	if (s_check>=mS)
+		return true;
+	else 
+		return false;
+}
+
+/**
+* Return the lane-0 index in the lanes vector
+* @return An unsigned int value with the index
+*/
+unsigned int LaneSection::GetZeroLaneIndex()
+{
+	for (unsigned int i=0; i<GetLaneCount(); i++)
+	{
+		if(mLaneVector.at(i).GetId()==0)
+			return i;
+	}
+	return 0;
+}
+
+/**
+* Return the number of left lanes
+* @return An unsigned int value with the number of left lanes
+*/
+unsigned int LaneSection::GetLeftLaneCount()
+{
+	unsigned int count=0;
+	for (unsigned int i=0;i<GetLaneCount();i++)
+	{
+		if(mLaneVector.at(i).GetSide()==1)
+			count++;
+	}
+	return count;
+}
+
+/**
+* Return the number of central lanes
+* @return An unsigned int value with the number of central lanes
+*/
+unsigned int LaneSection::GetCenterLaneCount()
+{
+	unsigned int count=0;
+	for(unsigned int i=0; i<GetLaneCount(); i++)
+	{
+		if(mLaneVector[i].GetSide()==0)
+		{
+			count++;
+		}
+	}
+	return count;
+}
+
+/**
+* Return the number of right lanes
+* @return An unsigned int value with the number of right lanes
+*/
+unsigned int LaneSection::GetRightLaneCount()
+{
+	unsigned int count=0;
+	for (unsigned int i=0;i<GetLaneCount();i++)
+	{
+		if(mLaneVector.at(i).GetSide()==-1)
+			count++;
+	}
+	return count;
+}
+
+/**
+* Fill a special structure with all the lane / lane section data that is sampled at a provided s-offset position along the road
+* This data is used later to fill the geometry arrays
+* @param s_chek s-offset along the road at which to sample the lane section
+* @param laneSectionSample The structure that has to be filled with the sampled data
+* @return Returns true if the operation was successful. 
+*/
+bool LaneSection::FillLaneSectionSample(double s_check, LaneSectionSample& laneSectionSample)
+{
+	//clear and initialize variables
+	laneSectionSample.ClearVectors();
+	double width=0;
+	int leftMax=0;
+	int rightMax=GetLaneCount()-1;
+
+	s_check-=GetS();
+
+	bool level;
+	string type;
+	LaneHeight height; 
+	LaneRoadMark roadMark;
+	//Fill in left width vector
+	//if there are left lanes
+	if (GetLeftLaneCount()>0)
+	{	
+		//go through all of them
+		for (int i=GetZeroLaneIndex(); i>=leftMax;i--)
+		{	
+			type=GetLane(i)->GetType();
+			level=GetLane(i)->GetLevel();
+			height=GetLane(i)->GetHeightValue(s_check);
+			roadMark=GetLane(i)->GetRoadMarkValue(s_check);
+			//and accumulate the width
+			width=GetLane(i)->GetWidthValue(s_check);
+
+			laneSectionSample.AddLeftRecord(type, width, height, roadMark, level);
+		}
+	}
+
+	//same for the right side of the road
+	if (GetRightLaneCount()>0)
+	{	
+		//go through all of them
+		for (int i=GetZeroLaneIndex(); i<=rightMax;i++)
+		{	
+			type=GetLane(i)->GetType();
+			level=GetLane(i)->GetLevel();
+			height=GetLane(i)->GetHeightValue(s_check);
+			roadMark=GetLane(i)->GetRoadMarkValue(s_check);
+			//and accumulate the width
+			width=GetLane(i)->GetWidthValue(s_check);
+
+			laneSectionSample.AddRightRecord(type, width, height, roadMark, level);	
+		}
+	}
+	return true;
+}
+
+/**
+* Destructor. Delete all the members of the vectors: mLeft, mCenter, mRight
+*/
+LaneSection::~LaneSection()
+{
+	// DELETING LANES
+	mLaneVector.clear();
+}
+
+
+/**
+* Lane Section Sample. Holds all the lane information at a certain S value including lane widths, levels, 
+* heights, etc
+*
+*
+*
+*
+*/ 
+
+LaneSectionSample::LaneSectionSample()
+{}
+
+/*
+* Add various elements to the structure. Depending on the the value to be added, various input parameters are used.
+* The methods are divided into left and right for left and right sides of the road.
+*/
+void LaneSectionSample::AddLeftType(string type)
+{	mLeftTypeVector.push_back(type);	}
+void LaneSectionSample::AddLeftWidth(double width)
+{	mLeftWidthVector.push_back(width);	}
+void LaneSectionSample::AddLeftHeight(LaneHeight height)
+{	mLeftHeightVector.push_back(height);	}
+void LaneSectionSample::AddLeftRoadMark(LaneRoadMark roadMark)
+{	mLeftRoadMarkVector.push_back(roadMark);	}
+void LaneSectionSample::AddLeftLevel(bool level)
+{	mLeftLevelVector.push_back(level);	}
+
+void LaneSectionSample::AddRightType(string type)
+{	mRightTypeVector.push_back(type);	}
+void LaneSectionSample::AddRightWidth(double width)
+{	mRightWidthVector.push_back(width);	}
+void LaneSectionSample::AddRightHeight(LaneHeight height)
+{	mRightHeightVector.push_back(height);	}
+void LaneSectionSample::AddRightRoadMark(LaneRoadMark roadMark)
+{	mRightRoadMarkVector.push_back(roadMark);	}
+void LaneSectionSample::AddRightLevel(bool level)
+{	mRightLevelVector.push_back(level);	}
+
+void LaneSectionSample::AddLeftRecord(string type, double width, LaneHeight height, LaneRoadMark roadMark, bool level)
+{
+	AddLeftType(type);
+	AddLeftWidth(width);
+	AddLeftHeight(height);
+	AddLeftRoadMark(roadMark);
+	AddLeftLevel(level);
+}
+void LaneSectionSample::AddRightRecord(string type, double width, LaneHeight height, LaneRoadMark roadMark, bool level)
+{
+	AddRightType(type);
+	AddRightWidth(width);
+	AddRightHeight(height);
+	AddRightRoadMark(roadMark);
+	AddRightLevel(level);
+}
+
+/*
+* Get various elements of the structure. The methods return type depends on the elements that are returned.
+* The methods are divided into left and right for left and right sides of the road.
+*/
+string LaneSectionSample::GetLeftType(unsigned int i)
+{	return mLeftTypeVector.at(i);	}
+double LaneSectionSample::GetLeftWidth(unsigned int i)
+{	return mLeftWidthVector.at(i);	}
+LaneHeight LaneSectionSample::GetLeftHeight(unsigned int i)
+{	return mLeftHeightVector.at(i);	}
+LaneRoadMark LaneSectionSample::GetLeftRoadMark(unsigned int i)
+{	return mLeftRoadMarkVector.at(i);	}
+bool LaneSectionSample::GetLeftLevel(unsigned int i)
+{	return mLeftLevelVector.at(i);	}
+
+string LaneSectionSample::GetRightType(unsigned int i)
+{	return mRightTypeVector.at(i);	}
+double LaneSectionSample::GetRightWidth(unsigned int i)
+{	return mRightWidthVector.at(i);	}
+LaneHeight LaneSectionSample::GetRightHeight(unsigned int i)
+{	return mRightHeightVector.at(i);	}
+LaneRoadMark LaneSectionSample::GetRightRoadMark(unsigned int i)
+{	return mRightRoadMarkVector.at(i);	}
+bool LaneSectionSample::GetRightLevel(unsigned int i)
+{	return mRightLevelVector.at(i);	}
+
+
+/*
+* Get the number of elements in the vectors
+*/
+unsigned int LaneSectionSample::GetLeftVectorsSize()
+{	return mLeftWidthVector.size();	}
+unsigned int LaneSectionSample::GetRightVectorsSize()
+{	return mRightWidthVector.size();	}
+
+
+/*
+* Get the various record vectors. The vector type depends on the record
+* The methods are divided into left and right for left and right sides of the road.
+*/
+vector<string>* LaneSectionSample::GetLeftTypeVector()
+{	return &mLeftTypeVector;	}
+vector<double>* LaneSectionSample::GetLeftWidthVector()
+{	return &mLeftWidthVector;	}
+vector<LaneHeight>* LaneSectionSample::GetLeftHeigthVector()
+{	return &mLeftHeightVector;	}
+vector<LaneRoadMark>* LaneSectionSample::GetLeftRoadMarkVector()
+{	return &mLeftRoadMarkVector;	}
+vector<bool>* LaneSectionSample::GetLeftLevelVector()
+{	return &mLeftLevelVector;	}
+
+vector<string>* LaneSectionSample::GetRightTypeVector()
+{	return &mRightTypeVector;	}
+vector<double>* LaneSectionSample::GetRightWidthVector()
+{	return &mRightWidthVector;	}
+vector<LaneHeight>* LaneSectionSample::GetRightHeigthVector()
+{	return &mRightHeightVector;	}
+vector<LaneRoadMark>* LaneSectionSample::GetRightRoadMarkVector()
+{	return &mRightRoadMarkVector;	}
+vector<bool>* LaneSectionSample::GetRightLevelVector()
+{	return &mRightLevelVector;	}
+
+/*
+* Clear the vectors
+*/
+void LaneSectionSample::ClearVectors()
+{
+	mLeftTypeVector.clear();
+	mLeftWidthVector.clear();
+	mLeftHeightVector.clear();
+	mLeftRoadMarkVector.clear();
+	mLeftLevelVector.clear();
+
+	mRightTypeVector.clear();
+	mRightWidthVector.clear();
+	mRightHeightVector.clear();
+	mRightRoadMarkVector.clear();
+	mRightLevelVector.clear();
+}
+
+/**
+* Lane class. Holds all the record data that describes a lane
+*
+*
+*
+*
+*
+*/
+
+/**
+*	Constructor
+*/
+Lane::Lane(short int side, int id, string type, bool level)
+{	mSide=side; mId=id; mType=type; mLevel=level;	mPredecessorExists=false; mSuccessorExists=false;	}
+
+/**
+*	Various set methods.
+*/
+void Lane::SetSide(short int side)
+{
+	mSide=side;
+}
+void Lane::SetId(int id)
+{
+	mId=id;
+}
+void Lane::SetType(string type)
+{
+	mType=type;
+}
+void Lane::SetLevel(bool level)
+{
+	mLevel=level;
+}
+//-------------
+void Lane::SetPredecessor(int predecessor)
+{	mPredecessor=predecessor; mPredecessorExists=true;	}
+//-------------
+void Lane::SetSuccessor(int successor)
+{	mSuccessor=successor;	mSuccessorExists=true;	}
+
+/**
+*	Remove lane linkage
+*/
+void Lane::RemovePredecessor()
+{	mPredecessor=0;	mPredecessorExists=false;	}
+
+void Lane::RemoveSuccessor()
+{	mSuccessor=0;	mSuccessorExists=false;		}
+
+
+/**
+ * Methods used to add child records to the respective vectors
+ */
+unsigned int Lane::AddWidthRecord(double s, double a, double b, double c, double d)
+{	
+	// Gets the index where the record should be inserted in the vector
+	unsigned int index = CheckWidthInterval(s)+1;
+	// If larger than the record count - push to the back
+	if(index>=GetLaneWidthCount()) mLaneWidth.push_back(LaneWidth(s,a,b,c,d));	
+	// else insert in the middle
+	else mLaneWidth.insert(mLaneWidth.begin()+index, LaneWidth(s,a,b,c,d));
+	// Save the last added record index
+	mLastAddedLaneWidth=index;
+	return index;
+}
+//-------------
+unsigned int Lane::AddRoadMarkRecord(double sOffset, string type, string weight, string color, double width, string laneChange)
+{	
+	// Check the first method in the group for details
+
+	unsigned int index = CheckRoadMarkInterval(sOffset)+1;
+	if(index>=GetLaneRoadMarkCount()) mLaneRoadMark.push_back(LaneRoadMark(sOffset, type, weight, color, width, laneChange));	
+	else mLaneRoadMark.insert(mLaneRoadMark.begin()+index, LaneRoadMark(sOffset, type, weight, color, width, laneChange));
+	mLastAddedLaneRoadMark=index;
+	return index;
+}
+//-------------
+unsigned int Lane::AddMaterialRecord(double sOffset, string surface, double friction, double roughness)
+{	
+	// Check the first method in the group for details
+
+	unsigned int index = CheckMaterialInterval(sOffset)+1;
+	if(index>=GetLaneMaterialCount()) mLaneMaterial.push_back(LaneMaterial(sOffset,surface,friction,roughness));	
+	else mLaneMaterial.insert(mLaneMaterial.begin()+index, LaneMaterial(sOffset,surface,friction,roughness));
+	mLastAddedLaneMaterial=index;
+	return index;
+}
+//-------------
+unsigned int Lane::AddVisibilityRecord(double sOffset, double forward, double back, double left, double right)
+{	
+	// Check the first method in the group for details
+
+	unsigned int index = CheckVisibilityInterval(sOffset)+1;
+	if(index>=GetLaneVisibilityCount()) mLaneVisibility.push_back(LaneVisibility(sOffset,forward,back,left,right));	
+	else mLaneVisibility.insert(mLaneVisibility.begin()+index, LaneVisibility(sOffset,forward,back,left,right));
+	mLastAddedLaneVisibility=index;
+	return index;
+}
+//-------------
+unsigned int Lane::AddSpeedRecord(double sOffset, double max)
+{	
+	// Check the first method in the group for details
+
+	unsigned int index = CheckSpeedInterval(sOffset)+1;
+	if(index>=GetLaneSpeedCount()) mLaneSpeed.push_back(LaneSpeed(sOffset,max));	
+	else mLaneSpeed.insert(mLaneSpeed.begin()+index, LaneSpeed(sOffset,max));
+	mLastAddedLaneSpeed=index;
+	return index;
+}
+//-------------
+unsigned int Lane::AddAccessRecord(double sOffset, string restriction)
+{	
+	// Check the first method in the group for details
+
+	unsigned int index = CheckAccessInterval(sOffset)+1;
+	if(index>=GetLaneAccessCount()) mLaneAccess.push_back(LaneAccess(sOffset,restriction));	
+	else mLaneAccess.insert(mLaneAccess.begin()+index, LaneAccess(sOffset,restriction));
+	mLastAddedLaneAccess=index;
+	return index;
+}
+//-------------
+unsigned int Lane::AddHeightRecord(double sOffset, double inner, double outer)
+{	
+	// Check the first method in the group for details
+
+	unsigned int index = CheckHeightInterval(sOffset)+1;
+	if(index>=GetLaneHeightCount()) mLaneHeight.push_back(LaneHeight(sOffset,inner,outer));	
+	else mLaneHeight.insert(mLaneHeight.begin()+index, LaneHeight(sOffset,inner,outer));
+	mLastAddedLaneHeight=index;
+	return index;
+}
+
+/**
+ * Methods used to clone child records in the respective vectors
+ */
+unsigned int Lane::CloneLaneWidth(unsigned int index)
+{
+	// Clone the object and insert it in the middle of the vector
+	if(index<mLaneWidth.size()-1)
+		mLaneWidth.insert(mLaneWidth.begin()+index+1, mLaneWidth[index]);
+	// or just push it to the back
+	else if(index==mLaneWidth.size()-1)
+		mLaneWidth.push_back(mLaneWidth[index]);
+	// Save the last added record index
+	mLastAddedLaneWidth=index+1;
+	return mLastAddedLaneWidth;
+}
+unsigned int Lane::CloneLaneRoadMark(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mLaneRoadMark.size()-1)
+		mLaneRoadMark.insert(mLaneRoadMark.begin()+index+1, mLaneRoadMark[index]);
+	else if(index==mLaneRoadMark.size()-1)
+		mLaneRoadMark.push_back(mLaneRoadMark[index]);
+	mLastAddedLaneRoadMark=index+1;
+	return mLastAddedLaneRoadMark;
+}
+unsigned int Lane::CloneLaneMaterial(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mLaneMaterial.size()-1)
+		mLaneMaterial.insert(mLaneMaterial.begin()+index+1, mLaneMaterial[index]);
+	else if(index==mLaneMaterial.size()-1)
+		mLaneMaterial.push_back(mLaneMaterial[index]);
+	mLastAddedLaneMaterial=index+1;
+	return mLastAddedLaneMaterial;
+}
+unsigned int Lane::CloneLaneVisibility(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mLaneVisibility.size()-1)
+		mLaneVisibility.insert(mLaneVisibility.begin()+index+1, mLaneVisibility[index]);
+	else if(index==mLaneVisibility.size()-1)
+		mLaneVisibility.push_back(mLaneVisibility[index]);
+	mLastAddedLaneVisibility=index+1;
+	return mLastAddedLaneVisibility;
+}
+unsigned int Lane::CloneLaneSpeed(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mLaneSpeed.size()-1)
+		mLaneSpeed.insert(mLaneSpeed.begin()+index+1, mLaneSpeed[index]);
+	else if(index==mLaneSpeed.size()-1)
+		mLaneSpeed.push_back(mLaneSpeed[index]);
+	mLastAddedLaneSpeed=index+1;
+	return mLastAddedLaneSpeed;
+}
+unsigned int Lane::CloneLaneAccess(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mLaneAccess.size()-1)
+		mLaneAccess.insert(mLaneAccess.begin()+index+1, mLaneAccess[index]);
+	else if(index==mLaneAccess.size()-1)
+		mLaneAccess.push_back(mLaneAccess[index]);
+	mLastAddedLaneAccess=index+1;
+	return mLastAddedLaneAccess;
+}
+unsigned int Lane::CloneLaneHeight(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mLaneHeight.size()-1)
+		mLaneHeight.insert(mLaneHeight.begin()+index+1, mLaneHeight[index]);
+	else if(index==mLaneHeight.size()-1)
+		mLaneHeight.push_back(mLaneHeight[index]);
+	mLastAddedLaneHeight=index+1;
+	return mLastAddedLaneHeight;
+}
+
+/**
+ * Methods used to delete child records from the respective vectors
+ */
+void Lane::DeleteLaneWidth(unsigned int index)
+{
+	mLaneWidth.erase(mLaneWidth.begin()+index);
+}
+void Lane::DeleteLaneRoadMark(unsigned int index)
+{
+	mLaneRoadMark.erase(mLaneRoadMark.begin()+index);
+}
+void Lane::DeleteLaneMaterial(unsigned int index)
+{
+	mLaneMaterial.erase(mLaneMaterial.begin()+index);
+}
+void Lane::DeleteLaneVisibility(unsigned int index)
+{
+	mLaneVisibility.erase(mLaneVisibility.begin()+index);
+}
+void Lane::DeleteLaneSpeed(unsigned int index)
+{
+	mLaneSpeed.erase(mLaneSpeed.begin()+index);
+}
+void Lane::DeleteLaneAccess(unsigned int index)
+{
+	mLaneAccess.erase(mLaneAccess.begin()+index);
+}
+void Lane::DeleteLaneHeight(unsigned int index)
+{
+	mLaneHeight.erase(mLaneHeight.begin()+index);
+}
+
+
+/**
+*	Getters of the lane parameters
+*/
+int Lane::GetSide()
+{
+	return mSide;
+}
+int Lane::GetId()
+{
+	return mId;
+}
+string Lane::GetType()
+{
+	return mType;
+}
+bool Lane::GetLevel()
+{
+	return mLevel;
+}
+
+/**
+*	Check if linkage information is provided
+*/
+bool Lane::IsPredecessorSet()
+{
+	return mPredecessorExists;
+}
+int Lane::GetPredecessor()
+{
+	return mPredecessor;
+}
+bool Lane::IsSuccessorSet()
+{
+	return mSuccessorExists;
+}
+int Lane::GetSuccessor()
+{
+	return mSuccessor;
+}
+
+
+/**
+*	Get pointers to the records vectors
+*/
+vector <LaneWidth> *Lane::GetLaneWidthVector()
+{	return &mLaneWidth;	}
+
+vector <LaneRoadMark> *Lane::GetLaneRoadMarkVector()
+{	return &mLaneRoadMark;	}
+
+vector <LaneMaterial> *Lane::GetLaneMaterialVector()
+{	return &mLaneMaterial;	}
+
+vector <LaneVisibility> *Lane::GetLaneVisibilityVector()
+{	return &mLaneVisibility;	}
+
+vector <LaneSpeed> *Lane::GetLaneSpeedVector()
+{	return &mLaneSpeed;	}
+
+vector <LaneAccess> *Lane::GetLaneAccessVector()
+{	return &mLaneAccess;	}
+
+vector <LaneHeight> *Lane::GetLaneHeightVector()
+{	return &mLaneHeight;	}
+
+
+/**
+*	Get the number of elements in a certain vector
+*/
+unsigned int Lane::GetLaneWidthCount()
+{	return mLaneWidth.size();	}
+
+unsigned int Lane::GetLaneRoadMarkCount()
+{	return mLaneRoadMark.size();	}
+
+unsigned int Lane::GetLaneMaterialCount()
+{	return mLaneMaterial.size();	}
+
+unsigned int Lane::GetLaneVisibilityCount()
+{	return mLaneVisibility.size();	}
+
+unsigned int Lane::GetLaneSpeedCount()
+{	return mLaneSpeed.size();	}
+
+unsigned int Lane::GetLaneAccessCount()
+{	return mLaneAccess.size();	}
+
+unsigned int Lane::GetLaneHeightCount()
+{	return mLaneHeight.size();	}
+
+/**
+*	Get the elements of a certain vectors at position i
+*/
+LaneWidth* Lane::GetLaneWidth(unsigned int i)
+{
+	if ((mLaneWidth.size()>0)&&(i<mLaneWidth.size()))
+		return &mLaneWidth.at(i);
+	else
+		return NULL;
+}
+
+LaneRoadMark* Lane::GetLaneRoadMark(unsigned int i)
+{
+	if ((mLaneRoadMark.size()>0)&&(i<mLaneRoadMark.size()))
+		return &mLaneRoadMark.at(i);
+	else
+		return NULL;
+}
+
+LaneMaterial* Lane::GetLaneMaterial(unsigned int i)
+{
+	if ((mLaneMaterial.size()>0)&&(i<mLaneMaterial.size()))
+		return &mLaneMaterial.at(i);
+	else
+		return NULL;
+}
+
+LaneVisibility* Lane::GetLaneVisibility(unsigned int i)
+{
+	if ((mLaneVisibility.size()>0)&&(i<mLaneVisibility.size()))
+		return &mLaneVisibility.at(i);
+	else
+		return NULL;
+}
+
+LaneSpeed* Lane::GetLaneSpeed(unsigned int i)
+{
+	if ((mLaneSpeed.size()>0)&&(i<mLaneSpeed.size()))
+		return &mLaneSpeed.at(i);
+	else
+		return NULL;
+}
+
+LaneAccess* Lane::GetLaneAccess(unsigned int i)
+{
+	if ((mLaneAccess.size()>0)&&(i<mLaneAccess.size()))
+		return &mLaneAccess.at(i);
+	else
+		return NULL;
+}
+
+LaneHeight* Lane::GetLaneHeight(unsigned int i)
+{
+	if ((mLaneHeight.size()>0)&&(i<mLaneHeight.size()))
+		return &mLaneHeight.at(i);
+	else
+		return NULL;
+}
+
+
+/**
+*	Get the last elements of a certain vectors
+*/
+LaneWidth* Lane::GetLastLaneWidth()
+{
+	if (mLaneWidth.size()>0)
+		return &mLaneWidth.at(mLaneWidth.size()-1);
+	else
+		return NULL;
+}
+LaneRoadMark* Lane::GetLastLaneRoadMark()
+{
+	if (mLaneRoadMark.size()>0)
+		return &mLaneRoadMark.at(mLaneRoadMark.size()-1);
+	else
+		return NULL;
+}
+LaneMaterial* Lane::GetLastLaneMaterial()
+{
+	if (mLaneMaterial.size()>0)
+		return &mLaneMaterial.at(mLaneMaterial.size()-1);
+	else
+		return NULL;
+}
+LaneVisibility* Lane::GetLastLaneVisibility()
+{
+	if (mLaneVisibility.size()>0)
+		return &mLaneVisibility.at(mLaneVisibility.size()-1);
+	else
+		return NULL;
+}
+LaneSpeed* Lane::GetLastLaneSpeed()
+{
+	if (mLaneSpeed.size()>0)
+		return &mLaneSpeed.at(mLaneSpeed.size()-1);
+	else
+		return NULL;
+}
+LaneAccess* Lane::GetLastLaneAccess()
+{
+	if (mLaneAccess.size()>0)
+		return &mLaneAccess.at(mLaneAccess.size()-1);
+	else
+		return NULL;
+}
+LaneHeight* Lane::GetLastLaneHeight()
+{
+	if (mLaneHeight.size()>0)
+		return &mLaneHeight.at(mLaneHeight.size()-1);
+	else
+		return NULL;
+}
+
+/**
+*	Get the last added elements of a certain vectors (their position might not be at the end of the vector)
+*/
+LaneWidth* Lane::GetLastAddedLaneWidth()
+{
+	if(mLastAddedLaneWidth<mLaneWidth.size())
+		return &mLaneWidth.at(mLastAddedLaneWidth);
+	else
+		return NULL;
+}
+LaneRoadMark* Lane::GetLastAddedLaneRoadMark()
+{
+	if(mLastAddedLaneRoadMark<mLaneRoadMark.size())
+		return &mLaneRoadMark.at(mLastAddedLaneRoadMark);
+	else
+		return NULL;
+}
+LaneMaterial* Lane::GetLastAddedLaneMaterial()
+{
+	if(mLastAddedLaneMaterial<mLaneMaterial.size())
+		return &mLaneMaterial.at(mLastAddedLaneMaterial);
+	else
+		return NULL;
+}
+LaneVisibility* Lane::GetLastAddedLaneVisibility()
+{
+	if(mLastAddedLaneVisibility<mLaneVisibility.size())
+		return &mLaneVisibility.at(mLastAddedLaneVisibility);
+	else
+		return NULL;
+}
+LaneSpeed* Lane::GetLastAddedLaneSpeed()
+{
+	if(mLastAddedLaneSpeed<mLaneSpeed.size())
+		return &mLaneSpeed.at(mLastAddedLaneSpeed);
+	else
+		return NULL;
+}
+LaneAccess* Lane::GetLastAddedLaneAccess()
+{
+	if(mLastAddedLaneAccess<mLaneAccess.size())
+		return &mLaneAccess.at(mLastAddedLaneAccess);
+	else
+		return NULL;
+}
+LaneHeight* Lane::GetLastAddedLaneHeight()
+{
+	if(mLastAddedLaneHeight<mLaneHeight.size())
+		return &mLaneHeight.at(mLastAddedLaneHeight);
+	else
+		return NULL;
+}
+
+/**
+*	Check the intervals and return the index of the records that applies to the provided s-offset
+*/
+int  Lane::CheckWidthInterval(double s_check)
+{
+
+	int res=-1;
+	//Go through all the width records
+	for (unsigned int i=0;i<mLaneWidth.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (s_check >= mLaneWidth.at(i).GetS())
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+int Lane::CheckRoadMarkInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the road mark records
+	for (unsigned int i=0;i<mLaneRoadMark.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (s_check >= mLaneRoadMark.at(i).GetS())
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+int Lane::CheckMaterialInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the material records
+	for (unsigned int i=0;i<mLaneMaterial.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (s_check >= mLaneMaterial.at(i).GetS())
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+int Lane::CheckVisibilityInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the visibility records
+	for (unsigned int i=0;i<mLaneVisibility.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (s_check >= mLaneVisibility.at(i).GetS())
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+int Lane::CheckSpeedInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the speed records
+	for (unsigned int i=0;i<mLaneSpeed.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (s_check >= mLaneSpeed.at(i).GetS())
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+int Lane::CheckAccessInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the access records
+	for (unsigned int i=0;i<mLaneAccess.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (s_check >= mLaneAccess.at(i).GetS())
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+int Lane::CheckHeightInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the height records
+	for (unsigned int i=0;i<mLaneHeight.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (s_check >= mLaneHeight.at(i).GetS())
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+
+/**
+*	Evaluate the record and return the width value
+*/
+double  Lane::GetWidthValue(double s_check)
+{
+	double retVal=0;
+	//find the record where s_check belongs
+	int index=CheckWidthInterval(s_check);
+	//If found, return the type
+	if (index>=0)
+		retVal= mLaneWidth.at(index).GetValue(s_check);
+	return retVal;
+}
+
+/**
+*	Evaluate the record and return the height object
+*/
+LaneHeight  Lane::GetHeightValue(double s_check)
+{
+	LaneHeight  retVal(0,0,0);
+	//find the record where s_check belongs
+	int index=CheckHeightInterval(s_check);
+	//If found, return the type
+	if (index>=0)
+	{
+		retVal.SetInner(mLaneHeight.at(index).GetInner());
+		retVal.SetOuter(mLaneHeight.at(index).GetOuter());
+	}
+	return retVal;
+}
+
+
+/**
+*	Evaluate the road marks records and return the road mark object corresponding to the provided s-offset
+*/
+LaneRoadMark Lane::GetRoadMarkValue(double s_check)
+{
+	LaneRoadMark returnRoadMark;
+	//find the record where s_check belongs
+	int index=CheckRoadMarkInterval(s_check);
+	//If found, return the params 
+	if (index>=0)
+	{
+		returnRoadMark.SetColor(mLaneRoadMark.at(index).GetColor());
+		returnRoadMark.SetLaneChange(mLaneRoadMark.at(index).GetLaneChange());
+		returnRoadMark.SetType(mLaneRoadMark.at(index).GetType());
+		returnRoadMark.SetWeight(mLaneRoadMark.at(index).GetWeight());
+		returnRoadMark.SetWidth(mLaneRoadMark.at(index).GetWidth());
+	}
+
+	return returnRoadMark;
+
+}
+
+/**
+* Destructor
+* Delete all the members of the vectors:
+* mLaneWidth, mRoadMark, mLaneMaterial, mLaneVisibility, mLaneSpeed, mLaneAccess, mLaneHeight
+*/
+Lane::~Lane()
+{
+	// DELETING LANE WIDTHS
+	mLaneWidth.clear();
+
+	// DELETING LANE ROAD MARKS
+	mLaneRoadMark.clear();
+
+	// DELETING LANE MATERIAL
+	mLaneMaterial.clear();
+
+	// DELETING LANE VISIBILITY
+	mLaneVisibility.clear();
+
+	// DELETING LANE SPEED
+	mLaneSpeed.clear();
+
+	// DELETING LANE ACCESS
+	mLaneAccess.clear();
+
+	// DELETING LANE HEIGHTS
+	mLaneHeight.clear();
+}
+
+/**
+* Lane width class. Holds all the data that describes a lane width
+*
+*
+*
+*
+*
+*/
+
+/**
+* Constructor
+* @param s s-offset of the record starting from the lane section s-offset
+* @ param a,b,c,d The 4 parameters of the polynomial
+*/
+LaneWidth::LaneWidth(double s, double a, double b, double c, double d):ThirdOrderPolynom (s,a,b,c,d)
+{}
+
+/**
+* Road mark class. Holds all the data that describes a road mark
+*
+*
+*
+*
+*
+*/
+
+/*
+* Constructors
+*/
+LaneRoadMark::LaneRoadMark()
+{	mSOffset=0, mType="none"; mWeight="standard"; mColor="standard"; mWidth=0.75; mLaneChange="both"; 	}
+//-------------
+LaneRoadMark::LaneRoadMark(double sOffset, string type, string weight, string color, double width, string laneChange)
+{	mSOffset=sOffset; mType=type; mWeight=weight; mColor=color; mWidth=width; mLaneChange=laneChange;	
+}
+//-------------
+LaneRoadMark::LaneRoadMark(double sOffset, string type, string weight, string color, double width)
+{	mSOffset=sOffset; mType=type; mWeight=weight; mColor=color; mWidth=width; mLaneChange="both"; }
+
+/*
+* Methods that set the parameters of the road mark
+*/
+void LaneRoadMark::SetS(double value)
+{	mSOffset = value;	}
+void LaneRoadMark::SetType(string type)
+{	mType=type;	}
+void LaneRoadMark::SetWeight(string weight)
+{	mWeight=weight;	}
+void LaneRoadMark::SetColor(string color)
+{	mColor=color;	}
+void LaneRoadMark::SetWidth(double value)
+{	mWidth=value;	}
+void LaneRoadMark::SetLaneChange(string laneChange)
+{	mLaneChange=laneChange;	}
+
+
+/*
+* Methods that return the parameters of the road mark
+*/
+double LaneRoadMark::GetS()
+{	return mSOffset;	}
+string LaneRoadMark::GetType()
+{	return mType;	}
+string LaneRoadMark::GetWeight()
+{	return mWeight;	}
+string LaneRoadMark::GetColor()
+{	return mColor;	}
+double LaneRoadMark::GetWidth()
+{	return mWidth;	}
+string LaneRoadMark::GetLaneChange()
+{	return mLaneChange;	}
+
+/**
+* Lane material class. Contains all the data that describes a lane material
+*
+*
+*
+*
+*
+*/
+
+/*
+* Constructor
+*/
+LaneMaterial::LaneMaterial (double sOffset, string surface, double friction, double roughness)
+{	mSOffset=sOffset; mSurface=surface; mFriction=friction; mRoughness=roughness;	}
+
+/*
+* Methods that return the parameters of the lane material
+*/
+double LaneMaterial::GetS()
+{	return mSOffset;	}
+string LaneMaterial::GetSurface()
+{	return mSurface;	}
+double LaneMaterial::GetFriction()
+{	return mFriction;	}
+double LaneMaterial::GetRoughness()
+{	return mRoughness;	}
+
+/*
+* Methods that set the parameters of the lane material
+*/
+void LaneMaterial::SetS(double value)
+{	mSOffset=value;	}
+void LaneMaterial::SetSurface(string surface)
+{	mSurface=surface;	}
+void LaneMaterial::SetFriction(double value)
+{	mFriction=value;	}
+void LaneMaterial::SetRoughness(double value)
+{	mRoughness=value;	}
+
+
+/**
+* Lane visibility class. Contains all the data that describes lane visibility record
+*
+*
+*
+*
+*
+*/
+
+/*
+* Constructor
+*/
+LaneVisibility::LaneVisibility(double sOffset, double forward, double back, double left, double right)
+{	mSOffset=sOffset; mForward=forward; mBack=back; mLeft=left; mRight=right;	}
+
+/*
+* Methods that return the parameters of the lane visibility
+*/
+double LaneVisibility::GetS()
+{	return mSOffset;	}
+double LaneVisibility::GetForward()
+{	return mForward;	}
+double LaneVisibility::GetBack()
+{	return mBack;	}
+double LaneVisibility::GetLeft()
+{	return mLeft;	}
+double LaneVisibility::GetRight()
+{	return mRight;	}
+
+/*
+* Methods that set the parameters of the lane visibility
+*/
+void LaneVisibility::SetS(double value)
+{	mSOffset=value;	}
+void LaneVisibility::SetForward(double value)
+{	mForward=value;	}
+void LaneVisibility::SetBack(double value)
+{	mBack=value;	}
+void LaneVisibility::SetLeft(double value)
+{	mLeft=value;	}
+void LaneVisibility::SetRight(double value)
+{	mRight=value;	}
+
+
+/**
+* Lane speed class. Contains all the data that describes lane speed record
+*
+*
+*
+*
+*
+*/
+
+/*
+* Constructor
+*/
+LaneSpeed::LaneSpeed (double sOffset, double max)
+{	mSOffset=sOffset; mMax=max;}
+
+/*
+* Methods that return the parameters of the lane speed
+*/
+double LaneSpeed::GetS()
+{	return mSOffset;	}
+double LaneSpeed::GetMax()
+{	return mMax;	}
+
+/*
+* Methods that set the parameters of the lane speed
+*/
+void LaneSpeed::SetS(double value)
+{	mSOffset=value;	}
+void LaneSpeed::SetMax(double value)
+{	mMax=value;	}
+
+
+/**
+* Lane access class. Contains all the data that describes lane access record
+*
+*
+*
+*
+*
+*/
+/*
+* Constructor
+*/
+LaneAccess::LaneAccess (double sOffset, string restriction)
+{	mSOffset=sOffset; mRestriction = restriction;	}
+
+/*
+* Methods that return the parameters of the lane access
+*/
+double LaneAccess::GetS()
+{	return mSOffset;	}
+string LaneAccess::GetRestriction()
+{	return mRestriction;	}
+
+/*
+* Methods that set the parameters of the lane access
+*/
+void LaneAccess::SetS(double value)
+{	mSOffset=value;	}
+void LaneAccess::SetRestriction(string restriction)
+{	mRestriction=restriction;	}
+
+/**
+* Lane height class. Contains all the data that describes lane access record
+*
+*
+*
+*
+*
+*/
+/*
+* Constructors
+*/
+LaneHeight::LaneHeight()
+{mSOffset=0; mInner=0; mOuter=0;}
+LaneHeight::LaneHeight (double sOffset, double inner, double outer)
+{	mSOffset=sOffset; mInner=inner; mOuter=outer;	}
+
+/*
+* Methods that return the parameters of the lane height
+*/
+double LaneHeight::GetS()
+{	return mSOffset;	}
+double LaneHeight::GetInner()
+{	return mInner;	}
+double LaneHeight::GetOuter()
+{	return mOuter;	}
+
+/*
+* Methods that set the parameters of the lane height
+*/
+void LaneHeight::SetS(double value)
+{	mSOffset=value;	}
+void LaneHeight::SetInner(double value)
+{	mInner=value;	}
+void LaneHeight::SetOuter(double value)
+{	mOuter=value;	}

+ 773 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Lane.h

@@ -0,0 +1,773 @@
+#ifndef LANE_H
+#define LANE_H
+
+#include "Road.h"
+#include "OtherStructures.h"
+#include <vector>
+#include <string>
+
+
+//Prototypes
+class LaneSection;
+class LaneSectionSample;
+class Lane;
+class LaneWidth;
+class LaneRoadMark;
+class LaneMaterial;
+class LaneVisibility;
+class LaneSpeed;
+class LaneAccess;
+class LaneHeight;
+
+using std::vector;
+using std::string;
+
+/**
+* Lane section class. Holds all the lane section information
+*
+*
+*
+*
+*/
+class LaneSection
+{
+private:
+	/**
+	* Record parameters
+	*/
+	double mS;
+	vector<Lane> mLaneVector;
+
+	unsigned int mLastAddedLane;
+
+public:
+	/**
+	* Constructor. Sets basic lane section parameters
+	* @param s s-offset of the lane section
+	*/
+	LaneSection (double s);
+
+	/**
+	* Add a lane to the lane section
+	* @param side the side of the road to which the lane will be added
+	* @param id ID of the lane
+	* @param type Type of the lane (Section 6.5 of the OpenDRIVE specification) 
+	* @param level Level parameter of the road
+	* @param sort Defines if the lanes should be sorted when added. True by default
+	*/
+	unsigned int AddLane(short int side, int id, string type, bool level, bool sort=true);
+
+
+	/**
+	* Delete the lane at the provided index
+	*/
+	void DeleteLane(unsigned int index);
+
+	/**
+	* Delete the outside left or right lane 
+	*/
+	void DeleteLeftLane();
+	void DeleteRigthLane();
+
+	/**
+	* Get the last lane
+	* @return A pointer to Lane object
+	*/
+	Lane* GetLastLane();
+
+	/**
+	* Get the last added lane (which might not be the one from the end of the vector)
+	* @return A pointer to Lane object
+	*/
+	Lane* GetLastAddedLane();
+
+	/**
+	* Get the last left lane
+	* @return A pointer to Lane object
+	*/
+	Lane* GetLastLeftLane();
+
+	/**
+	* Get the last right lane
+	* @return A pointer to Lane object
+	*/
+	Lane* GetLastRightLane();
+
+	/**
+	* Get the last center lane
+	* @return A pointer to Lane object
+	*/
+	Lane* GetLastCenterLane();
+
+	/**
+	* Get the lane by providing its index
+	* @param i Index of the lane to be returned
+	* @return A pointer to Lane object
+	*/
+	Lane* GetLane(unsigned int i);
+
+	/**
+	* Get the lane number
+	* @return Unsigned int with that stores the number of lanes
+	*/
+	unsigned int GetLaneCount();
+
+	/**
+	* Get the lane vector
+	* @return A pointer to a vector of type Lane
+	*/
+	vector<Lane>* GetLaneVector();
+
+	/**
+	* Get the lane section s-offset
+	*/
+	double GetS();
+
+	/**
+	* Get the lane section final s-offset which is the s-offset of the last record of the lane section
+	*/
+	double GetS2();
+
+	/**
+	* Set the lane section s-offset
+	*/
+	void SetS(double value);
+
+
+	/**
+	* Check if the tested s-offset is inside the lane section interval
+	* @param A double s-offset value that has to be checked
+	* @return Return true if the s-offset value belongs to current lane section, false otherwise
+	*/
+	bool CheckInterval(double s_check);
+
+	/**
+	* Return the lane-0 index in the lanes vector
+	* @return An unsigned int value with the index
+	*/
+	unsigned int GetZeroLaneIndex();
+
+	/**
+	* Return the number of left lanes
+	* @return An unsigned int value with the number of left lanes
+	*/
+	unsigned int GetLeftLaneCount();
+
+	/**
+	* Return the number of central lanes
+	* @return An unsigned int value with the number of central lanes
+	*/
+	unsigned int GetCenterLaneCount();
+
+	/**
+	* Return the number of right lanes
+	* @return An unsigned int value with the number of right lanes
+	*/
+	unsigned int GetRightLaneCount();
+
+	/**
+	* Fill a special structure with all the lane / lane section data that is sampled at a provided s-offset position along the road
+	* @param s_chek s-offset along the road at which to sample the lane section
+	* @param laneSectionSample The structure that has to be filled with the sampled data
+	* @return Returns true if the operation was successful. 
+	*/
+	bool FillLaneSectionSample(double s_check, LaneSectionSample& laneSectionSample);
+
+	/**
+	* Destructor. Delete all the members of the vectors: mLeft, mCenter, mRight
+	*/
+	~LaneSection();
+};
+
+
+/**
+* Lane Section Sample. Holds all the lane information at a certain S value including lane widths, levels, 
+* heights, etc
+*
+*
+*
+*
+*/ 
+class LaneSectionSample
+{
+private:
+	/*
+	*	All the vectors for the data that is sampled. For ease of use the structure is divided into left and right lane groups.
+	*
+	*/
+	vector<string> mLeftTypeVector;
+	vector<double> mLeftWidthVector;
+	vector<LaneHeight> mLeftHeightVector;
+	vector<LaneRoadMark> mLeftRoadMarkVector;
+	vector<bool> mLeftLevelVector;
+
+	vector<string> mRightTypeVector;
+	vector<double> mRightWidthVector;
+	vector<LaneHeight> mRightHeightVector;
+	vector<LaneRoadMark> mRightRoadMarkVector;
+	vector<bool> mRightLevelVector;
+public:
+	LaneSectionSample();
+
+	/*
+	* Add various elements to the structure. Depending on the the value to be added, various input parameters are used.
+	* The methods are divided into left and right for left and right sides of the road.
+	*/
+	void AddLeftType(string type);
+	void AddLeftWidth(double width);
+	void AddLeftHeight(LaneHeight height);
+	void AddLeftRoadMark(LaneRoadMark roadMark);
+	void AddLeftLevel(bool level);
+
+	void AddRightType(string type);
+	void AddRightWidth(double width);
+	void AddRightHeight(LaneHeight height);
+	void AddRightRoadMark(LaneRoadMark roadMark);
+	void AddRightLevel(bool level);
+
+	void AddLeftRecord(string type, double width, LaneHeight height, LaneRoadMark roadMark, bool level);
+	void AddRightRecord(string type, double width, LaneHeight height, LaneRoadMark roadMark, bool level);
+
+	/*
+	* Get various elements of the structure. The methods return type depends on the elements that are returned.
+	* The methods are divided into left and right for left and right sides of the road.
+	*/
+	string GetLeftType(unsigned int i);
+	double GetLeftWidth(unsigned int i);
+	LaneHeight GetLeftHeight(unsigned int i);
+	LaneRoadMark GetLeftRoadMark(unsigned int i);
+	bool GetLeftLevel(unsigned int i);
+
+	string GetRightType(unsigned int i);
+	double GetRightWidth(unsigned int i);
+	LaneHeight GetRightHeight(unsigned int i);
+	LaneRoadMark GetRightRoadMark(unsigned int i);
+	bool GetRightLevel(unsigned int i);
+
+	/*
+	* Get the number of elements in the vectors
+	*/
+	unsigned int GetLeftVectorsSize();
+	unsigned int GetRightVectorsSize();
+
+	/*
+	* Get the various record vectors. The vector type depends on the record
+	* The methods are divided into left and right for left and right sides of the road.
+	*/
+	vector<string>* GetLeftTypeVector();
+	vector<double>* GetLeftWidthVector();
+	vector<LaneHeight>* GetLeftHeigthVector();
+	vector<LaneRoadMark>* GetLeftRoadMarkVector();
+	vector<bool>* GetLeftLevelVector();
+
+	vector<string>* GetRightTypeVector();
+	vector<double>* GetRightWidthVector();
+	vector<LaneHeight>* GetRightHeigthVector();
+	vector<LaneRoadMark>* GetRightRoadMarkVector();
+	vector<bool>* GetRightLevelVector();
+
+
+	/*
+	* Clear the vectors
+	*/
+	void ClearVectors();
+
+};
+
+
+
+/**
+* Lane class. Holds all the record data that describes a lane
+*
+*
+*
+*
+*
+*/
+class Lane
+{
+private:
+	/**
+	*	Record parameters
+	*/
+	short int mSide; //0 = center, -1 = right, 1=left
+	int mId;
+	string mType; 
+	bool mLevel; //true or false(default)
+
+	//links
+	bool mPredecessorExists;
+	int mPredecessor;
+	bool mSuccessorExists;
+	int mSuccessor;
+
+	//Width
+	vector <LaneWidth> mLaneWidth;
+	//Road Mark
+	vector <LaneRoadMark> mLaneRoadMark;
+	//Lane Material
+	vector <LaneMaterial> mLaneMaterial;
+	//Lane Visibility
+	vector <LaneVisibility> mLaneVisibility;
+	//Lane Speed
+	vector <LaneSpeed> mLaneSpeed;
+	//Lane Access
+	vector<LaneAccess> mLaneAccess;
+	//Lane Height
+	vector<LaneHeight> mLaneHeight;
+
+
+	unsigned int mLastAddedLaneWidth;
+	unsigned int mLastAddedLaneRoadMark;
+	unsigned int mLastAddedLaneMaterial;
+	unsigned int mLastAddedLaneVisibility;
+	unsigned int mLastAddedLaneSpeed;
+	unsigned int mLastAddedLaneAccess;
+	unsigned int mLastAddedLaneHeight;
+
+public:
+	/**
+	*	Constructor
+	*/
+	Lane(short int side, int id, string type, bool level);
+	/**
+	*	Operator less, Used to sort the lanes
+	*/
+	bool operator<(Lane rhs)const { return (mId < rhs.mId); }
+
+
+	/**
+	*	Various set methods.
+	*/
+	void SetSide(short int side);
+	void SetId(int id);
+	void SetType(string type);
+	void SetLevel(bool level);
+	void SetPredecessor(int predecessor);
+	void SetSuccessor(int successor);
+
+	/**
+	*	Remove lane linkage methods.
+	*/
+	void RemovePredecessor();
+	void RemoveSuccessor();
+
+	/**
+	 * Methods used to add child records to the respective vectors
+	 */
+	unsigned int AddWidthRecord(double s, double a, double b, double c, double d);
+	unsigned int AddRoadMarkRecord(double sOffset, string type, string weight, string color, double width, string laneChange);
+	unsigned int AddMaterialRecord(double sOffset, string surface, double friction, double roughness);
+	unsigned int AddVisibilityRecord(double sOffset, double forward, double back, double left, double right);
+	unsigned int AddSpeedRecord(double sOffset, double max);
+	unsigned int AddAccessRecord(double sOffset, string restriction);
+	unsigned int AddHeightRecord(double sOffset, double inner, double outer);
+
+	/**
+	 * Methods used to clone child records in the respective vectors
+	 */
+	unsigned int CloneLaneWidth(unsigned int index);
+	unsigned int CloneLaneRoadMark(unsigned int index);
+	unsigned int CloneLaneMaterial(unsigned int index);
+	unsigned int CloneLaneVisibility(unsigned int index);
+	unsigned int CloneLaneSpeed(unsigned int index);
+	unsigned int CloneLaneAccess(unsigned int index);
+	unsigned int CloneLaneHeight(unsigned int index);
+
+	/**
+	 * Methods used to delete child records from the respective vectors
+	 */
+	void DeleteLaneWidth(unsigned int index);
+	void DeleteLaneRoadMark(unsigned int index);
+	void DeleteLaneMaterial(unsigned int index);
+	void DeleteLaneVisibility(unsigned int index);
+	void DeleteLaneSpeed(unsigned int index);
+	void DeleteLaneAccess(unsigned int index);
+	void DeleteLaneHeight(unsigned int index);
+
+
+	/**
+	*	Getters of the lane parameters
+	*/
+	int GetSide();
+	int GetId();
+	string GetType();
+	bool GetLevel();
+
+	/**
+	*	Check if linkage information is provided
+	*/
+	bool IsPredecessorSet();
+	int GetPredecessor();
+	bool IsSuccessorSet();
+	int GetSuccessor();
+
+	/**
+	*	Get pointers to the records vectors
+	*/
+	vector <LaneWidth> *GetLaneWidthVector();
+	vector <LaneRoadMark> *GetLaneRoadMarkVector();
+	vector <LaneMaterial> *GetLaneMaterialVector();
+	vector <LaneVisibility> *GetLaneVisibilityVector();
+	vector <LaneSpeed> *GetLaneSpeedVector();
+	vector <LaneAccess> *GetLaneAccessVector();
+	vector <LaneHeight> *GetLaneHeightVector();
+
+
+	/**
+	*	Get the number of elements in a certain vector
+	*/
+	unsigned int GetLaneWidthCount();
+	unsigned int GetLaneRoadMarkCount();
+	unsigned int GetLaneMaterialCount();
+	unsigned int GetLaneVisibilityCount();
+	unsigned int GetLaneSpeedCount();
+	unsigned int GetLaneAccessCount();
+	unsigned int GetLaneHeightCount();
+
+
+	/**
+	*	Get the elements of a certain vectors at position i
+	*/
+	LaneWidth* GetLaneWidth(unsigned int i); 
+	LaneRoadMark* GetLaneRoadMark(unsigned int i);
+	LaneMaterial* GetLaneMaterial(unsigned int i);
+	LaneVisibility* GetLaneVisibility(unsigned int i);
+	LaneSpeed* GetLaneSpeed(unsigned int i);
+	LaneAccess* GetLaneAccess(unsigned int i);
+	LaneHeight* GetLaneHeight(unsigned int i);
+
+
+	/**
+	*	Get the last elements of a certain vectors
+	*/
+	LaneWidth* GetLastLaneWidth(); 
+	LaneRoadMark* GetLastLaneRoadMark();
+	LaneMaterial* GetLastLaneMaterial();
+	LaneVisibility* GetLastLaneVisibility();
+	LaneSpeed* GetLastLaneSpeed();
+	LaneAccess* GetLastLaneAccess();
+	LaneHeight* GetLastLaneHeight();
+
+	/**
+	*	Get the last added elements of a certain vectors (their position might not be at the end of the vector)
+	*/
+	LaneWidth* GetLastAddedLaneWidth(); 
+	LaneRoadMark* GetLastAddedLaneRoadMark();
+	LaneMaterial* GetLastAddedLaneMaterial();
+	LaneVisibility* GetLastAddedLaneVisibility();
+	LaneSpeed* GetLastAddedLaneSpeed();
+	LaneAccess* GetLastAddedLaneAccess();
+	LaneHeight* GetLastAddedLaneHeight();
+
+	/**
+	*	Check the intervals and return the index of the records that applies to the provided s-offset
+	*/
+	int CheckWidthInterval(double s_check);
+	int CheckRoadMarkInterval(double s_check);
+	int CheckMaterialInterval(double s_check);
+	int CheckVisibilityInterval(double s_check);
+	int CheckSpeedInterval(double s_check);
+	int CheckAccessInterval(double s_check);
+	int CheckHeightInterval(double s_check);
+
+
+	/**
+	*	Evaluate the record and return the width value
+	*/
+	double GetWidthValue(double s_check);
+
+	/**
+	*	Evaluate the record and return the height object
+	*/
+	LaneHeight GetHeightValue(double s_check);
+
+	/**
+	*	Evaluate the road marks records and return the road mark object corresponding to the provided s-offset
+	*/
+	LaneRoadMark GetRoadMarkValue(double s_check);
+
+
+	/**
+	* Destructor
+	* Delete all the members of the vectors:
+	* mLaneWidth, mRoadMark, mLaneMaterial, mLaneVisibility, mLaneSpeed, mLaneAccess, mLaneHeight
+	*/
+	~Lane();
+	//--------------
+
+};
+
+/**
+* Lane width class. Holds all the data that describes a lane width
+*
+*
+*
+*
+*
+*/
+class LaneWidth : public ThirdOrderPolynom
+{
+public:
+
+	/**
+	* Constructor
+	* @param s s-offset of the record starting from the lane section s-offset
+	* @ param a,b,c,d The 4 parameters of the polynomial
+	*/
+	LaneWidth(double s, double a, double b, double c, double d);
+
+};
+
+/**
+* Road mark class. Holds all the data that describes a road mark
+*
+*
+*
+*
+*
+*/
+class LaneRoadMark
+{
+private:
+
+	/*
+	* Parameters of the road mark
+	*/
+	double mSOffset;
+	string mType;
+	string mWeight;
+	string mColor; 
+	double mWidth;
+	string mLaneChange;
+public:
+	/*
+	* Constructors
+	*/
+	LaneRoadMark();
+	LaneRoadMark(double sOffset, string type, string weight, string color, double width, string laneChange);
+	LaneRoadMark(double sOffset, string type, string weight, string color, double width);
+
+	/*
+	* Methods that set the parameters of the road mark
+	*/
+	void SetS(double value);
+	void SetType(string type);
+	void SetWeight(string weight);
+	void SetColor(string color);
+	void SetWidth(double value);
+	void SetLaneChange(string laneChange);
+
+	/*
+	* Methods that return the parameters of the road mark
+	*/
+	double GetS();
+	string GetType();
+	string GetWeight();
+	string GetColor();
+	double GetWidth();
+	string GetLaneChange();
+
+};
+
+/**
+* Lane material class. Contains all the data that describes a lane material
+*
+*
+*
+*
+*
+*/
+class LaneMaterial
+{
+private:
+	/*
+	* Parameters that describe the lane material
+	*/
+	double mSOffset;
+	string mSurface;
+	double mFriction;
+	double mRoughness;
+public:
+
+	/*
+	* Constructor
+	*/
+	LaneMaterial (double sOffset, string surface, double friction, double roughness);
+
+	/*
+	* Methods that return the parameters of the lane material
+	*/
+	double GetS();
+	string GetSurface();
+	double GetFriction();
+	double GetRoughness();
+
+	/*
+	* Methods that set the parameters of the lane material
+	*/
+	void SetS(double value);
+	void SetSurface(string surface);
+	void SetFriction(double value);
+	void SetRoughness(double value);
+
+};
+
+/**
+* Lane visibility class. Contains all the data that describes lane visibility record
+*
+*
+*
+*
+*
+*/
+class LaneVisibility
+{
+private:
+	/*
+	* Parameters that describe the lane visibility
+	*/
+	double mSOffset;
+	double mForward;
+	double mBack;
+	double mLeft;
+	double mRight;
+public:
+	/*
+	* Constructor
+	*/
+	LaneVisibility(double sOffset, double forward, double back, double left, double right);
+
+	/*
+	* Methods that return the parameters of the lane visibility
+	*/
+	double GetS();
+	double GetForward();
+	double GetBack();
+	double GetLeft();
+	double GetRight();
+
+	/*
+	* Methods that set the parameters of the lane visibility
+	*/
+	void SetS(double value);
+	void SetForward(double value);
+	void SetBack(double value);
+	void SetLeft(double value);
+	void SetRight(double value);
+
+};
+
+/**
+* Lane speed class. Contains all the data that describes lane speed record
+*
+*
+*
+*
+*
+*/
+class LaneSpeed
+{
+private:
+	/*
+	* Parameters that describe the lane speed
+	*/
+	double mSOffset;
+	double mMax;
+public:
+	/*
+	* Constructor
+	*/
+	LaneSpeed (double sOffset, double max);
+
+	/*
+	* Methods that return the parameters of the lane speed
+	*/
+	double GetS();
+	double GetMax();
+
+	/*
+	* Methods that set the parameters of the lane speed
+	*/
+	void SetS(double value);
+	void SetMax(double value);
+};
+
+/**
+* Lane access class. Contains all the data that describes lane access record
+*
+*
+*
+*
+*
+*/
+class LaneAccess
+{
+private:
+	/*
+	* Parameters that describe the lane access
+	*/
+	double mSOffset;
+	string mRestriction;
+public:
+	/*
+	* Constructor
+	*/
+	LaneAccess (double sOffset, string restriction);
+
+	/*
+	* Methods that return the parameters of the lane access
+	*/
+	double GetS();
+	string GetRestriction();
+
+	/*
+	* Methods that set the parameters of the lane access
+	*/
+	void SetS(double value);
+	void SetRestriction(string restriction);
+};
+
+/**
+* Lane height class. Contains all the data that describes lane access record
+*
+*
+*
+*
+*
+*/
+class LaneHeight
+{
+private:
+	/*
+	* Parameters that describe the lane height
+	*/
+	double mSOffset;
+	double mInner;
+	double mOuter;
+public:
+	/*
+	* Constructors
+	*/
+	LaneHeight();
+	LaneHeight (double sOffset, double inner, double outer);
+
+	/*
+	* Methods that return the parameters of the lane height
+	*/
+	double GetS();
+	double GetInner();
+	double GetOuter();
+
+	/*
+	* Methods that set the parameters of the lane height
+	*/
+	void SetS(double value);
+	void SetInner(double value);
+	void SetOuter(double value);
+};
+
+//----------------------------------------------------------------------------------
+
+
+#endif

+ 514 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/ObjectSignal.cpp

@@ -0,0 +1,514 @@
+#include "ObjectSignal.h"
+
+#include <iostream>
+
+signal_positionRoad::signal_positionRoad(double s, double t, double zOffset, double hOffset, double pitch, double roll)
+{
+    ms = s;
+    mt = t;
+    mzOffset = zOffset;
+    mhOffset = hOffset;
+    mpitch = pitch;
+    mroll = roll;
+}
+
+double signal_positionRoad::Gets()
+{
+    return ms;
+}
+
+double signal_positionRoad::Gett()
+{
+    return mt;
+}
+
+double signal_positionRoad::GetzOffset()
+{
+    return mzOffset;
+}
+
+double signal_positionRoad::GethOffset()
+{
+    return mhOffset;
+}
+
+double signal_positionRoad::Getpitch()
+{
+    return mpitch;
+}
+
+double signal_positionRoad::Getroll()
+{
+    return mroll;
+}
+
+void signal_positionRoad::Sets(double s)
+{
+    ms = s;
+}
+
+void signal_positionRoad::Sett(double t)
+{
+    mt = t;
+}
+
+void signal_positionRoad::SetzOffset(double zOffset)
+{
+    mzOffset = zOffset;
+}
+
+void signal_positionRoad::SethOffset(double hOffset)
+{
+    mhOffset = hOffset;
+}
+
+void signal_positionRoad::Setpitch(double pitch)
+{
+    mpitch = pitch;
+}
+
+void signal_positionRoad::Setroll(double roll)
+{
+    mroll = roll;
+}
+
+signal_positionInertial::signal_positionInertial(double x, double y,double z, double hdg, double pitch, double roll)
+{
+    mx = x;
+    my = y;
+    mz = z;
+    mhdg = hdg;
+    mpitch = pitch;
+    mroll = roll;
+}
+
+double signal_positionInertial::Getx()
+{
+    return mx;
+}
+
+double signal_positionInertial::Gety()
+{
+    return my;
+}
+
+double signal_positionInertial::Getz()
+{
+    return mz;
+}
+
+double signal_positionInertial::Gethdg()
+{
+    return mhdg;
+}
+
+double signal_positionInertial::Getpitch()
+{
+    return mpitch;
+}
+
+double signal_positionInertial::Getroll()
+{
+    return mroll;
+}
+
+void signal_positionInertial::Setx(double x)
+{
+    mx = x;
+}
+
+void signal_positionInertial::Sety(double y)
+{
+    my = y;
+}
+
+void signal_positionInertial::Setz(double z)
+{
+    mz = z;
+}
+
+void signal_positionInertial::Sethdg(double hdg)
+{
+    mhdg = hdg;
+}
+
+void signal_positionInertial::Setpitch(double pitch)
+{
+    mpitch = pitch;
+}
+
+void signal_positionInertial::Setroll(double roll)
+{
+    mroll = roll;
+}
+
+
+signal_laneValidity::signal_laneValidity(int fromLane,int toLane)
+{
+    mfromLane = fromLane;
+    mtoLane = toLane;
+}
+
+int signal_laneValidity::GetfromLane()
+{
+    return mfromLane;
+}
+
+int signal_laneValidity::GettoLane()
+{
+    return mtoLane;
+}
+
+void signal_laneValidity::SetfromLane(int fromLane)
+{
+    mfromLane = fromLane;
+}
+
+void signal_laneValidity::SettoLane(int toLane)
+{
+    mtoLane = toLane;
+}
+
+
+Signal::Signal(double s, double t, std::string id, std::string name, bool dynamic,string orientation,
+               double zOffset, string type, std::string country, std::string countryRevision,
+               string subtype, double hOffset, double pitch, double roll, double height, double width)
+{
+    ms = s;
+    mt = t;
+    mid = id;
+    mname = name;
+    mdynamic = dynamic;
+    morientation = orientation;
+    mzOffset = zOffset;
+    mtype = type;
+    mcountry = country;
+    mcountryRevision = countryRevision;
+    msubtype = subtype;
+    mhOffset = hOffset;
+    mpitch = pitch;
+    mroll = roll;
+    mheight = height;
+    mwidth = width;
+    mpsignal_laneValidity = 0;
+    mpsignal_positionInertial = 0;
+    mpsignal_positionRoad = new signal_positionRoad(s,t,zOffset,hOffset,pitch,roll);
+}
+
+Signal::Signal()
+{
+    mpsignal_positionInertial = 0;
+    mpsignal_positionRoad = 0;
+    mpsignal_laneValidity = 0;
+
+}
+Signal::~Signal()
+{
+    if(mpsignal_laneValidity != 0)delete mpsignal_laneValidity;
+    if(mpsignal_positionInertial != 0)delete mpsignal_positionInertial;
+    if(mpsignal_positionRoad != 0)delete mpsignal_positionRoad;
+}
+
+Signal& Signal::operator=(const Signal& x)
+{
+    if (this != &x)
+    {
+        this->ms = x.ms;
+        this->mt = x.mt;
+        this->mid = x.mid;
+        this->mname = x.mname;
+        this->mdynamic = x.mdynamic;
+        this->morientation = x.morientation;
+        this->mzOffset = x.mzOffset;
+        this->mtype = x.mtype;
+        this->mcountry = x.mcountry;
+        this->mcountryRevision = x.mcountryRevision;
+        this->msubtype = x.msubtype;
+        this->mhOffset = x.mhOffset;
+        this->mpitch = x.mpitch;
+        this->mroll = x.mroll;
+        this->mheight = x.mheight;
+        this->mwidth = x.mwidth;
+        this->mpsignal_positionInertial = 0;
+        if(x.mpsignal_positionInertial != 0)
+        {
+            this->mpsignal_positionInertial = new signal_positionInertial(x.mpsignal_positionInertial->Getx(),
+                                                                      x.mpsignal_positionInertial->Gety(),
+                                                                      x.mpsignal_positionInertial->Getz(),
+                                                                      x.mpsignal_positionInertial->Gethdg(),
+                                                                      x.mpsignal_positionInertial->Getpitch(),
+                                                                      x.mpsignal_positionInertial->Getroll());
+        }
+        this->mpsignal_laneValidity = 0;
+        if(x.mpsignal_laneValidity != 0)
+        {
+            this->mpsignal_laneValidity = new signal_laneValidity(x.mpsignal_laneValidity->GetfromLane(),
+                                                              x.mpsignal_laneValidity->GettoLane());
+        }
+        this->mpsignal_positionRoad = new signal_positionRoad(ms,mt,mzOffset,mhOffset,mpitch,mroll);
+    }
+    return *this;
+}
+
+Signal::Signal(const Signal &x)
+{
+    ms = x.ms;
+    mt = x.mt;
+    mid = x.mid;
+    mname = x.mname;
+    mdynamic = x.mdynamic;
+    morientation = x.morientation;
+    mzOffset = x.mzOffset;
+    mtype = x.mtype;
+    mcountry = x.mcountry;
+    mcountryRevision = x.mcountryRevision;
+    msubtype = x.msubtype;
+    mhOffset = x.mhOffset;
+    mpitch = x.mpitch;
+    mroll = x.mroll;
+    mheight = x.mheight;
+    mwidth = x.mwidth;
+    this->mpsignal_positionInertial = 0;
+    if(x.mpsignal_positionInertial != 0)
+    {
+        this->mpsignal_positionInertial = new signal_positionInertial(x.mpsignal_positionInertial->Getx(),
+                                                                  x.mpsignal_positionInertial->Gety(),
+                                                                  x.mpsignal_positionInertial->Getz(),
+                                                                  x.mpsignal_positionInertial->Gethdg(),
+                                                                  x.mpsignal_positionInertial->Getpitch(),
+                                                                  x.mpsignal_positionInertial->Getroll());
+    }
+    this->mpsignal_laneValidity = 0;
+    if(x.mpsignal_laneValidity != 0)
+    {
+        this->mpsignal_laneValidity = new signal_laneValidity(x.mpsignal_laneValidity->GetfromLane(),
+                                                          x.mpsignal_laneValidity->GettoLane());
+    }
+    mpsignal_positionRoad = new signal_positionRoad(ms,mt,mzOffset,mhOffset,mpitch,mroll);
+}
+
+double Signal::Gets()
+{
+    return ms;
+}
+
+double Signal::Gett()
+{
+    return mt;
+}
+
+string Signal::Getid()
+{
+    return mid;
+}
+
+string Signal::Getname()
+{
+    return mname;
+}
+
+bool Signal::Getdynamic()
+{
+    return mdynamic;
+}
+
+string Signal::Getorientation()
+{
+    return morientation;
+}
+
+double Signal::GetzOffset()
+{
+    return mzOffset;
+}
+
+string Signal::Gettype()
+{
+    return mtype;
+}
+
+string Signal::Getcountry()
+{
+    return mcountry;
+}
+
+string Signal::GetcountryRevision()
+{
+    return mcountryRevision;
+}
+
+string Signal::Getsubtype()
+{
+    return msubtype;
+}
+
+double Signal::GethOffset()
+{
+    return mhOffset;
+}
+
+double Signal::Getpitch()
+{
+    return mpitch;
+}
+
+double Signal::Getroll()
+{
+    return mroll;
+}
+
+double Signal::Getheight()
+{
+    return mheight;
+}
+
+double Signal::Getwidth()
+{
+    return mwidth;
+}
+
+signal_positionRoad * Signal::GetpositionRoad()
+{
+    return mpsignal_positionRoad;
+}
+
+signal_positionInertial * Signal::GetpositionInertial()
+{
+    return mpsignal_positionInertial;
+}
+
+void Signal::Sets(double s)
+{
+    ms = s;
+}
+
+void Signal::Sett(double t)
+{
+    mt = t;
+}
+
+void Signal::Setid(std::string id)
+{
+    mid = id;
+}
+
+void Signal::Setname(std::string name)
+{
+    mname = name;
+}
+
+void Signal::Setdynamic(bool dynamic)
+{
+    mdynamic = dynamic;
+}
+
+void Signal::Setorientation(std::string orientation)
+{
+    morientation = orientation;
+}
+
+void Signal::SetzOffset(double zOffset)
+{
+    mzOffset = zOffset;
+}
+
+void Signal::Settype(string type)
+{
+    mtype = type;
+}
+
+void Signal::Setcountry(std::string country)
+{
+    mcountry = country;
+}
+
+void Signal::SetcountryRevision(std::string countryRevision)
+{
+    mcountryRevision = countryRevision;
+}
+
+void Signal::Setsubtype(string subtype)
+{
+    msubtype = subtype;
+}
+
+void Signal::SethOffset(double hOffset)
+{
+    mhOffset = hOffset;
+}
+
+void Signal::Setpitch(double pitch)
+{
+    mpitch = pitch;
+}
+
+void Signal::Setroll(double roll)
+{
+    mroll = roll;
+}
+
+void Signal::Setheight(double height)
+{
+    mheight = height;
+}
+
+void Signal::Setwidth(double width)
+{
+    mwidth = width;
+}
+
+void Signal::SetlaneValidity(int fromLane, int toLane)
+{
+    if(mpsignal_laneValidity == 0)
+    {
+        mpsignal_laneValidity = new signal_laneValidity(fromLane,toLane);
+    }
+    else
+    {
+        mpsignal_laneValidity->SetfromLane(fromLane);
+        mpsignal_laneValidity->SettoLane(toLane);
+    }
+}
+
+void Signal::SetpositionRoad(double s, double t, double zOffset, double hOffset, double pitch,double roll)
+{
+    if(mpsignal_positionRoad == 0)
+    {
+        mpsignal_positionRoad = new signal_positionRoad(s,t,zOffset,hOffset,pitch,roll);
+    }
+    else
+    {
+        mpsignal_positionRoad->Sets(s);
+        mpsignal_positionRoad->Sett(t);
+        mpsignal_positionRoad->SetzOffset(zOffset);
+        mpsignal_positionRoad->SethOffset(hOffset);
+        mpsignal_positionRoad->Setpitch(pitch);
+        mpsignal_positionRoad->Setroll(roll);
+    }
+}
+
+void Signal::SetpositionInertial(double x, double y, double z, double hdg, double pitch, double roll)
+{
+    if(mpsignal_positionInertial == 0)
+    {
+        mpsignal_positionInertial = new signal_positionInertial(x,y,z,hdg,pitch,roll);
+    }
+    else
+    {
+        mpsignal_positionInertial->Setx(x);
+        mpsignal_positionInertial->Sety(y);
+        mpsignal_positionInertial->Setz(z);
+        mpsignal_positionInertial->Sethdg(hdg);
+        mpsignal_positionInertial->Setpitch(pitch);
+        mpsignal_positionInertial->Setroll(roll);
+    }
+}
+
+signal_laneValidity * Signal::GetlaneValidity()
+{
+    return mpsignal_laneValidity;
+}
+
+
+
+

+ 163 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/ObjectSignal.h

@@ -0,0 +1,163 @@
+#ifndef OBJECTSIGNAL_H
+#define OBJECTSIGNAL_H
+
+#include <vector>
+#include <string>
+
+using std::vector;
+using std::string;
+
+
+//***********************************************************************************
+//Object
+//***********************************************************************************
+class Object
+{
+public:
+	Object(){}
+};
+//----------------------------------------------------------------------------------
+
+
+
+class signal_positionRoad
+{
+private:
+    double ms;
+    double mt;
+    double mzOffset;
+    double mhOffset;
+    double mpitch;
+    double mroll;
+public:
+    signal_positionRoad(double s,double t,double zOffset,double hOffset, double pitch,double roll);
+    double Gets();
+    double Gett();
+    double GetzOffset();
+    double GethOffset();
+    double Getpitch();
+    double Getroll();
+    void Sets(double s);
+    void Sett(double t);
+    void SetzOffset(double zOffset);
+    void SethOffset(double hOffset);
+    void Setpitch(double pitch);
+    void Setroll(double roll);
+};
+
+class signal_positionInertial
+{
+private:
+    double mx;
+    double my;
+    double mz;
+    double mhdg;
+    double mpitch;
+    double mroll;
+public:
+    signal_positionInertial(double x,double y,double z,double hdg,double pitch,double roll );
+    double Getx();
+    double Gety();
+    double Getz();
+    double Gethdg();
+    double Getpitch();
+    double Getroll();
+    void Setx(double x);
+    void Sety(double y);
+    void Setz(double z);
+    void Sethdg(double hdg);
+    void Setpitch(double pitch);
+    void Setroll(double roll);
+};
+
+class signal_laneValidity
+{
+private:
+    int mfromLane;
+    int mtoLane;
+public:
+    signal_laneValidity(int fromLane,int toLane);
+    int GetfromLane();
+    int GettoLane();
+    void SetfromLane(int fromLane);
+    void SettoLane(int toLane);
+};
+
+
+//***********************************************************************************
+//Signal
+//***********************************************************************************
+class Signal
+{
+private:
+    double ms;
+    double mt;
+    string mid;
+    string mname;
+    bool mdynamic;
+    string morientation;
+    double mzOffset;
+    string mtype;
+    string mcountry;
+    string mcountryRevision;
+    string msubtype;
+    double mhOffset;
+    double mpitch;
+    double mroll;
+    double mheight;
+    double mwidth;
+    signal_positionRoad * mpsignal_positionRoad;
+    signal_positionInertial * mpsignal_positionInertial;
+    signal_laneValidity * mpsignal_laneValidity;
+public:
+    Signal(double s,double t,string id,string name,bool dynamic,string orientation,double zOffset,string type,string country,string countryRevision,
+           string subtype,double hOffset,double pitch,double roll ,double height,double width);
+    Signal();
+    ~Signal();
+    Signal& operator=(const Signal& x);
+    Signal(const Signal & x);
+    double Gets();
+    double Gett();
+    string Getid();
+    string Getname();
+    bool Getdynamic();
+    string Getorientation();
+    double GetzOffset();
+    string Gettype();
+    string Getcountry();
+    string GetcountryRevision();
+    string Getsubtype();
+    double GethOffset();
+    double Getpitch();
+    double Getroll();
+    double Getheight();
+    double Getwidth();
+    signal_positionRoad * GetpositionRoad();
+    signal_positionInertial * GetpositionInertial();
+    signal_laneValidity * GetlaneValidity();
+    void Sets(double s);
+    void Sett(double t);
+    void Setid(string id);
+    void Setname(string name);
+    void Setdynamic(bool dynamic);
+    void Setorientation(string orientation);
+    void SetzOffset(double zOffset);
+    void Settype(string type);
+    void Setcountry(string country);
+    void SetcountryRevision(string countryRevision);
+    void Setsubtype(string subtype);
+    void SethOffset(double hOffset);
+    void Setpitch(double pitch);
+    void Setroll(double roll);
+    void Setheight(double height);
+    void Setwidth(double width);
+    void SetlaneValidity(int fromLane, int toLane);
+    void SetpositionRoad(double s,double t, double zOffset,double hOffset,double pitch,double roll);
+    void SetpositionInertial(double x,double y, double z, double hdg,double pitch,double roll);
+
+
+};
+//----------------------------------------------------------------------------------
+
+
+#endif

+ 307 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDrive.cpp

@@ -0,0 +1,307 @@
+#include "OpenDrive.h"
+
+
+//***********************************************************************************
+//OpenDRIVE Structure
+//***********************************************************************************
+/**
+ * Constructor
+ */
+OpenDrive::OpenDrive()
+{
+	mHeader=NULL;
+}
+
+
+/**
+ * Sets the header of the OpenDrive file
+ */
+void OpenDrive::SetHeader(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date, 
+						  double north, double south, double east,double west)
+{	
+	if (mHeader==NULL)
+		mHeader=new Header(revMajor, revMinor, name, version, date, north, south, east, west);
+	else
+	{
+		mHeader->SetAllParams(revMajor, revMinor, name, version, date, north, south, east, west);
+	}
+
+}
+
+void OpenDrive::SetHeader(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date,
+                          double north, double south, double east,double west,double lat0,double lon0,double hdg0)
+{
+    if (mHeader==NULL)
+        mHeader=new Header(revMajor, revMinor, name, version, date, north, south, east, west,lat0,lon0,hdg0);
+    else
+    {
+        mHeader->SetAllParams(revMajor, revMinor, name, version, date, north, south, east, west,lat0,lon0,hdg0);
+    }
+
+}
+
+/**
+ * Methods used to add records to the respective vectors
+ */
+unsigned int OpenDrive::AddRoad(string name, double length, string id, string junction)
+{
+	unsigned int index=GetRoadCount();
+	// Adds the new road to the end of the vector
+	mRoadVector.push_back(Road(name, length, id, junction));
+	// Saves the index of the newly added road
+	mLastAddedRoad=index;
+	return index;
+}
+unsigned int OpenDrive::AddJunction(string name, string id)
+{
+	unsigned int index=GetJunctionCount();
+	// Adds the new junction to the end of the vector
+	mJunctionVector.push_back(Junction(name,id));
+	// Saves the index of the newly added junction
+	mLastAddedJunction=index;
+	return index;
+}
+
+/**
+ * Methods used to delete records from the respective vectors
+ */
+void OpenDrive::DeleteRoad(unsigned int index)
+{
+	mRoadVector.erase(mRoadVector.begin()+index);
+}
+void OpenDrive::DeleteJunction(unsigned int index)
+{
+	mJunctionVector.erase(mJunctionVector.begin()+index);
+}
+
+//-------------------------------------------------
+
+/**
+ * Getters for the last child records in their respective vectors
+ */
+Road* OpenDrive::GetLastRoad()
+{	
+	if (mRoadVector.size()>0)
+		return &(mRoadVector.at(mRoadVector.size()-1));
+	else
+		return NULL;
+}
+Junction* OpenDrive::GetLastJunction()
+{
+	if (mJunctionVector.size()>0)
+		return &(mJunctionVector.at(mJunctionVector.size()-1));
+	else
+		return NULL;
+}
+
+/**
+ * Getters for the last added records in their respective vectors
+ */
+Road* OpenDrive::GetLastAddedRoad()
+{	
+	if(mLastAddedRoad<mRoadVector.size())
+		return &mRoadVector.at(mLastAddedRoad);
+	else
+		return NULL;
+}
+
+/**
+ * Getter for the OpenDrive header
+ */
+Header* OpenDrive::GetHeader()
+{ 
+	return mHeader;
+}
+
+/**
+ * Getters for the records and their vectors
+ */
+// Road records
+vector<Road> * OpenDrive::GetRoadVector()
+{
+	return &mRoadVector;
+}
+Road* OpenDrive::GetRoad(unsigned int i)
+{	
+	if ((i < mRoadVector.size())&&( mRoadVector.size()>0))
+		return &(mRoadVector.at(i));	
+	else
+		return NULL;
+}
+unsigned int OpenDrive::GetRoadCount()
+{	
+	return mRoadVector.size();	
+}
+// Junction records
+vector<Junction> * OpenDrive::GetJunctionVector()
+{
+	return &mJunctionVector;
+}
+Junction* OpenDrive::GetJunction(unsigned int i)
+{	if (i < mJunctionVector.size())
+		return &(mJunctionVector.at(i));
+	else
+		return NULL;
+}
+unsigned int OpenDrive::GetJunctionCount()
+{	
+	return mJunctionVector.size();	
+}
+//-------------------------------------------------
+
+/**
+ * Clears the OpenDrive structure, could be used to start a new document
+ */
+void OpenDrive::Clear()
+{
+	mRoadVector.clear();
+	mJunctionVector.clear();
+}
+
+/**
+ * Destructor
+ */
+OpenDrive::~OpenDrive()
+{
+	if (mHeader!=NULL)
+		delete mHeader;
+
+	// DELETING ROADS
+	mRoadVector.clear();
+
+	// DELETING JUNCTIONS
+	mJunctionVector.clear();
+}
+
+
+//***********************************************************************************
+//Header
+//***********************************************************************************
+/**
+ * Constructor that initializes the base properties
+ */
+Header::Header(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date, 
+			   double north, double south, double east,double west)
+{
+	mRevMajor=revMajor;
+	mRevMinor=revMinor;
+	mName=name;
+	mVersion=version;
+	mDate=date;
+	mNorth=north;
+	mSouth=south;
+	mEast=east;
+	mWest=west;
+
+}
+
+Header::Header(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date,
+               double north, double south, double east,double west,double lat0,double lon0,double hdg0)
+{
+    mRevMajor=revMajor;
+    mRevMinor=revMinor;
+    mName=name;
+    mVersion=version;
+    mDate=date;
+    mNorth=north;
+    mSouth=south;
+    mEast=east;
+    mWest=west;
+
+    mLat0=lat0;
+    mLon0=lon0;
+    mHdg0=hdg0;
+
+}
+
+/**
+ * Getter for all properties
+ */
+void Header::GetAllParams(unsigned short int &revMajor, unsigned short int &revMinor, string &name, float &version, string &date, 
+						  double &north, double &south, double &east,double &west)
+{
+	revMajor=mRevMajor;
+	revMinor=mRevMinor;
+	name=mName;
+	version=mVersion;
+	date=mDate;
+	north=mNorth;
+	south=mSouth;
+	east=mEast;
+	west=mWest;
+
+}
+
+void Header::GetAllParams(unsigned short int &revMajor, unsigned short int &revMinor, string &name, float &version, string &date,
+                          double &north, double &south, double &east,double &west,double &lat0,double &lon0, double & hdg0)
+{
+    revMajor=mRevMajor;
+    revMinor=mRevMinor;
+    name=mName;
+    version=mVersion;
+    date=mDate;
+    north=mNorth;
+    south=mSouth;
+    east=mEast;
+    west=mWest;
+    lat0=mLat0;
+    lon0=mLon0;
+    hdg0=mHdg0;
+
+}
+
+
+void Header::GetXYValues(double &north, double &south, double &east,double &west)
+{
+	north=mNorth;
+	south=mSouth;
+	east=mEast;
+	west=mWest;
+}
+
+/**
+ * Setter for all properties
+ */
+void Header::SetAllParams(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date, 
+						  double north, double south, double east,double west)
+{
+	mRevMajor=revMajor;
+	mRevMinor=revMinor;
+	mName=name;
+	mVersion=version;
+	mDate=date;
+	mNorth=north;
+	mSouth=south;
+	mEast=east;
+	mWest=west;
+}
+
+void Header::SetAllParams(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date,
+                          double north, double south, double east,double west,double lat0,double lon0,double hdg0)
+{
+    mRevMajor=revMajor;
+    mRevMinor=revMinor;
+    mName=name;
+    mVersion=version;
+    mDate=date;
+    mNorth=north;
+    mSouth=south;
+    mEast=east;
+    mWest=west;
+    mLat0=lat0;
+    mLon0=lon0;
+    mHdg0=hdg0;
+}
+void Header::SetXYValues(double north, double south, double east,double west)
+{
+	mNorth=north;
+	mSouth=south;
+	mEast=east;
+	mWest=west;
+}
+
+void Header::GetLat0Lon0(double &lat0, double &lon0)
+{
+    lat0 = mLat0;
+    lon0 = mLon0;
+}

+ 190 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDrive.h

@@ -0,0 +1,190 @@
+#ifndef OPENDRIVE_H
+#define OPENDRIVE_H
+
+#include <vector>
+#include <string>
+
+#include "Road.h"
+//--Prototypes--
+//main
+class Header;
+//--------------
+
+
+using std::vector;
+using std::string;
+
+
+/**
+ * The main class in OpenDrive structure
+ * Holds the two vectors of the top-level records: ROAD and JUNCTION
+ * Has methods to add, get and delete those records
+ * From this class - one could get access to any record in OpenDrive structure
+ * going down the hierarchy
+ */
+class OpenDrive
+{
+private:
+	/**
+	 * Header of the OpenDrive file
+	 */
+	Header* mHeader;
+
+	/**
+	 * Vectors used to store the top-level ROAD and JUNCTION records
+	 */
+	vector<Road> mRoadVector;
+	vector<Junction> mJunctionVector;
+	
+	/**
+	 * Indices of the last added records
+	 */
+	unsigned int mLastAddedRoad;
+	unsigned int mLastAddedJunction;
+
+	//-------------------------------------------------
+
+	/**
+	 * Copy constructor, makes the object non-copyable
+	 */
+	OpenDrive (const OpenDrive& openDrive){};
+	const OpenDrive& operator=(const OpenDrive& rhs){};
+
+public:
+	/**
+	 * Constructor
+	 */
+	OpenDrive();
+
+	//-------------------------------------------------
+
+	/**
+	 * Sets the header of the OpenDrive file
+	 */
+	void SetHeader(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date, 
+					double north, double south, double east,double west);
+
+    /**
+     * Sets the header of the OpenDrive file  Added by Yuchuli,2019.11.04
+     */
+    void SetHeader(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date,
+                    double north, double south, double east,double west,double lat0,double lon0,double hdg0);
+	
+	/**
+	 * Methods used to add records to the respective vectors
+	 */
+	unsigned int AddRoad(string name, double length, string id, string junction);
+	unsigned int AddJunction(string name, string id);
+
+	/**
+	 * Methods used to delete records from the respective vectors
+	 */
+	void DeleteRoad(unsigned int index);
+	void DeleteJunction(unsigned int index);
+
+	//-------------------------------------------------
+
+	/**
+	 * Getters for the last child records in their respective vectors
+	 */
+	Road* GetLastRoad();
+	Junction* GetLastJunction();
+
+	/**
+	 * Getters for the last added records in their respective vectors
+	 */
+	Road* GetLastAddedRoad();
+
+	/**
+	 * Getter for the OpenDrive header
+	 */
+	Header* GetHeader();
+
+	/**
+	 * Getters for the records and their vectors
+	 */
+	// Road records
+	vector<Road> * GetRoadVector();
+	Road* GetRoad(unsigned int i);
+	unsigned int GetRoadCount();
+	// Junction records
+	vector<Junction> * GetJunctionVector();
+	Junction* GetJunction(unsigned int i);
+	unsigned int GetJunctionCount();
+	
+	//-------------------------------------------------
+
+
+	/**
+	 * Clears the OpenDrive structure, could be used to start a new document
+	 */
+	void Clear();
+
+
+	/**
+	 * Destructor
+	 */
+	~OpenDrive();
+};
+
+
+
+/**
+ * Class used to store the heading details of the OpenDrive file
+ */
+class Header
+{
+private:
+	/**
+	 * Base properties
+	 */
+	unsigned short int mRevMajor;
+	unsigned short int mRevMinor;
+	string mName;
+	float mVersion;
+	string mDate;
+	double mNorth;
+	double mSouth;
+	double mEast;
+	double mWest;
+
+    //Added by Yuchuli,2019.11.04
+    double mLat0;
+    double mLon0;
+    double mHdg0;
+
+public:
+	/**
+	 * Constructor that initializes the base properties
+	 */
+	Header(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date, 
+		double north, double south, double east,double west);
+
+    Header(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date,
+        double north, double south, double east,double west,double lat0,double lon0, double hdg0);
+	
+	/**
+	 * Getter for all properties
+	 */
+	void GetAllParams(unsigned short int &revMajor, unsigned short int &revMinor, string &name, float &version, string &date, 
+		double &north, double &south, double &east,double &west);
+    void GetAllParams(unsigned short int &revMajor, unsigned short int &revMinor, string &name, float &version, string &date,
+        double &north, double &south, double &east,double &west,double &lat0,double &lon0, double & hdg0);
+	void GetXYValues(double &north, double &south, double &east,double &west);
+	
+	/**
+	 * Setter for all properties
+	 */
+	void SetAllParams(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date, 
+		double north, double south, double east,double west);
+	void SetXYValues(double north, double south, double east,double west);
+
+    void SetAllParams(unsigned short int revMajor, unsigned short int revMinor, string name, float version, string date,
+        double north, double south, double east,double west,double lat0,double lon0,double hdg0);
+
+
+    void GetLat0Lon0(double & lat0,double & lon0);
+};
+
+
+#endif

+ 1226 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDriveXmlParser.cpp

@@ -0,0 +1,1226 @@
+#include "OpenDriveXmlParser.h"
+#include <iostream>
+#include <algorithm>
+//#include "windows.h"
+
+using std::cout;
+using std::endl;
+
+/**
+ * Constructor which saves a reference to OpenDrive structure
+ */
+OpenDriveXmlParser::OpenDriveXmlParser (OpenDrive* openDriveObj)
+{	
+	mOpenDrive=openDriveObj;	
+}
+
+/**
+ * The following methods are used to read the data from the XML file and fill in the the OpenDrive structure
+ * Methods follow the hierarchical structure and are called automatically when ReadFile is executed
+ */
+bool OpenDriveXmlParser::ReadHeader(TiXmlElement *node)
+{
+	//Read the Header
+	unsigned short int revMajor;
+	unsigned short int revMinor;
+	string name;
+	float version;
+	string date;
+	double north;
+	double south;
+	double east;
+	double west;
+
+    //Added By Yuchuli,2019.11.04
+    double lat0;
+    double lon0;
+    double hdg0;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryValueAttribute<unsigned short int>("revMajor",&revMajor);
+	checker+=node->QueryValueAttribute<unsigned short int>("revMinor",&revMinor);
+	checker+=node->QueryStringAttribute("name",&name);
+	checker+=node->QueryFloatAttribute("version",&version);
+	checker+=node->QueryStringAttribute("date",&date);
+	checker+=node->QueryDoubleAttribute("north",&north);
+	checker+=node->QueryDoubleAttribute("south",&south);
+	checker+=node->QueryDoubleAttribute("east",&east);
+	checker+=node->QueryDoubleAttribute("west",&west);
+
+
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Header attributes"<<endl;
+		return false;
+	}
+
+    checker+=node->QueryDoubleAttribute("lat0",&lat0);
+    checker+=node->QueryDoubleAttribute("lon0",&lon0);
+    checker+=node->QueryDoubleAttribute("hdg0",&hdg0);
+
+    mOpenDrive->SetHeader(revMajor, revMinor, name, version, date, north, south, east, west,lat0,lon0,hdg0);
+
+	return true;
+
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadRoad(TiXmlElement *node)
+{
+	//Read road attributes
+	string name;
+	double length;
+	string id;
+	string junction;
+
+	int checker=TIXML_SUCCESS;
+	
+//	checker+=node->QueryStringAttribute("name",&name);
+	checker+=node->QueryDoubleAttribute("length",&length);
+	checker+=node->QueryStringAttribute("id",&id);
+	checker+=node->QueryStringAttribute("junction",&junction);
+
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Road attributes"<<endl;
+		return false;
+	}
+
+    if(node->QueryStringAttribute("name",&name) != TIXML_SUCCESS)
+    {
+        name = "";
+    }
+	//fill in
+	mOpenDrive->AddRoad(name, length, id, junction);
+	Road* road = mOpenDrive->GetLastAddedRoad();
+	TiXmlElement* subNode;
+
+
+	//Get links
+	subNode=node->FirstChildElement("link");
+	if (subNode)
+	{
+		ReadRoadLinks (road,subNode);
+	}	
+
+	//Proceed to road Type
+	subNode=node->FirstChildElement("type");
+	while (subNode)
+	{
+		ReadRoadType(road, subNode);
+		subNode=subNode->NextSiblingElement("type");
+	}
+
+	//Proceed to planView
+	subNode=node->FirstChildElement("planView");
+	ReadPlanView(road, subNode);
+
+	//Proceed to ElevationProfile
+	subNode=node->FirstChildElement("elevationProfile");
+	if (subNode)
+	{
+		ReadElevationProfile(road, subNode);
+	}
+
+	//Proceed to LateralProfile
+	subNode=node->FirstChildElement("lateralProfile");
+	if (subNode)
+	{
+		ReadLateralProfile(road, subNode);
+	}
+
+	//Proceed to Lanes
+	subNode=node->FirstChildElement("lanes");
+	ReadLanes(road, subNode);
+
+	//Proceed to Objects
+	subNode=node->FirstChildElement("objects");
+	if (subNode)
+	{
+		ReadObjects(road, subNode);
+	}
+
+	//Proceed to Signals
+	subNode=node->FirstChildElement("signals");
+	if (subNode)
+	{
+		ReadSignals(road, subNode);
+	}
+
+	//Proceed to Surface
+	subNode=node->FirstChildElement("surface");
+	if (subNode)
+	{
+		ReadSurface(road, subNode);
+	}
+
+	return true;
+}
+//--------------
+
+bool  OpenDriveXmlParser::ReadRoadLinks (Road* road, TiXmlElement *node)
+{
+	TiXmlElement* subNode;
+	subNode=node->FirstChildElement("predecessor");
+	if (subNode)
+	{
+		ReadRoadLink(road, subNode,0);
+	}
+
+	subNode=node->FirstChildElement("successor");
+	if (subNode)
+	{
+		ReadRoadLink(road, subNode,1);
+	}
+
+	subNode=node->FirstChildElement("neighbor");
+	if (subNode)
+	{
+		ReadRoadLink(road, subNode,2);
+	}
+
+	subNode=node->NextSiblingElement("neighbor");
+	if (subNode)
+	{
+		ReadRoadLink(road, subNode,2);
+	}
+
+	return true;
+}
+//--------------
+
+bool  OpenDriveXmlParser::ReadRoadLink (Road* road, TiXmlElement *node, short int type)
+{
+	//all three types (neighbor, successor or predecessor) have the same number and same types of members,
+	//but in case this changes in future, load it separately
+	if (type == 0)
+	{
+		string elementType; 
+		string elementId;
+		string contactPoint="NA";
+
+		int checker=TIXML_SUCCESS;
+		checker+=node->QueryStringAttribute("elementType",&elementType);
+		checker+=node->QueryStringAttribute("elementId",&elementId);
+		if (elementType.compare("road")==0)
+			checker+=node->QueryStringAttribute("contactPoint",&contactPoint);
+
+		if (checker!=TIXML_SUCCESS)
+		{
+			cout<<"Error parsing Predecessor attributes"<<endl;
+			return false;
+		}
+		road->SetPredecessor(elementType,elementId,contactPoint);
+		return true;
+
+	}
+	else if (type == 1)
+	{
+		string elementType; 
+		string elementId;
+		string contactPoint="NA";
+
+		int checker=TIXML_SUCCESS;
+		checker+=node->QueryStringAttribute("elementType",&elementType);
+		checker+=node->QueryStringAttribute("elementId",&elementId);
+		if (elementType.compare("road")==0)
+			checker+=node->QueryStringAttribute("contactPoint",&contactPoint);
+
+		if (checker!=TIXML_SUCCESS)
+		{
+			cout<<"Error parsing Successor attributes"<<endl;
+			return false;
+		}
+		road->SetSuccessor(elementType,elementId,contactPoint);
+		return true;
+	}
+
+	else if (type == 2)
+	{
+		string side; 
+		string elementId;
+		string direction;
+
+		int checker=TIXML_SUCCESS;
+		checker+=node->QueryStringAttribute("side",&side);
+		checker+=node->QueryStringAttribute("elementId",&elementId);
+		checker+=node->QueryStringAttribute("direction",&direction);
+
+		if (checker!=TIXML_SUCCESS)
+		{
+			cout<<"Error parsing Neighbor attributes"<<endl;
+			return false;
+		}
+		road->SetNeighbor(side,elementId,direction);
+		return true;
+	}
+
+	return false;
+		
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadRoadType (Road* road, TiXmlElement *node)
+{
+	double s;
+	string type;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryDoubleAttribute("s",&s);
+	checker+=node->QueryStringAttribute("type",&type);
+
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Road Type attributes"<<endl;
+		return false;
+	}
+
+	road->AddRoadType(s,type);
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadPlanView(Road* road, TiXmlElement *node)
+{
+	//Get geometry
+	TiXmlElement* subNode;
+	TiXmlElement* subNodeType;
+	subNode=node->FirstChildElement("geometry");
+	
+	while (subNode)
+	{
+		subNodeType=subNode->FirstChildElement();
+		if (subNodeType->ValueStr().compare("line")==0)
+		{
+			ReadGeometryBlock(road, subNode,0);		//load a straight block
+		}
+		else if (subNodeType->ValueStr().compare("spiral")==0)
+		{
+			ReadGeometryBlock(road, subNode,1);		//load a turn block
+		}
+        else if (subNodeType->ValueStr().compare("arc")==0)
+        {
+            ReadGeometryBlock(road, subNode,2);		//load a turn block
+        }
+		else if (subNodeType->ValueStr().compare("poly3")==0)
+		{
+            ReadGeometryBlock(road, subNode,3);		//load a polynom spline block
+		}       
+        else if (subNodeType->ValueStr().compare("paramPoly3")==0)
+        {
+            ReadGeometryBlock(road, subNode,4);		//load a polynom spline block
+        }
+			
+
+		subNode=subNode->NextSiblingElement("geometry");
+
+	}
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadGeometryBlock (Road* road, TiXmlElement *&node, short int blockType)
+{
+	road->AddGeometryBlock();
+	GeometryBlock* geomBlock=road->GetLastAddedGeometryBlock();
+	switch (blockType)
+	{
+	case 0:
+		ReadGeometry(geomBlock, node, 0);
+		break;
+	case 1:
+		ReadGeometry(geomBlock, node, 1);
+//		node=node->NextSiblingElement("geometry");
+//		ReadGeometry(geomBlock, node, 2);
+//		node=node->NextSiblingElement("geometry");
+//		ReadGeometry(geomBlock, node, 1);
+		break;
+	case 2:
+        ReadGeometry(geomBlock, node, 2);
+		break;
+    case 3:
+        ReadGeometry(geomBlock, node, 3);
+        break;
+    case 4:
+        ReadGeometry(geomBlock, node, 4);
+        break;
+    default:
+        break;
+	}
+
+	return true;
+	
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadGeometry(GeometryBlock* geomBlock, TiXmlElement *node, short int geometryType)
+{
+	double s, x, y, hdg, length;
+	//read the geometry node
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryDoubleAttribute("s",&s);
+	checker+=node->QueryDoubleAttribute("x",&x);
+	checker+=node->QueryDoubleAttribute("y",&y);
+	checker+=node->QueryDoubleAttribute("hdg",&hdg);
+	checker+=node->QueryDoubleAttribute("length",&length);
+
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Geometry attributes"<<endl;
+		return false;
+	}
+
+	TiXmlElement *subNode=node->FirstChildElement();
+
+	//read the type nodes
+	switch ( geometryType )
+      {
+	case 0:		//line
+		geomBlock->AddGeometryLine(s,x,y,hdg,length);
+		break;
+	case 1:		//spiral
+		checker=TIXML_SUCCESS;
+		double curvatureStart, curvatureEnd; 
+		checker+=subNode->QueryDoubleAttribute("curvStart",&curvatureStart);
+		checker+=subNode->QueryDoubleAttribute("curvEnd",&curvatureEnd);
+		if (checker!=TIXML_SUCCESS)
+		{
+			cout<<"Error parsing spiral attributes"<<endl;
+			return false;
+		}
+		geomBlock->AddGeometrySpiral(s,x,y,hdg,length,curvatureStart,curvatureEnd);
+		break;
+	case 2:		//arc
+		checker=TIXML_SUCCESS;
+		double curvature;
+		checker+=subNode->QueryDoubleAttribute("curvature",&curvature);
+		if (checker!=TIXML_SUCCESS)
+		{
+			cout<<"Error parsing arc attributes"<<endl;
+			return false;
+		}
+		geomBlock->AddGeometryArc(s,x,y,hdg,length,curvature);
+		break;
+
+
+	case 3:		//poly3
+		checker=TIXML_SUCCESS;
+		double a,b,c,d;
+		checker+=subNode->QueryDoubleAttribute("a",&a);
+		checker+=subNode->QueryDoubleAttribute("b",&b);
+		checker+=subNode->QueryDoubleAttribute("c",&c);
+		checker+=subNode->QueryDoubleAttribute("d",&d);
+		if (checker!=TIXML_SUCCESS)
+		{
+			cout<<"Error parsing arc attributes"<<endl;
+			return false;
+		}
+
+		geomBlock->AddGeometryPoly3(s,x,y,hdg,length,a,b,c,d);
+		break;
+
+    case 4:		//parampoly3,add by Yuchuli 2019.11.1
+        checker=TIXML_SUCCESS;
+        double ua,ub,uc,ud,va,vb,vc,vd;
+        checker+=subNode->QueryDoubleAttribute("aU",&ua);
+        checker+=subNode->QueryDoubleAttribute("bU",&ub);
+        checker+=subNode->QueryDoubleAttribute("cU",&uc);
+        checker+=subNode->QueryDoubleAttribute("dU",&ud);
+        checker+=subNode->QueryDoubleAttribute("aV",&va);
+        checker+=subNode->QueryDoubleAttribute("bV",&vb);
+        checker+=subNode->QueryDoubleAttribute("cV",&vc);
+        checker+=subNode->QueryDoubleAttribute("dV",&vd);
+        if (checker!=TIXML_SUCCESS)
+        {
+            cout<<"Error parsing arc attributes"<<endl;
+            return false;
+        }
+
+        geomBlock->AddGeometryParamPoly3(s,x,y,hdg,length,ua,ub,uc,ud,va,vb,vc,vd);
+        break;
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadElevationProfile (Road* road, TiXmlElement *node)
+{
+	TiXmlElement* subNode;
+	subNode=node->FirstChildElement("elevation");
+	double s, a, b, c, d;
+	while (subNode)
+	{
+		int checker=TIXML_SUCCESS;
+		checker+=subNode->QueryDoubleAttribute("s",&s);
+		checker+=subNode->QueryDoubleAttribute("a",&a);
+		checker+=subNode->QueryDoubleAttribute("b",&b);
+		checker+=subNode->QueryDoubleAttribute("c",&c);
+		checker+=subNode->QueryDoubleAttribute("d",&d);
+
+		if (checker!=TIXML_SUCCESS)
+		{
+			cout<<"Error parsing Elevation attributes"<<endl;
+			return false;
+		}
+
+		road->AddElevation(s,a,b,c,d);
+
+		subNode=subNode->NextSiblingElement("elevation");
+	}
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLateralProfile (Road* road, TiXmlElement *node)
+{
+	TiXmlElement* subNode;
+	subNode=node->FirstChildElement("superelevation");
+	double s, a, b, c, d;
+	while (subNode)
+	{
+		int checker=TIXML_SUCCESS;
+		checker+=subNode->QueryDoubleAttribute("s",&s);
+		checker+=subNode->QueryDoubleAttribute("a",&a);
+		checker+=subNode->QueryDoubleAttribute("b",&b);
+		checker+=subNode->QueryDoubleAttribute("c",&c);
+		checker+=subNode->QueryDoubleAttribute("d",&d);
+
+		if (checker!=TIXML_SUCCESS)
+		{
+			cout<<"Error parsing Superelevation attributes"<<endl;
+			return false;
+		}
+
+		road->AddSuperElevation(s,a,b,c,d);
+
+		subNode=subNode->NextSiblingElement("superelevation");
+	}
+
+	subNode=node->FirstChildElement("crossfall");
+	string side;
+	while (subNode)
+	{
+		int checker=TIXML_SUCCESS;
+		checker+=subNode->QueryStringAttribute("side",&side);
+		checker+=subNode->QueryDoubleAttribute("s",&s);
+		checker+=subNode->QueryDoubleAttribute("a",&a);
+		checker+=subNode->QueryDoubleAttribute("b",&b);
+		checker+=subNode->QueryDoubleAttribute("c",&c);
+		checker+=subNode->QueryDoubleAttribute("d",&d);
+
+		if (checker!=TIXML_SUCCESS)
+		{
+			cout<<"Error parsing Crossfall attributes"<<endl;
+			return false;
+		}
+
+		road->AddCrossfall(side,s,a,b,c,d);
+
+		subNode=subNode->NextSiblingElement("crossfall");
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLanes (Road* road, TiXmlElement *node)
+{
+	TiXmlElement *subNode = node->FirstChildElement("laneSection");
+	while (subNode)
+	{
+		ReadLaneSections(road, subNode);
+		subNode=subNode->NextSiblingElement("laneSection");
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLaneSections (Road* road, TiXmlElement *node)
+{
+
+	int checker=TIXML_SUCCESS;
+	double s;
+	checker+=node->QueryDoubleAttribute("s",&s);
+
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Lane Section attributes"<<endl;
+		return false;
+	}
+
+	
+	road->AddLaneSection(s);
+	LaneSection* laneSection=road->GetLastAddedLaneSection();
+	TiXmlElement *subNode=node->FirstChildElement("left");
+	if (subNode)
+	{
+		subNode=subNode->FirstChildElement("lane");
+		while(subNode)
+		{
+			
+			ReadLane(laneSection,subNode,1);	//0 for left
+			subNode=subNode->NextSiblingElement("lane");
+		}
+
+	}
+
+	subNode=node->FirstChildElement("center");
+	if (subNode)
+	{
+		subNode=subNode->FirstChildElement("lane");
+		while(subNode)
+		{
+			
+			ReadLane(laneSection,subNode,0);	//1 for center	
+			subNode=subNode->NextSiblingElement("lane");
+		}
+	}
+
+	subNode=node->FirstChildElement("right");
+	if (subNode)
+	{
+		subNode=subNode->FirstChildElement("lane");
+		while(subNode)
+		{
+			
+			ReadLane(laneSection,subNode,-1);	//2 for right	
+			subNode=subNode->NextSiblingElement("lane");
+		}
+	}
+
+
+	//OutputDebugString( "\n") ;
+	for (unsigned int i=0;i<laneSection->GetLaneVector()->size();i++)
+	{
+		int id = static_cast<Lane>(laneSection->GetLaneVector()->at(i)).GetId();
+
+		/*char* buf;
+		buf=new char[5];
+		itoa(id,buf,10);
+
+		OutputDebugString( buf ) ;
+		OutputDebugString( " ") ;*/
+	}
+	//OutputDebugString( "\n") ;
+
+
+	//sort in descending order
+	std::sort(laneSection->GetLaneVector()->begin(),laneSection->GetLaneVector()->end());
+	std::reverse(laneSection->GetLaneVector()->begin(),laneSection->GetLaneVector()->end());
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLane (LaneSection* laneSection, TiXmlElement *node, short int laneType)
+{
+	//Read Lane attributes
+	short int side=laneType;
+	int id;
+	string type; 
+	string level; 
+	bool boolLevel;
+	int predecessor;
+	int successor;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryIntAttribute("id",&id);
+	checker+=node->QueryStringAttribute("type",&type);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Lane attributes"<<endl;
+		return false;
+	}
+	//in case "level" is missing, apply default value
+	checker=node->QueryStringAttribute("level",&level);
+	if (checker!=TIXML_SUCCESS)
+	{	level="false"; }
+
+	//convert level to bool
+
+	if (level.compare("false")==0 || level.compare("0")==0)
+		boolLevel=false;
+	else
+		boolLevel=true;
+
+	//pointer to the lane
+	Lane* lane; 
+	//Depending on the laneType, add it to the appropriate vector and get a pointer to it
+
+	laneSection->AddLane(side,id,type,boolLevel,false);
+	lane=laneSection->GetLastAddedLane();
+
+
+	//Read Link parameters and add them to the lane if available
+	TiXmlElement *subNode=node->FirstChildElement("link");
+	TiXmlElement *subSubNode;
+	if (subNode)
+		subSubNode=subNode->FirstChildElement("predecessor");
+			if (subSubNode)
+			{
+				checker=subSubNode->QueryIntAttribute("id",&predecessor);
+				if (checker==TIXML_SUCCESS)
+					lane->SetPredecessor(predecessor);
+			}
+	if (subNode)
+		subSubNode=subNode->FirstChildElement("successor");
+			if (subSubNode)
+			{
+				checker=subSubNode->QueryIntAttribute("id",&successor);
+				if (checker==TIXML_SUCCESS)
+					lane->SetSuccessor(successor);
+			}
+
+	//Proceed to the Road width
+	subNode=node->FirstChildElement("width");
+	while (subNode)
+	{
+		ReadLaneWidth(lane, subNode);
+		subNode=subNode->NextSiblingElement("width");
+	}
+
+	//Proceed to the Road Mark
+	subNode=node->FirstChildElement("roadMark");
+	while (subNode)
+	{
+		ReadLaneRoadMark(lane, subNode);
+		subNode=subNode->NextSiblingElement("roadMark");
+	}
+
+	//Proceed to the Lane Material
+	subNode=node->FirstChildElement("material");
+	while (subNode)
+	{
+		ReadLaneMaterial(lane, subNode);
+		subNode=subNode->NextSiblingElement("material");
+	}
+
+	//Proceed to the Lane Visibility
+	subNode=node->FirstChildElement("visibility");
+	while (subNode)
+	{
+		ReadLaneVisibility(lane, subNode);
+		subNode=subNode->NextSiblingElement("visibility");
+	}
+
+	//Proceed to the Lane speed
+	subNode=node->FirstChildElement("speed");
+	while (subNode)
+	{
+		ReadLaneSpeed(lane, subNode);
+		subNode=subNode->NextSiblingElement("speed");
+	}
+
+	//Proceed to the Lane access
+	subNode=node->FirstChildElement("access");
+	while (subNode)
+	{
+		ReadLaneAccess(lane, subNode);
+		subNode=subNode->NextSiblingElement("access");
+	}
+
+	//Proceed to the Lane height
+	subNode=node->FirstChildElement("height");
+	while (subNode)
+	{
+		ReadLaneHeight(lane, subNode);
+		subNode=subNode->NextSiblingElement("height");
+	}
+
+	return true;
+}
+//--------------
+
+
+bool OpenDriveXmlParser::ReadLaneWidth(Lane* lane, TiXmlElement *node)
+{
+	double sOffset, a, b, c, d;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryDoubleAttribute("sOffset",&sOffset);
+	checker+=node->QueryDoubleAttribute("a",&a);
+	checker+=node->QueryDoubleAttribute("b",&b);
+	checker+=node->QueryDoubleAttribute("c",&c);
+	checker+=node->QueryDoubleAttribute("d",&d);
+
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Lane Weight attributes"<<endl;
+		return false;
+	}
+
+	lane->AddWidthRecord(sOffset,a,b,c,d);
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLaneRoadMark(Lane* lane, TiXmlElement *node)
+{
+	
+	double sOffset;
+	string type;
+	string weight;
+	string color; 
+	double width;
+	string laneChange;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryDoubleAttribute("sOffset",&sOffset);
+	checker+=node->QueryStringAttribute("type",&type);
+	checker+=node->QueryStringAttribute("weight",&weight);
+	checker+=node->QueryStringAttribute("color",&color);
+	
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Lane Weight attributes"<<endl;
+		return false;
+	}
+
+	checker+=node->QueryDoubleAttribute("width",&width);
+	if (checker!=TIXML_SUCCESS)
+	{	width=0;	}
+
+	checker=node->QueryStringAttribute("laneChange",&laneChange);
+	if (checker!=TIXML_SUCCESS)
+	{	laneChange = "both"; }
+
+	lane->AddRoadMarkRecord(sOffset,type,weight,color,width,laneChange);
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLaneMaterial(Lane* lane, TiXmlElement *node)
+{
+	double sOffset;
+	string surface;
+	double friction;
+	double roughness;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryDoubleAttribute("sOffset",&sOffset);
+	checker+=node->QueryStringAttribute("surface",&surface);
+	checker+=node->QueryDoubleAttribute("friction",&friction);
+	checker+=node->QueryDoubleAttribute("roughness",&roughness);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Lane Weight attributes"<<endl;
+		return false;
+	}
+
+	lane->AddMaterialRecord(sOffset,surface,friction,roughness);
+
+	return true;
+
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLaneVisibility(Lane* lane, TiXmlElement *node)
+{
+	double sOffset;
+	double forward;
+	double back;
+	double left;
+	double right;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryDoubleAttribute("sOffset",&sOffset);
+	checker+=node->QueryDoubleAttribute("forward",&forward);
+	checker+=node->QueryDoubleAttribute("back",&back);
+	checker+=node->QueryDoubleAttribute("left",&left);
+	checker+=node->QueryDoubleAttribute("right",&right);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Lane Weight attributes"<<endl;
+		return false;
+	}
+
+	lane->AddVisibilityRecord(sOffset,forward,back,left,right);
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLaneSpeed(Lane* lane, TiXmlElement *node)
+{	
+	double sOffset;
+	double max;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryDoubleAttribute("sOffset",&sOffset);
+	checker+=node->QueryDoubleAttribute("max",&max);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Lane Weight attributes"<<endl;
+		return false;
+	}
+
+	lane->AddSpeedRecord(sOffset,max);
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLaneAccess(Lane* lane, TiXmlElement *node)
+{
+	double sOffset;
+	string restriction;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryDoubleAttribute("sOffset",&sOffset);
+	checker+=node->QueryStringAttribute("restriction",&restriction);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Lane Weight attributes"<<endl;
+		return false;
+	}
+
+	lane->AddAccessRecord(sOffset,restriction);
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadLaneHeight(Lane* lane, TiXmlElement *node)
+{
+	double sOffset;
+	double inner;
+	double outer;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryDoubleAttribute("sOffset",&sOffset);
+	checker+=node->QueryDoubleAttribute("inner",&inner);
+	checker+=node->QueryDoubleAttribute("outer",&outer);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Lane Weight attributes"<<endl;
+		return false;
+	}
+
+	lane->AddHeightRecord(sOffset,inner,outer);
+
+	return true;
+}
+//--------------
+
+//--------------
+
+bool OpenDriveXmlParser::ReadObjects (Road* road, TiXmlElement *node)
+{
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadSignals (Road* road, TiXmlElement *node)
+{
+
+    TiXmlElement *subNode = node->FirstChildElement("signal");
+    while (subNode)
+    {
+        ReadSignal(road, subNode);
+        subNode=subNode->NextSiblingElement("signal");
+    }
+    return true;
+
+
+}
+
+bool OpenDriveXmlParser::ReadSignal(Road *road, TiXmlElement *node)
+{
+    double s;
+    double t;
+    string id;
+    string name;
+    bool dynamic;
+    string strdynamic;
+    string orientation;
+    double zOffset;
+    string type;
+    string country;
+    string countryRevision;
+    string subtype;
+    double hOffset;
+    double pitch;
+    double roll;
+    double height;
+    double width;
+
+    int checker=TIXML_SUCCESS;
+    checker+=node->QueryDoubleAttribute("s",&s);
+    checker+=node->QueryDoubleAttribute("t",&t);
+    checker+=node->QueryStringAttribute("id",&id);
+    checker+=node->QueryStringAttribute("name",&name);
+    checker+=node->QueryStringAttribute("dynamic",&strdynamic);
+    checker+=node->QueryStringAttribute("orientation",&orientation);
+    checker+=node->QueryDoubleAttribute("zOffset",&zOffset);
+    checker+=node->QueryStringAttribute("type",&type);
+    checker+=node->QueryStringAttribute("country",&country);
+    checker+=node->QueryStringAttribute("countryRevision",&countryRevision);
+    checker+=node->QueryStringAttribute("subtype",&subtype);
+    checker+=node->QueryDoubleAttribute("hOffset",&hOffset);
+    checker+=node->QueryDoubleAttribute("pitch",&pitch);
+    checker+=node->QueryDoubleAttribute("roll",&roll);
+    checker+=node->QueryDoubleAttribute("height",&height);
+    checker+=node->QueryDoubleAttribute("width",&width);
+    if (checker!=TIXML_SUCCESS)
+    {
+        cout<<"Error parsing Lane Signals attributes"<<endl;
+        return false;
+    }
+    if(strncmp(strdynamic.data(),"no",256) == 0)dynamic = false;
+    else dynamic = true;
+    road->AddSignal(s,t,id,name,dynamic,orientation,zOffset,type,country,countryRevision,subtype,hOffset,
+                    pitch,roll,height,width);
+
+    Signal * pSignal = road->GetSignal(road->GetSignalCount() - 1);
+    TiXmlElement * subNode;
+    //Proceed to Signals
+    subNode=node->FirstChildElement("validity");
+    if (subNode)
+    {
+        ReadSignal_laneValidity(pSignal, subNode);
+    }
+    subNode=node->FirstChildElement("positionInertial");
+    if(subNode)
+    {
+        ReadSignal_positionInertial(pSignal,subNode);
+    }
+    return true;
+}
+
+bool OpenDriveXmlParser::ReadSignal_laneValidity(Signal *pSignal, TiXmlElement *node)
+{
+    int fromLane;
+    int toLane;
+    int checker=TIXML_SUCCESS;
+    checker+=node->QueryIntAttribute("fromLane",&fromLane);
+    checker+=node->QueryIntAttribute("toLane",&toLane);
+    if (checker!=TIXML_SUCCESS)
+    {
+        cout<<"Error parsing laneValidity attributes"<<endl;
+        return false;
+    }
+    pSignal->SetlaneValidity(fromLane,toLane);
+    return true;
+}
+
+bool OpenDriveXmlParser::ReadSignal_positionInertial(Signal *pSignal, TiXmlElement *node)
+{
+    double x,y,z,hdg,pitch,roll;
+    int checker=TIXML_SUCCESS;
+    checker+=node->QueryDoubleAttribute("x",&x);
+    checker+=node->QueryDoubleAttribute("y",&y);
+    checker+=node->QueryDoubleAttribute("z",&z);
+    checker+=node->QueryDoubleAttribute("hdg",&hdg);
+    checker+=node->QueryDoubleAttribute("pitch",&pitch);
+    checker+=node->QueryDoubleAttribute("roll",&roll);
+    if (checker!=TIXML_SUCCESS)
+    {
+        cout<<"Error parsing positionInertial attributes"<<endl;
+        return false;
+    }
+    pSignal->SetpositionInertial(x,y,z,hdg,pitch,roll);
+    return true;
+}
+
+
+//--------------
+
+bool OpenDriveXmlParser::ReadSurface (Road* road, TiXmlElement *node)
+{
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlParser::ReadController (TiXmlElement *node)
+{	return true;	}
+//--------------
+
+bool OpenDriveXmlParser::ReadJunction (TiXmlElement *node)
+{	
+	string name;
+	string id;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryStringAttribute("name",&name);
+	checker+=node->QueryStringAttribute("id",&id);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Junction attributes"<<endl;
+		return false;
+	}
+
+	mOpenDrive->AddJunction(name,id);
+	Junction* junction=mOpenDrive->GetLastJunction();
+
+	//Read connection parameters and add them to the lane if available
+	TiXmlElement *subNode=node->FirstChildElement("connection");
+
+	while (subNode)
+	{
+		ReadJunctionConnection(junction, subNode);
+		subNode=subNode->NextSiblingElement("connection");
+	}
+
+
+	//Read connection parameters and add them to the lane if available
+	subNode=node->FirstChildElement("priority");
+
+	while (subNode)
+	{
+		ReadJunctionPriority(junction, subNode);
+		subNode=subNode->NextSiblingElement("priority");
+	}
+
+
+
+	//Read connection parameters and add them to the lane if available
+	subNode=node->FirstChildElement("controller");
+
+	while (subNode)
+	{
+		ReadJunctionController(junction, subNode);
+		subNode=subNode->NextSiblingElement("controller");
+	}
+
+
+	return true;
+	
+}
+//--------------
+bool OpenDriveXmlParser::ReadJunctionConnection (Junction* junction, TiXmlElement *node)
+{
+	string id;
+	string incomingRoad;
+	string connectingRoad;
+	string contactPoint;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryStringAttribute("id",&id);
+	checker+=node->QueryStringAttribute("incomingRoad",&incomingRoad);
+	checker+=node->QueryStringAttribute("connectingRoad",&connectingRoad);
+	checker+=node->QueryStringAttribute("contactPoint",&contactPoint);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Junction Connection attributes"<<endl;
+		return false;
+	}
+
+	junction->AddJunctionConnection(id,incomingRoad,connectingRoad,contactPoint);
+	JunctionConnection* junctionConnetion = junction->GetLastJunctionConnection();
+
+	TiXmlElement *subNode=node->FirstChildElement("laneLink");
+
+	while (subNode)
+	{
+		ReadJunctionConnectionLaneLink(junctionConnetion, subNode);
+		subNode=subNode->NextSiblingElement("laneLink");
+	}
+
+	return true;
+}
+bool OpenDriveXmlParser::ReadJunctionConnectionLaneLink (JunctionConnection* junctionConnection, TiXmlElement *node)
+{
+	int from;
+	int to;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryIntAttribute("from",&from);
+	checker+=node->QueryIntAttribute("to",&to);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Junction Lane Link attributes"<<endl;
+		return false;
+	}
+
+	junctionConnection->AddJunctionLaneLink(from,to);
+	return true;
+}
+
+bool OpenDriveXmlParser::ReadJunctionPriority (Junction* junction, TiXmlElement *node)
+{
+	string high;
+	string low;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryStringAttribute("high",&high);
+	checker+=node->QueryStringAttribute("low",&low);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Junction Priority attributes"<<endl;
+		return false;
+	}
+
+	junction->AddJunctionPriority(high,low);
+	return true;
+}
+bool OpenDriveXmlParser::ReadJunctionController (Junction* junction, TiXmlElement *node)
+{
+	string id;
+	string type;
+
+	int checker=TIXML_SUCCESS;
+	checker+=node->QueryStringAttribute("id",&id);
+	checker+=node->QueryStringAttribute("type",&type);
+	if (checker!=TIXML_SUCCESS)
+	{
+		cout<<"Error parsing Junction Controller attributes"<<endl;
+		return false;
+	}
+
+	junction->AddJunctionController(id,type);
+	return true;
+}
+
+
+//---------------------------------------------------------------------------
+/**
+ * Reads the data from the OpenDrive structure to a file
+ */
+bool OpenDriveXmlParser::ReadFile(std::string fileName)
+{
+	//Read and load File
+	TiXmlDocument doc( fileName );
+	bool loadOkay = doc.LoadFile();
+	if (loadOkay)
+	{
+		TiXmlElement *rootNode=doc.FirstChildElement();
+		//read header
+		int checker=TIXML_SUCCESS;
+		TiXmlElement *node=rootNode->FirstChildElement("header");
+		ReadHeader(node);
+
+		//read roads
+		node=rootNode->FirstChildElement("road");
+		while (node!=0)
+		{
+			ReadRoad(node);
+			node=node->NextSiblingElement("road");
+		}
+
+		//read controllers
+		node=rootNode->FirstChildElement("controller");
+		while (node!=0)
+		{
+			ReadController(node);
+			node=node->NextSiblingElement("controller");
+		}
+
+		//read junctions
+		node=rootNode->FirstChildElement("junction");
+		while (node!=0)
+		{
+			ReadJunction(node);
+			node=node->NextSiblingElement("junction");
+		}
+
+		return true;
+	}
+	
+	//failed to read the file
+	cout<<"Could not read file: "<<fileName<<endl;
+	return false;
+}
+//--------------

+ 89 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDriveXmlParser.h

@@ -0,0 +1,89 @@
+#ifndef OPENDRIVEXMLPARSER_H
+#define OPENDRIVEXMLPARSER_H
+
+#include <vector>
+#include <string>
+
+#include <iostream>
+#include <fstream>
+#include "../TinyXML/tinyxml.h"
+
+#include "OpenDrive.h"
+
+/**
+ * Class used to parse an XML file and fill in the OpenDrive structure
+ *
+ */
+class OpenDriveXmlParser
+{
+private:
+	OpenDrive* mOpenDrive;
+public:
+	/**
+	 * Constructor which saves a reference to OpenDrive structure
+	 */
+	OpenDriveXmlParser (OpenDrive* openDriveObj);
+
+	/**
+	 * Reads the data from the OpenDrive structure to a file
+	 */
+	bool ReadFile(std::string fileName);
+
+
+	/**
+	 * The following methods are used to read the data from the XML file and fill in the the OpenDrive structure
+	 * Methods follow the hierarchical structure and are called automatically when ReadFile is executed
+	 */
+	bool ReadHeader (TiXmlElement *node);
+	bool ReadRoad (TiXmlElement *node);
+	bool ReadRoadLinks (Road* road, TiXmlElement *node);
+	bool ReadRoadLink (Road* road, TiXmlElement *node, short int type);
+	bool ReadRoadType (Road* road, TiXmlElement *node);
+	//--------------
+
+	bool ReadPlanView(Road* road, TiXmlElement *node);
+	bool ReadGeometryBlock (Road* road, TiXmlElement *&node, short int blockType);
+	bool ReadGeometry(GeometryBlock* geomBlock, TiXmlElement *node, short int geometryType);
+	//--------------
+
+	bool ReadElevationProfile (Road* road, TiXmlElement *node);
+	bool ReadLateralProfile (Road* road, TiXmlElement *node);
+	//--------------
+
+	bool ReadLanes (Road* road, TiXmlElement *node);
+	bool ReadLaneSections (Road* road, TiXmlElement *node);
+	bool ReadLane (LaneSection* laneSection, TiXmlElement *node, short int laneType);
+	bool ReadLaneWidth(Lane* lane, TiXmlElement *node);
+	bool ReadLaneRoadMark(Lane* lane, TiXmlElement *node);
+	bool ReadLaneMaterial(Lane* lane, TiXmlElement *node);
+	bool ReadLaneVisibility(Lane* lane, TiXmlElement *node);
+	bool ReadLaneSpeed(Lane* lane, TiXmlElement *node);
+	bool ReadLaneAccess(Lane* lane, TiXmlElement *node);
+	bool ReadLaneHeight(Lane* lane, TiXmlElement *node);
+	//--------------
+
+	bool ReadObjects (Road* road, TiXmlElement *node);
+	bool ReadSignals (Road* road, TiXmlElement *node);
+    bool ReadSignal(Road * road,TiXmlElement * node);
+    bool ReadSignal_positionInertial(Signal * pSignal, TiXmlElement *node);
+    bool ReadSignal_laneValidity(Signal * pSignal,TiXmlElement * node);
+	//--------------
+
+	bool ReadSurface (Road* road, TiXmlElement *node);
+	//--------------
+
+	bool ReadController (TiXmlElement *node);
+	//--------------
+
+	bool ReadJunction (TiXmlElement *node);
+	bool ReadJunctionConnection (Junction* junction, TiXmlElement *node);
+	bool ReadJunctionConnectionLaneLink (JunctionConnection* junctionConnection, TiXmlElement *node);
+	//--------------
+
+	bool ReadJunctionPriority (Junction* junction, TiXmlElement *node);
+	bool ReadJunctionController (Junction* junction, TiXmlElement *node);
+	//--------------
+};
+
+
+#endif

+ 1175 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDriveXmlWriter.cpp

@@ -0,0 +1,1175 @@
+#include "OpenDriveXmlWriter.h"
+#include <iostream>
+#include <algorithm>
+//#include "windows.h"
+
+using std::cout;
+using std::endl;
+
+/**
+ * Constructor which saves a reference to OpenDrive structure
+ */
+OpenDriveXmlWriter::OpenDriveXmlWriter (OpenDrive* openDriveObj)
+{	
+	mOpenDrive=openDriveObj;	
+}
+
+/**
+ * The following methods are used to create the XML representation of the OpenDrive structure
+ * Methods follow the same hierarchical structure and are called automatically when WriteFile
+ * is executed
+ */
+bool OpenDriveXmlWriter::WriteHeader(TiXmlElement *node)
+{
+	//Write the Header
+	unsigned short int revMajor;
+	unsigned short int revMinor;
+	string name;
+	float version;
+	string date;
+	double north;
+	double south;
+	double east;
+	double west;
+    double lat0;
+    double lon0;
+    double hdg0;
+
+	Header *lHeader = mOpenDrive->GetHeader();
+    lHeader->GetAllParams(revMajor, revMinor, name, version, date, north, south, east, west,lat0,lon0,hdg0);
+
+	TiXmlElement *nodeHeader = new TiXmlElement("header");
+	node->LinkEndChild(nodeHeader);
+
+	nodeHeader->SetAttribute("revMajor",revMajor);
+	nodeHeader->SetAttribute("revMinor",revMinor);
+	nodeHeader->SetAttribute("name",name);
+	nodeHeader->SetDoubleAttribute("version",version);
+	nodeHeader->SetAttribute("date",date);
+
+	std::stringstream snorth;
+	snorth << setprecision(16) << setiosflags (ios_base::scientific) << north;
+	nodeHeader->SetAttribute("north",snorth.str());
+
+	std::stringstream ssouth;
+	ssouth << setprecision(16) << setiosflags (ios_base::scientific) << south;
+	nodeHeader->SetAttribute("south",ssouth.str());
+
+	std::stringstream seast;
+	seast << setprecision(16) << setiosflags (ios_base::scientific) << east;
+	nodeHeader->SetAttribute("east",seast.str());
+
+	std::stringstream swest;
+	swest << setprecision(16) << setiosflags (ios_base::scientific) << west;
+	nodeHeader->SetAttribute("west",swest.str());
+
+    std::stringstream slat0;
+    slat0 << setprecision(16) << setiosflags (ios_base::scientific) << lat0;
+    nodeHeader->SetAttribute("lat0",slat0.str());
+
+    std::stringstream slon0;
+    slon0 << setprecision(16) << setiosflags (ios_base::scientific) << lon0;
+    nodeHeader->SetAttribute("lon0",slon0.str());
+
+    std::stringstream shdg0;
+    shdg0 << setprecision(16) << setiosflags (ios_base::scientific) << hdg0;
+    nodeHeader->SetAttribute("hdg0",shdg0.str());
+
+
+	return true;
+}
+//--------------
+bool OpenDriveXmlWriter::WriteRoad(TiXmlElement *node, Road *road)
+{
+	//Write road attributes
+	string name;
+	double length;
+	string id;
+	string junction;
+
+	name = road->GetRoadName();
+	length = road->GetRoadLength();
+	id = road->GetRoadId();
+	junction = road->GetRoadJunction();
+
+	TiXmlElement *nodeRoad = new TiXmlElement("road");
+	node->LinkEndChild(nodeRoad);
+
+	nodeRoad->SetAttribute("name",name);
+	std::stringstream slength;
+	slength << setprecision(16) << setiosflags (ios_base::scientific) << length;
+	nodeRoad->SetAttribute("length",slength.str());
+	nodeRoad->SetAttribute("id",id);
+	nodeRoad->SetAttribute("junction",junction);
+
+	//Fill in
+
+	//Links
+	WriteRoadLinks (nodeRoad,road);
+
+	//Types
+	WriteRoadType(nodeRoad, road);
+
+	//PlanView
+	WritePlanView(nodeRoad, road);
+
+	//ElevationProfile
+	WriteElevationProfile(nodeRoad, road);
+
+	//LateralProfile
+	WriteLateralProfile(nodeRoad, road);
+
+	//Proceed to Lanes
+	WriteLanes(nodeRoad, road);
+
+
+	//Proceed to Objects
+	WriteObjects(nodeRoad, road);
+
+	//Proceed to Signals
+	WriteSignals(nodeRoad, road);
+
+	/*
+	//Proceed to Surface
+	subNode=node->FirstChildElement("surface");
+	if (subNode)
+	{
+	WriteSurface(road, subNode);
+	}
+	*/
+
+	return true;
+}
+//--------------
+
+bool  OpenDriveXmlWriter::WriteRoadLinks (TiXmlElement *node, Road* road)
+{
+	TiXmlElement* nodeLink = new TiXmlElement("link");
+	node->LinkEndChild(nodeLink);
+
+	RoadLink *lPredecessor = road->GetPredecessor();
+	if(lPredecessor)
+	{
+		TiXmlElement* nodeLinkPredecessor = new TiXmlElement("predecessor");
+		nodeLink->LinkEndChild(nodeLinkPredecessor);
+		nodeLinkPredecessor->SetAttribute("elementType", lPredecessor->GetElementType());
+		nodeLinkPredecessor->SetAttribute("elementId", lPredecessor->GetElementId());
+		nodeLinkPredecessor->SetAttribute("contactPoint", lPredecessor->GetContactPoint());
+	}
+	RoadLink *lSuccessor = road->GetSuccessor();
+	if(lSuccessor)
+	{
+		TiXmlElement* nodeLinkSuccessor = new TiXmlElement("successor");
+		nodeLink->LinkEndChild(nodeLinkSuccessor);
+		nodeLinkSuccessor->SetAttribute("elementType", lSuccessor->GetElementType());
+		nodeLinkSuccessor->SetAttribute("elementId", lSuccessor->GetElementId());
+		nodeLinkSuccessor->SetAttribute("contactPoint", lSuccessor->GetContactPoint());
+	}
+	RoadNeighbor *lNeighbor1 = road->GetNeighbor1();
+	if(lNeighbor1)
+	{
+		TiXmlElement* nodeLinkNeighbor1 = new TiXmlElement("neighbor");
+		nodeLink->LinkEndChild(nodeLinkNeighbor1);
+		nodeLinkNeighbor1->SetAttribute("side", lNeighbor1->GetSide());
+		nodeLinkNeighbor1->SetAttribute("elementId", lNeighbor1->GetElementId());
+		nodeLinkNeighbor1->SetAttribute("direction", lNeighbor1->GetDirection());
+	}
+	RoadNeighbor *lNeighbor2 = road->GetNeighbor2();
+	if(lNeighbor2)
+	{
+		TiXmlElement* nodeLinkNeighbor2 = new TiXmlElement("neighbor");
+		nodeLink->LinkEndChild(nodeLinkNeighbor2);
+		nodeLinkNeighbor2->SetAttribute("side", lNeighbor2->GetSide());
+		nodeLinkNeighbor2->SetAttribute("elementId", lNeighbor2->GetElementId());
+		nodeLinkNeighbor2->SetAttribute("direction", lNeighbor2->GetDirection());
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteRoadType (TiXmlElement *node, Road* road)
+{
+	double s;
+	string type;
+
+	unsigned int roadTypeCount = road->GetRoadTypeCount();
+	for(unsigned int i=0; i<roadTypeCount; i++)
+	{
+		RoadType *lRoadType = road->GetRoadType(i);
+
+		s=lRoadType->GetS();
+		type=lRoadType->GetType();
+
+		TiXmlElement *nodeRoadType = new TiXmlElement("type");
+		node->LinkEndChild(nodeRoadType);
+
+		std::stringstream ss;
+		ss << setprecision(16) << setiosflags (ios_base::scientific) << s;
+		nodeRoadType->SetAttribute("s",ss.str());
+		nodeRoadType->SetAttribute("type",type);
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WritePlanView(TiXmlElement *node, Road *road)
+{
+	TiXmlElement* nodePlanView = new TiXmlElement("planView");
+	node->LinkEndChild(nodePlanView);
+
+	unsigned int geometryCount = road->GetGeometryBlockCount();
+	for(unsigned int i=0; i<geometryCount; i++)
+	{
+		WriteGeometryBlock(nodePlanView, road->GetGeometryBlock(i));
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteGeometryBlock (TiXmlElement *node, GeometryBlock* geometryBlock)
+{
+
+	if(geometryBlock->CheckIfLine())
+	{
+
+        WriteGeometry(node, geometryBlock->GetGeometryAt(0), geometryBlock->GetGeometryAt(0)->GetGeomType());
+	}
+	else
+	{
+		WriteGeometry(node, geometryBlock->GetGeometryAt(0), 1);
+		WriteGeometry(node, geometryBlock->GetGeometryAt(1), 2);
+		WriteGeometry(node, geometryBlock->GetGeometryAt(2), 1);
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteGeometry(TiXmlElement *node, RoadGeometry* roadGeometry,  short int geometryType)
+{
+	double s, x, y, hdg, length;
+
+	s=roadGeometry->GetS();
+	x=roadGeometry->GetX();
+	y=roadGeometry->GetY();
+	hdg=roadGeometry->GetHdg();
+	length=roadGeometry->GetLength();
+
+	//Write the geometry node
+	TiXmlElement *nodeGeometry = new TiXmlElement("geometry");
+	node->LinkEndChild(nodeGeometry);
+
+	std::stringstream ss;
+	ss << setprecision(16) << setiosflags (ios_base::scientific) << s;
+	nodeGeometry->SetAttribute("s",ss.str());
+
+	std::stringstream sx;
+	sx << setprecision(16) << setiosflags (ios_base::scientific) << x;
+	nodeGeometry->SetAttribute("x",sx.str());
+
+	std::stringstream sy;
+	sy << setprecision(16) << setiosflags (ios_base::scientific) << y;
+	nodeGeometry->SetAttribute("y",sy.str());
+
+	std::stringstream shdg;
+	shdg << setprecision(16) << setiosflags (ios_base::scientific) << hdg;
+	nodeGeometry->SetAttribute("hdg",shdg.str());
+
+	std::stringstream slength;
+	slength << setprecision(16) << setiosflags (ios_base::scientific) << length;
+	nodeGeometry->SetAttribute("length",slength.str());
+
+
+	//Write the type nodes
+	switch ( geometryType )
+	{
+	case 0:	
+		{
+			//line
+			TiXmlElement *nodeLine = new TiXmlElement("line");
+			nodeGeometry->LinkEndChild(nodeLine);
+			break;
+		}
+	case 1:
+		{		
+			//spiral
+			double curvatureStart, curvatureEnd; 
+			GeometrySpiral *lSpiral=static_cast<GeometrySpiral*>(roadGeometry);
+			curvatureStart=lSpiral->GetCurvatureStart();
+			curvatureEnd=lSpiral->GetCurvatureEnd();
+
+			TiXmlElement *nodeSpiral = new TiXmlElement("spiral");
+			nodeGeometry->LinkEndChild(nodeSpiral);
+
+
+			std::stringstream scurvatureStart;
+			scurvatureStart << setprecision(16) << setiosflags (ios_base::scientific) << curvatureStart;
+			nodeSpiral->SetAttribute("curvStart",scurvatureStart.str());
+
+			std::stringstream scurvatureEnd;
+			scurvatureEnd << setprecision(16) << setiosflags (ios_base::scientific) << curvatureEnd;
+			nodeSpiral->SetAttribute("curvEnd",scurvatureEnd.str());
+			break;
+		}
+	case 2:
+		{		
+			//arc
+			double curvature;
+			GeometryArc *lArc=static_cast<GeometryArc*>(roadGeometry);
+			curvature=lArc->GetCurvature();
+
+			TiXmlElement *nodeArc = new TiXmlElement("arc");
+			nodeGeometry->LinkEndChild(nodeArc);
+
+			std::stringstream scurvature;
+			scurvature << setprecision(16) << setiosflags (ios_base::scientific) << curvature;
+			nodeArc->SetAttribute("curvature",scurvature.str());
+			break;
+		}
+	case 3:
+		{		
+			//poly3
+			break;
+		}
+
+    case 4:
+        {   //paramPoly3 add by Yu Chuli. 2019.11.1
+            double ua,ub,uc,ud,va,vb,vc,vd;
+            GeometryParamPoly3 *lpp3=static_cast<GeometryParamPoly3 *>(roadGeometry);
+
+            ua = lpp3->GetuA();
+            ub = lpp3->GetuB();
+            uc = lpp3->GetuC();
+            ud = lpp3->GetuD();
+            va = lpp3->GetvA();
+            vb = lpp3->GetvB();
+            vc = lpp3->GetvC();
+            vd = lpp3->GetvD();
+
+            TiXmlElement *nodeParamPoly3 = new TiXmlElement("paramPoly3");
+            nodeGeometry->LinkEndChild(nodeParamPoly3);
+
+            std::stringstream sua;
+            sua << setprecision(16) << setiosflags (ios_base::scientific) << ua;
+            nodeParamPoly3->SetAttribute("aU",sua.str());
+
+            std::stringstream sub;
+            sub << setprecision(16) << setiosflags (ios_base::scientific) << ub;
+            nodeParamPoly3->SetAttribute("bU",sub.str());
+
+            std::stringstream suc;
+            suc << setprecision(16) << setiosflags (ios_base::scientific) << uc;
+            nodeParamPoly3->SetAttribute("cU",suc.str());
+
+            std::stringstream sud;
+            sud << setprecision(16) << setiosflags (ios_base::scientific) << ud;
+            nodeParamPoly3->SetAttribute("dU",sud.str());
+
+            std::stringstream sva;
+            sva << setprecision(16) << setiosflags (ios_base::scientific) << va;
+            nodeParamPoly3->SetAttribute("aV",sva.str());
+
+            std::stringstream svb;
+            svb << setprecision(16) << setiosflags (ios_base::scientific) << vb;
+            nodeParamPoly3->SetAttribute("bV",svb.str());
+
+            std::stringstream svc;
+            svc << setprecision(16) << setiosflags (ios_base::scientific) << vc;
+            nodeParamPoly3->SetAttribute("cV",svc.str());
+
+            std::stringstream svd;
+            svd << setprecision(16) << setiosflags (ios_base::scientific) << vd;
+            nodeParamPoly3->SetAttribute("dV",svd.str());
+            break;
+
+        }
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteElevationProfile (TiXmlElement *node, Road* road)
+{
+	double s, a, b, c, d;
+
+	TiXmlElement* nodeElevationProfile = new TiXmlElement("elevationProfile");
+	node->LinkEndChild(nodeElevationProfile);
+
+	unsigned int lElevationCount = road->GetElevationCount();
+	for(unsigned int i=0; i<lElevationCount; i++)
+	{
+		Elevation *lElevation = road->GetElevation(i);
+		s=lElevation->GetS();
+		a=lElevation->GetA();
+		b=lElevation->GetB();
+		c=lElevation->GetC();
+		d=lElevation->GetD();
+
+		TiXmlElement *nodeElevation = new TiXmlElement("elevation");
+		nodeElevationProfile->LinkEndChild(nodeElevation);
+
+		std::stringstream ss;
+		ss << setprecision(16) << setiosflags (ios_base::scientific) << s;
+		nodeElevation->SetAttribute("s",ss.str());
+
+		std::stringstream sa;
+		sa << setprecision(16) << setiosflags (ios_base::scientific) << a;
+		nodeElevation->SetAttribute("a",sa.str());
+
+		std::stringstream sb;
+		sb << setprecision(16) << setiosflags (ios_base::scientific) << b;
+		nodeElevation->SetAttribute("b",sb.str());
+
+		std::stringstream sc;
+		sc << setprecision(16) << setiosflags (ios_base::scientific) << c;
+		nodeElevation->SetAttribute("c",sc.str());
+
+		std::stringstream sd;
+		sd << setprecision(16) << setiosflags (ios_base::scientific) << d;
+		nodeElevation->SetAttribute("d",sd.str());
+	}
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLateralProfile (TiXmlElement *node, Road* road)
+{
+	double s, a, b, c, d;
+	string side;
+
+	TiXmlElement* nodeLateralProfile = new TiXmlElement("lateralProfile");
+	node->LinkEndChild(nodeLateralProfile);
+
+	unsigned int lSuperElevationCount = road->GetSuperElevationCount();
+	for(unsigned int i=0; i<lSuperElevationCount; i++)
+	{
+		SuperElevation *lSuperElevation = road->GetSuperElevation(i);
+		s=lSuperElevation->GetS();
+		a=lSuperElevation->GetA();
+		b=lSuperElevation->GetB();
+		c=lSuperElevation->GetC();
+		d=lSuperElevation->GetD();
+
+		TiXmlElement *nodeSuperElevation = new TiXmlElement("superelevation");
+		nodeLateralProfile->LinkEndChild(nodeSuperElevation);
+
+		std::stringstream ss;
+		ss << setprecision(16) << setiosflags (ios_base::scientific) << s;
+		nodeSuperElevation->SetAttribute("s",ss.str());
+
+		std::stringstream sa;
+		sa << setprecision(16) << setiosflags (ios_base::scientific) << a;
+		nodeSuperElevation->SetAttribute("a",sa.str());
+
+		std::stringstream sb;
+		sb << setprecision(16) << setiosflags (ios_base::scientific) << b;
+		nodeSuperElevation->SetAttribute("b",sb.str());
+
+		std::stringstream sc;
+		sc << setprecision(16) << setiosflags (ios_base::scientific) << c;
+		nodeSuperElevation->SetAttribute("c",sc.str());
+
+		std::stringstream sd;
+		sd << setprecision(16) << setiosflags (ios_base::scientific) << d;
+		nodeSuperElevation->SetAttribute("d",sd.str());
+	}
+
+
+	unsigned int lCrossfallCount = road->GetCrossfallCount();
+	for(unsigned int i=0; i<lCrossfallCount; i++)
+	{
+		Crossfall *lCrossfall = road->GetCrossfall(i);
+		s=lCrossfall->GetS();
+		a=lCrossfall->GetA();
+		b=lCrossfall->GetB();
+		c=lCrossfall->GetC();
+		d=lCrossfall->GetD();
+		side=lCrossfall->GetSide();
+
+		TiXmlElement *nodeCrossfall = new TiXmlElement("crossfall");
+		nodeLateralProfile->LinkEndChild(nodeCrossfall);
+
+		nodeCrossfall->SetAttribute("side",side);
+
+		std::stringstream ss;
+		ss << setprecision(16) << setiosflags (ios_base::scientific) << s;
+		nodeCrossfall->SetAttribute("s",ss.str());
+
+		std::stringstream sa;
+		sa << setprecision(16) << setiosflags (ios_base::scientific) << a;
+		nodeCrossfall->SetAttribute("a",sa.str());
+
+		std::stringstream sb;
+		sb << setprecision(16) << setiosflags (ios_base::scientific) << b;
+		nodeCrossfall->SetAttribute("b",sb.str());
+
+		std::stringstream sc;
+		sc << setprecision(16) << setiosflags (ios_base::scientific) << c;
+		nodeCrossfall->SetAttribute("c",sc.str());
+
+		std::stringstream sd;
+		sd << setprecision(16) << setiosflags (ios_base::scientific) << d;
+		nodeCrossfall->SetAttribute("d",sd.str());
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLanes (TiXmlElement *node, Road* road)
+{
+	TiXmlElement* nodeLanes = new TiXmlElement("lanes");
+	node->LinkEndChild(nodeLanes);
+
+	unsigned int lLaneSectionCount = road->GetLaneSectionCount();
+	for(unsigned int i=0; i<lLaneSectionCount; i++)
+	{
+		WriteLaneSections(nodeLanes, road->GetLaneSection(i));
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLaneSections (TiXmlElement *node, LaneSection *laneSection)
+{
+	double s;
+	s=laneSection->GetS();
+
+	TiXmlElement* nodeLaneSection = new TiXmlElement("laneSection");
+	node->LinkEndChild(nodeLaneSection);
+
+	std::stringstream ss;
+	ss << setprecision(16) << setiosflags (ios_base::scientific) << s;
+	nodeLaneSection->SetAttribute("s",ss.str());
+
+	//Fill in lane section
+	short int curType=1;
+	TiXmlElement* nodeLanesLeft=NULL;
+	if(laneSection->GetLeftLaneCount()>0)
+	{
+		nodeLanesLeft = new TiXmlElement("left");
+		nodeLaneSection->LinkEndChild(nodeLanesLeft);
+	}
+	
+	TiXmlElement* nodeLanesCenter = new TiXmlElement("center");
+	nodeLaneSection->LinkEndChild(nodeLanesCenter);
+
+	TiXmlElement* nodeLanesRight=NULL;
+	if(laneSection->GetRightLaneCount()>0)
+	{
+		nodeLanesRight = new TiXmlElement("right");
+		nodeLaneSection->LinkEndChild(nodeLanesRight);
+	}
+
+
+	unsigned int lLaneCount = laneSection->GetLaneCount();
+	for(unsigned int i=0; i<lLaneCount; i++)
+	{
+		Lane *lLane = laneSection->GetLane(i);
+		short int lType=lLane->GetSide();
+		if(lType>0 && nodeLanesLeft!=NULL)
+		{
+			WriteLane(nodeLanesLeft, lLane);
+		}
+		else if(lType==0)
+		{
+			WriteLane(nodeLanesCenter, lLane);
+		}
+		else if(lType<0 && nodeLanesRight!=NULL)
+		{
+			WriteLane(nodeLanesRight, lLane);
+		}
+	}
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLane (TiXmlElement *node, Lane* lane)
+{
+	//Write Lane attributes
+	int id;
+	string type; 
+	string level; 
+	bool boolLevel;
+	int predecessor;
+	int successor;
+
+	id=lane->GetId();
+	type=lane->GetType();
+	boolLevel=lane->GetLevel();
+	if(boolLevel) level="true";
+	else level="false";
+	predecessor=lane->GetPredecessor();
+	successor=lane->GetSuccessor();
+	
+	TiXmlElement* nodeLane = new TiXmlElement("lane");
+	node->LinkEndChild(nodeLane);
+
+	//Attributes
+	nodeLane->SetAttribute("id",id);
+	nodeLane->SetAttribute("type",type);
+	nodeLane->SetAttribute("level",level);
+	
+	//Links
+	TiXmlElement* nodeLaneLink = new TiXmlElement("link");
+	nodeLane->LinkEndChild(nodeLaneLink);
+	if(lane->IsPredecessorSet())
+	{
+		TiXmlElement* nodeLaneLinkPredecessor = new TiXmlElement("predecessor");
+		nodeLaneLink->LinkEndChild(nodeLaneLinkPredecessor);
+		nodeLaneLinkPredecessor->SetAttribute("id",predecessor);
+	}
+	if(lane->IsSuccessorSet())
+	{
+		TiXmlElement* nodeLaneLinkSuccessor = new TiXmlElement("successor");
+		nodeLaneLink->LinkEndChild(nodeLaneLinkSuccessor);
+		nodeLaneLinkSuccessor->SetAttribute("id",successor);
+	}
+
+	//Lane Width
+	unsigned int lLaneWidthCount = lane->GetLaneWidthCount();
+	for(unsigned int i=0; i<lLaneWidthCount; i++)
+	{
+		WriteLaneWidth(nodeLane, lane->GetLaneWidth(i));
+	}
+
+	//Lane Road Mark
+	unsigned int lLaneRoadMark = lane->GetLaneRoadMarkCount();
+	for(unsigned int i=0; i<lLaneRoadMark; i++)
+	{
+		WriteLaneRoadMark(nodeLane, lane->GetLaneRoadMark(i));
+	}
+
+	//Lane Material
+	unsigned int lLaneMaterial = lane->GetLaneMaterialCount();
+	for(unsigned int i=0; i<lLaneMaterial; i++)
+	{
+		WriteLaneMaterial(nodeLane, lane->GetLaneMaterial(i));
+	}
+
+	//Lane Visibility
+	unsigned int lLaneVisibility = lane->GetLaneVisibilityCount();
+	for(unsigned int i=0; i<lLaneVisibility; i++)
+	{
+		WriteLaneVisibility(nodeLane, lane->GetLaneVisibility(i));
+	}
+
+	//Lane speed
+	unsigned int lLaneSpeed = lane->GetLaneSpeedCount();
+	for(unsigned int i=0; i<lLaneSpeed; i++)
+	{
+		WriteLaneSpeed(nodeLane, lane->GetLaneSpeed(i));
+	}
+
+	//Lane access
+	unsigned int lLaneAccess = lane->GetLaneAccessCount();
+	for(unsigned int i=0; i<lLaneAccess; i++)
+	{
+		WriteLaneAccess(nodeLane, lane->GetLaneAccess(i));
+	}
+
+	//Lane height
+	unsigned int lLaneHeight = lane->GetLaneHeightCount();
+	for(unsigned int i=0; i<lLaneHeight; i++)
+	{
+		WriteLaneHeight(nodeLane, lane->GetLaneHeight(i));
+	}
+
+	return true;
+}
+//--------------
+
+
+bool OpenDriveXmlWriter::WriteLaneWidth(TiXmlElement *node, LaneWidth* laneWidth)
+{
+	double sOffset, a, b, c, d;
+
+	sOffset=laneWidth->GetS();
+	a=laneWidth->GetA();
+	b=laneWidth->GetB();
+	c=laneWidth->GetC();
+	d=laneWidth->GetD();
+
+	TiXmlElement* nodeLaneWidth = new TiXmlElement("width");
+	node->LinkEndChild(nodeLaneWidth);
+
+	std::stringstream ssOffset;
+	ssOffset << setprecision(16) << setiosflags (ios_base::scientific) << sOffset;
+	nodeLaneWidth->SetAttribute("sOffset",ssOffset.str());
+
+	std::stringstream sa;
+	sa << setprecision(16) << setiosflags (ios_base::scientific) << a;
+	nodeLaneWidth->SetAttribute("a",sa.str());
+
+	std::stringstream sb;
+	sb << setprecision(16) << setiosflags (ios_base::scientific) << b;
+	nodeLaneWidth->SetAttribute("b",sb.str());
+
+	std::stringstream sc;
+	sc << setprecision(16) << setiosflags (ios_base::scientific) << c;
+	nodeLaneWidth->SetAttribute("c",sc.str());
+
+	std::stringstream sd;
+	sd << setprecision(16) << setiosflags (ios_base::scientific) << d;
+	nodeLaneWidth->SetAttribute("d",sd.str());
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLaneRoadMark(TiXmlElement *node, LaneRoadMark* laneRoadMark)
+{
+
+	double sOffset;
+	string type;
+	string weight;
+	string color; 
+	double width;
+	string laneChange;
+
+	sOffset=laneRoadMark->GetS();
+	type=laneRoadMark->GetType();
+	weight=laneRoadMark->GetWeight();
+	color=laneRoadMark->GetColor();
+	width=laneRoadMark->GetWidth();
+	laneChange=laneRoadMark->GetLaneChange();
+
+	TiXmlElement* nodeLaneRoadMark = new TiXmlElement("roadMark");
+	node->LinkEndChild(nodeLaneRoadMark);
+
+	std::stringstream ssOffset;
+	ssOffset << setprecision(16) << setiosflags (ios_base::scientific) << sOffset;
+	nodeLaneRoadMark->SetAttribute("sOffset",ssOffset.str());
+	nodeLaneRoadMark->SetAttribute("type",type);
+	nodeLaneRoadMark->SetAttribute("weight",weight);
+	nodeLaneRoadMark->SetAttribute("color",color);
+
+	std::stringstream swidth;
+	swidth << setprecision(16) << setiosflags (ios_base::scientific) << width;
+	nodeLaneRoadMark->SetAttribute("width",swidth.str());
+	nodeLaneRoadMark->SetAttribute("laneChange",laneChange);
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLaneMaterial(TiXmlElement *node, LaneMaterial* laneMaterial)
+{
+	double sOffset;
+	string surface;
+	double friction;
+	double roughness;
+
+	sOffset=laneMaterial->GetS();
+	surface=laneMaterial->GetSurface();
+	friction=laneMaterial->GetFriction();
+	roughness=laneMaterial->GetRoughness();
+
+	TiXmlElement* nodeLaneMaterial = new TiXmlElement("material");
+	node->LinkEndChild(nodeLaneMaterial);
+
+	std::stringstream ssOffset;
+	ssOffset << setprecision(16) << setiosflags (ios_base::scientific) << sOffset;
+	nodeLaneMaterial->SetAttribute("sOffset",ssOffset.str());
+	nodeLaneMaterial->SetAttribute("surface",surface);
+
+	std::stringstream sfriction;
+	sfriction << setprecision(16) << setiosflags (ios_base::scientific) << friction;
+	nodeLaneMaterial->SetAttribute("friction",sfriction.str());
+
+	std::stringstream sroughness;
+	sroughness << setprecision(16) << setiosflags (ios_base::scientific) << roughness;
+	nodeLaneMaterial->SetAttribute("roughness",sroughness.str());
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLaneVisibility(TiXmlElement *node, LaneVisibility* laneVisibility)
+{
+	double sOffset;
+	double forward;
+	double back;
+	double left;
+	double right;
+
+	sOffset=laneVisibility->GetS();
+	forward=laneVisibility->GetForward();
+	back=laneVisibility->GetBack();
+	left=laneVisibility->GetLeft();
+	right=laneVisibility->GetRight();
+
+	TiXmlElement* nodeLaneVisibility = new TiXmlElement("visibility");
+	node->LinkEndChild(nodeLaneVisibility);
+
+	std::stringstream ssOffset;
+	ssOffset << setprecision(16) << setiosflags (ios_base::scientific) << sOffset;
+	nodeLaneVisibility->SetAttribute("sOffset",ssOffset.str());
+
+	std::stringstream sforward;
+	sforward << setprecision(16) << setiosflags (ios_base::scientific) << forward;
+	nodeLaneVisibility->SetAttribute("forward",sforward.str());
+
+	std::stringstream sback;
+	sback << setprecision(16) << setiosflags (ios_base::scientific) << back;
+	nodeLaneVisibility->SetAttribute("back",sback.str());
+
+	std::stringstream sleft;
+	sleft << setprecision(16) << setiosflags (ios_base::scientific) << left;
+	nodeLaneVisibility->SetAttribute("left",sleft.str());
+
+	std::stringstream sright;
+	sright << setprecision(16) << setiosflags (ios_base::scientific) << right;
+	nodeLaneVisibility->SetAttribute("right",sright.str());
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLaneSpeed(TiXmlElement *node, LaneSpeed* laneSpeed)
+{	
+	double sOffset;
+	double max;
+
+	sOffset=laneSpeed->GetS();
+	max=laneSpeed->GetMax();
+
+	TiXmlElement* nodeLaneSpeed = new TiXmlElement("speed");
+	node->LinkEndChild(nodeLaneSpeed);
+
+	std::stringstream ssOffset;
+	ssOffset << setprecision(16) << setiosflags (ios_base::scientific) << sOffset;
+	nodeLaneSpeed->SetAttribute("sOffset",ssOffset.str());
+
+	std::stringstream smax;
+	smax << setprecision(16) << setiosflags (ios_base::scientific) << max;
+	nodeLaneSpeed->SetAttribute("max",smax.str());
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLaneAccess(TiXmlElement *node, LaneAccess* laneAccess)
+{
+	double sOffset;
+	string restriction;
+
+	sOffset=laneAccess->GetS();
+	restriction=laneAccess->GetRestriction();
+
+	TiXmlElement* nodeLaneAccess = new TiXmlElement("access");
+	node->LinkEndChild(nodeLaneAccess);
+
+	std::stringstream ssOffset;
+	ssOffset << setprecision(16) << setiosflags (ios_base::scientific) << sOffset;
+	nodeLaneAccess->SetAttribute("sOffset",ssOffset.str());
+	nodeLaneAccess->SetAttribute("restriction",restriction);
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteLaneHeight(TiXmlElement *node, LaneHeight* laneHeight)
+{
+	double sOffset;
+	double inner;
+	double outer;
+
+	sOffset=laneHeight->GetS();
+	inner=laneHeight->GetInner();
+	outer=laneHeight->GetOuter();
+
+	TiXmlElement* nodeLaneHeight = new TiXmlElement("height");
+	node->LinkEndChild(nodeLaneHeight);
+
+	std::stringstream ssOffset;
+	ssOffset << setprecision(16) << setiosflags (ios_base::scientific) << sOffset;
+	nodeLaneHeight->SetAttribute("sOffset",ssOffset.str());
+
+	std::stringstream sinner;
+	sinner << setprecision(16) << setiosflags (ios_base::scientific) << inner;
+	nodeLaneHeight->SetAttribute("inner",sinner.str());
+
+	std::stringstream souter;
+	souter << setprecision(16) << setiosflags (ios_base::scientific) << outer;
+	nodeLaneHeight->SetAttribute("outer",souter.str());
+	
+	return true;
+}
+//--------------
+
+//--------------
+
+bool OpenDriveXmlWriter::WriteObjects (TiXmlElement *node, Road* road)
+{
+	TiXmlElement* nodeObjects = new TiXmlElement("objects");
+	node->LinkEndChild(nodeObjects);
+
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteSignals (TiXmlElement *node, Road* road)
+{
+	TiXmlElement* nodeSignals = new TiXmlElement("signals");
+	node->LinkEndChild(nodeSignals);
+
+    unsigned int lSignalSectionCount = road->GetSignalCount();
+    for(unsigned int i=0; i<lSignalSectionCount; i++)
+    {
+        WriteSignal(nodeSignals, road->GetSignal(i));
+    }
+
+	return true;
+}
+
+bool OpenDriveXmlWriter::WriteSignal(TiXmlElement *node, Signal * pSignal)
+{
+    TiXmlElement* nodeSignal = new TiXmlElement("signal");
+    node->LinkEndChild(nodeSignal);
+
+    nodeSignal->SetAttribute("s",pSignal->Gets());
+    nodeSignal->SetAttribute("t",pSignal->Gett());
+    nodeSignal->SetAttribute("id",pSignal->Getid());
+    nodeSignal->SetAttribute("name",pSignal->Getname());
+    if(pSignal->Getdynamic() == true)
+    nodeSignal->SetAttribute("dynamic","yes");
+    else
+        nodeSignal->SetAttribute("dynamic","no");
+    nodeSignal->SetAttribute("orientation",pSignal->Getorientation());
+    nodeSignal->SetAttribute("zOffset",pSignal->GetzOffset());
+    nodeSignal->SetAttribute("type",pSignal->Gettype());
+    nodeSignal->SetAttribute("country",pSignal->Getcountry());
+    nodeSignal->SetAttribute("countryRevision",pSignal->GetcountryRevision());
+    nodeSignal->SetAttribute("subtype",pSignal->Getsubtype());
+    nodeSignal->SetAttribute("hOffset",pSignal->GethOffset());
+    nodeSignal->SetAttribute("pitch",pSignal->Getpitch());
+    nodeSignal->SetAttribute("roll",pSignal->Getroll());
+    nodeSignal->SetAttribute("height",pSignal->Getheight());
+    nodeSignal->SetAttribute("width",pSignal->Getwidth());
+
+    signal_laneValidity * psignal_lanevalidity = pSignal->GetlaneValidity();
+    if(psignal_lanevalidity != 0)
+    {
+        WriteSignal_laneValidity(nodeSignal,psignal_lanevalidity);
+    }
+
+    signal_positionInertial * psignal_positionInertial = pSignal->GetpositionInertial();
+    if(psignal_positionInertial != 0)
+    {
+        WriteSignal_positionInertial(nodeSignal,psignal_positionInertial);
+    }
+
+    return true;
+}
+
+bool OpenDriveXmlWriter::WriteSignal_positionInertial(TiXmlElement *node, signal_positionInertial *pSignal_positionInertial)
+{
+    TiXmlElement* nodepositionInertial = new TiXmlElement("positionInertial");
+
+    node->LinkEndChild(nodepositionInertial);
+
+    nodepositionInertial->SetAttribute("x",pSignal_positionInertial->Getx());
+    nodepositionInertial->SetAttribute("y",pSignal_positionInertial->Gety());
+    nodepositionInertial->SetAttribute("z",pSignal_positionInertial->Getz());
+    nodepositionInertial->SetAttribute("hdg",pSignal_positionInertial->Gethdg());
+    nodepositionInertial->SetAttribute("pitch",pSignal_positionInertial->Getpitch());
+    nodepositionInertial->SetAttribute("roll",pSignal_positionInertial->Getroll());
+
+    return true;
+}
+
+bool OpenDriveXmlWriter::WriteSignal_laneValidity(TiXmlElement *node, signal_laneValidity *pSignal_laneValidity)
+{
+    TiXmlElement* nodelaneValidity = new TiXmlElement("validity");
+
+    node->LinkEndChild(nodelaneValidity);
+
+    nodelaneValidity->SetAttribute("fromLane",pSignal_laneValidity->GetfromLane());
+    nodelaneValidity->SetAttribute("toLane",pSignal_laneValidity->GettoLane());
+
+    return true;
+}
+
+//--------------
+
+bool OpenDriveXmlWriter::WriteSurface (TiXmlElement *node, Road* road)
+{
+	return true;
+}
+//--------------
+
+bool OpenDriveXmlWriter::WriteController (TiXmlElement *node)
+{	return true;	}
+//--------------
+
+bool OpenDriveXmlWriter::WriteJunction (TiXmlElement *node, Junction *junction)
+{
+	string name;
+	string id;
+
+	name = junction->GetName();
+	id = junction->GetId();
+
+	TiXmlElement *nodeJunction = new TiXmlElement("junction");
+	node->LinkEndChild(nodeJunction);
+
+	nodeJunction->SetAttribute("name",name);
+	nodeJunction->SetAttribute("id",id);
+
+	//Connections
+	WriteJunctionConnection(nodeJunction, junction);
+
+	//Priorities
+	WriteJunctionPriority(nodeJunction, junction);
+
+	//Controllers
+	WriteJunctionController(nodeJunction, junction);
+
+	return true;
+}
+//--------------
+bool OpenDriveXmlWriter::WriteJunctionConnection (TiXmlElement *node, Junction* junction)
+{
+	string id;
+	string incomingRoad;
+	string connectingRoad;
+	string contactPoint;
+
+	unsigned int junctionConnectionCount = junction->GetJunctionConnectionCount();
+	for(unsigned int i=0; i<junctionConnectionCount; i++)
+	{
+		JunctionConnection *lJunctionConnection = junction->GetJunctionConnection(i);
+
+		id = lJunctionConnection->GetId();
+		incomingRoad = lJunctionConnection->GetIncomingRoad();
+		connectingRoad = lJunctionConnection->GetConnectingRoad();
+		contactPoint = lJunctionConnection->GetContactPoint();
+
+		TiXmlElement *nodeJunctionConnection = new TiXmlElement("connection");
+		node->LinkEndChild(nodeJunctionConnection);
+
+		nodeJunctionConnection->SetAttribute("id",id);
+		nodeJunctionConnection->SetAttribute("incomingRoad",incomingRoad);
+		nodeJunctionConnection->SetAttribute("connectingRoad",connectingRoad);
+		nodeJunctionConnection->SetAttribute("contactPoint",contactPoint);
+
+		//Lane links
+		WriteJunctionConnectionLaneLink(nodeJunctionConnection, lJunctionConnection);
+	}
+
+	return true;
+}
+bool OpenDriveXmlWriter::WriteJunctionConnectionLaneLink (TiXmlElement *node, JunctionConnection* junctionConnection)
+{
+	int from;
+	int to;
+	
+	unsigned int junctionLaneLinkCount = junctionConnection->GetJunctionLaneLinkCount();
+	for(unsigned int i=0; i<junctionLaneLinkCount; i++)
+	{
+		JunctionLaneLink *lJunctionLaneLink = junctionConnection->GetJunctionLaneLink(i);
+
+		from = lJunctionLaneLink->GetFrom();
+		to = lJunctionLaneLink->GetTo();
+
+		TiXmlElement *nodeJunctionLaneLink = new TiXmlElement("laneLink");
+		node->LinkEndChild(nodeJunctionLaneLink);
+
+		nodeJunctionLaneLink->SetAttribute("from",from);
+		nodeJunctionLaneLink->SetAttribute("to",to);
+	}
+	return true;
+}
+
+bool OpenDriveXmlWriter::WriteJunctionPriority (TiXmlElement *node, Junction* junction)
+{
+	string high;
+	string low;
+
+	unsigned int junctionPriorityCount = junction->GetJunctionPriorityCount();
+	for(unsigned int i=0; i<junctionPriorityCount; i++)
+	{
+		JunctionPriorityRoad *lJunctionPriority = junction->GetJunctionPriority(i);
+
+		high = lJunctionPriority->GetHigh();
+		low = lJunctionPriority->GetLow();
+
+		TiXmlElement *nodeJunctionPriority = new TiXmlElement("priority");
+		node->LinkEndChild(nodeJunctionPriority);
+
+		nodeJunctionPriority->SetAttribute("high",high);
+		nodeJunctionPriority->SetAttribute("low",low);
+	}
+
+	return true;
+}
+bool OpenDriveXmlWriter::WriteJunctionController (TiXmlElement *node, Junction* junction)
+{
+	string id;
+	string type;
+
+	unsigned int junctionControllerCount = junction->GetJunctionControllerCount();
+	for(unsigned int i=0; i<junctionControllerCount; i++)
+	{
+		JunctionController *lJunctionController = junction->GetJunctionController(i);
+
+		id = lJunctionController->GetId();
+		type = lJunctionController->GetType();
+
+		TiXmlElement *nodeJunctionController = new TiXmlElement("controller");
+		node->LinkEndChild(nodeJunctionController);
+
+		nodeJunctionController->SetAttribute("id",id);
+		nodeJunctionController->SetAttribute("type",type);
+	}
+	return true;
+}
+
+
+//---------------------------------------------------------------------------
+
+/**
+ * Writes the data from the OpenDrive structure to a file
+ */
+bool OpenDriveXmlWriter::WriteFile(std::string fileName)
+{
+	// XML document
+	TiXmlDocument doc;
+
+	TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );  
+	doc.LinkEndChild( decl );
+
+	TiXmlElement *rootNode = new TiXmlElement("OpenDRIVE");
+	doc.LinkEndChild(rootNode);
+
+	// Write header
+	WriteHeader(rootNode);
+
+	// Write roads
+	unsigned int roadCount = mOpenDrive->GetRoadCount();
+	for(unsigned int i=0; i<roadCount; i++)
+	{
+		WriteRoad(rootNode, mOpenDrive->GetRoad(i));
+	}
+
+	// Write junctions
+	unsigned int junctionCount = mOpenDrive->GetJunctionCount();
+	for(unsigned int i=0; i<junctionCount; i++)
+	{
+		WriteJunction(rootNode, mOpenDrive->GetJunction(i));
+	}
+
+	// Saves the XML structure to the file
+	doc.SaveFile( fileName ); 
+
+	return true;
+
+}
+//--------------

+ 90 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OpenDriveXmlWriter.h

@@ -0,0 +1,90 @@
+#ifndef OPENDRIVEXMLWRITER_H
+#define OPENDRIVEXMLWRITER_H
+
+#include <vector>
+#include <string>
+
+#include <iostream>
+#include <iomanip>
+using namespace std;
+#include <fstream>
+#include "../TinyXML/tinyxml.h"
+
+#include "OpenDrive.h"
+
+/**
+ * Class used to write the content of the OpenDrive structure to the file
+ *
+ */
+class OpenDriveXmlWriter
+{
+private:
+	OpenDrive* mOpenDrive;
+public:
+	/**
+	 * Constructor which saves a reference to OpenDrive structure
+	 */
+	OpenDriveXmlWriter (OpenDrive* openDriveObj);
+
+	/**
+	 * Writes the data from the OpenDrive structure to a file
+	 */
+	bool WriteFile(std::string fileName);
+	
+	/**
+	 * The following methods are used to create the XML representation of the OpenDrive structure
+	 * Methods follow the same hierarchical structure and are called automatically when WriteFile
+	 * is executed
+	 */
+	bool WriteHeader (TiXmlElement *node);
+	bool WriteRoad (TiXmlElement *node, Road *road);
+	bool WriteRoadLinks (TiXmlElement *node, Road* road);
+	bool WriteRoadType (TiXmlElement *node, Road* road);
+	//--------------
+
+	bool WritePlanView(TiXmlElement *node, Road* road);
+	bool WriteGeometryBlock (TiXmlElement *node, GeometryBlock *geometryBlock);
+	bool WriteGeometry(TiXmlElement *node, RoadGeometry* roadGeometry, short int geometryType);
+	//--------------
+
+	bool WriteElevationProfile (TiXmlElement *node, Road* road);
+	bool WriteLateralProfile (TiXmlElement *node, Road* road);
+	//--------------
+
+	bool WriteLanes (TiXmlElement *node, Road* road);
+	bool WriteLaneSections (TiXmlElement *node, LaneSection *laneSection);
+	bool WriteLane (TiXmlElement *node, Lane* lane);
+	bool WriteLaneWidth(TiXmlElement *node, LaneWidth* laneWidth);
+	bool WriteLaneRoadMark(TiXmlElement *node, LaneRoadMark* laneRoadMark);
+	bool WriteLaneMaterial(TiXmlElement *node, LaneMaterial* laneMaterial);
+	bool WriteLaneVisibility(TiXmlElement *node, LaneVisibility* laneVisibility);
+	bool WriteLaneSpeed(TiXmlElement *node, LaneSpeed* laneSpeed);
+	bool WriteLaneAccess(TiXmlElement *node, LaneAccess* laneAccess);
+	bool WriteLaneHeight(TiXmlElement *node, LaneHeight* laneHeight);
+	//--------------
+
+	bool WriteObjects (TiXmlElement *node, Road* road);
+	bool WriteSignals (TiXmlElement *node, Road* road);
+    bool WriteSignal(TiXmlElement * node, Signal * pSignal);
+    bool WriteSignal_positionInertial(TiXmlElement * node, signal_positionInertial * pSignal_positionInertial);
+    bool WriteSignal_laneValidity(TiXmlElement * node, signal_laneValidity * pSignal_laneValidity);
+	//--------------
+
+	bool WriteSurface (TiXmlElement *node, Road* road);
+	//--------------
+
+	bool WriteController (TiXmlElement *node);
+	//--------------
+
+	bool WriteJunction (TiXmlElement *node, Junction *junction);
+	bool WriteJunctionConnection (TiXmlElement *node, Junction* junction);
+	bool WriteJunctionConnectionLaneLink (TiXmlElement *node, JunctionConnection* junctionConnection);
+	//--------------
+
+	bool WriteJunctionPriority (TiXmlElement *node, Junction* junction);
+	bool WriteJunctionController (TiXmlElement *node, Junction* junction);
+	//--------------
+};
+
+
+#endif

+ 90 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OtherStructures.cpp

@@ -0,0 +1,90 @@
+#include "OtherStructures.h"
+
+//***********************************************************************************
+//Polynom of third order
+//***********************************************************************************
+/**
+ * Constructor that initializes the polynom with base properties
+ * 
+ * @param s S offset
+ * @param a A parameter of the polynom
+ * @param b B parameter of the polynom
+ * @param c C parameter of the polynom
+ * @param d D parameter of the polynom
+ */
+ThirdOrderPolynom::ThirdOrderPolynom (double s, double a, double b, double c, double d)
+{	
+	mS=s; mA=a; mB=b; mC=c; mD=d;	
+}
+
+/**
+ * Getters for base properties
+ */	
+double ThirdOrderPolynom::GetS()
+{
+	return mS;
+}
+double ThirdOrderPolynom::GetA()
+{
+	return mA;
+}
+double ThirdOrderPolynom::GetB()
+{
+	return mB;
+}
+double ThirdOrderPolynom::GetC()
+{
+	return mC;
+}
+
+double ThirdOrderPolynom::GetD()
+{
+	return mD;
+}
+
+/**
+ * Setters for base properties
+ */
+void ThirdOrderPolynom::SetS(double s)
+{
+	mS=s;
+}
+void ThirdOrderPolynom::SetA(double a)
+{
+	mA=a;
+}
+void ThirdOrderPolynom::SetB(double b)
+{
+	mB=b;
+}
+void ThirdOrderPolynom::SetC(double c)
+{
+	mC=c;
+}
+void ThirdOrderPolynom::SetD(double d)
+{
+	mD=d;
+}
+
+
+/**
+ * Method to check if sample S is inside the record interval
+ */	
+bool ThirdOrderPolynom::CheckInterval (double s_check)
+{
+	if (s_check>=mS)
+		return true;
+	else 
+		return false;
+}
+
+/**
+ * Returns the value at sample S
+ */	
+double ThirdOrderPolynom::GetValue(double s_check)
+{
+	double ds = s_check-mS;
+	double value = mA+ mB*ds+ mC*ds*ds + mD*ds*ds*ds;
+	return value;
+}
+//----------------------------------------------------------------------------------

+ 66 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/OtherStructures.h

@@ -0,0 +1,66 @@
+#ifndef OTHERSTRUCTURES_H
+#define OTHERSTRUCTURES_H
+#include <string>
+using std::string;
+
+/**
+ * Polynom of third order
+ *
+ */
+class ThirdOrderPolynom
+{
+protected:
+	double mS;
+	double mA;
+	double mB;
+	double mC;
+	double mD;
+public:
+	/**
+	 * Constructor that initializes the polynom with base properties
+	 * 
+	 * @param s S offset
+	 * @param a A parameter of the polynom
+	 * @param b B parameter of the polynom
+	 * @param c C parameter of the polynom
+	 * @param d D parameter of the polynom
+	 */
+	ThirdOrderPolynom (double s, double a, double b, double c, double d);
+	
+
+	/**
+	 * Setters for base properties
+	 */	
+	void SetS(double s);
+	void SetA(double a);
+	void SetB(double b);
+	void SetC(double c);
+	void SetD(double d);
+	
+
+	/**
+	 * Getters for base properties
+	 */		
+	double GetS();
+	double GetA();
+	double GetB();
+	double GetC();
+	double GetD();
+	
+
+	/**
+	 * Method to check if sample S is inside the record interval
+	 */	
+	bool CheckInterval (double s_check);
+
+	/**
+	 * Returns the value at sample S
+	 */	
+	double GetValue(double s_check);
+
+};
+//----------------------------------------------------------------------------------
+
+
+
+#endif

+ 1258 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Road.cpp

@@ -0,0 +1,1258 @@
+#include "Road.h"
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+
+
+
+//***********************************************************************************
+//Road segment
+//***********************************************************************************
+/**
+ * Constructor 
+ */
+Road::Road()
+{	
+	mPredecessor=NULL; mSuccessor=NULL; mNeighbor1=NULL; mNeighbor2=NULL;	
+}
+
+/**
+ * Constructor that initializes the road with basic properties
+ * 
+ * @param name Name of the road
+ * @param length Length of the road
+ * @param id Unique ID of the road
+ * @param junction ID of the junction, this road might be a part of
+ */
+Road::Road(string name, double length, string id, string junction)
+{	
+	mPredecessor=NULL; mSuccessor=NULL; mNeighbor1=NULL; mNeighbor2=NULL;	mName=name; mLength=length; mId=id; mJunction=junction;
+}
+
+/**
+ * Copy constructor
+ */
+Road::Road (const Road& road)
+{
+	mName=road.mName;
+	mLength=road.mLength;
+	mId=road.mId;
+	mJunction=road.mJunction;
+
+	mPredecessor=NULL;
+	mSuccessor=NULL;
+	mNeighbor1=NULL;
+	mNeighbor2=NULL;
+
+	if (road.mPredecessor!=NULL)
+		mPredecessor = new RoadLink(road.mPredecessor->GetElementType(), road.mPredecessor->GetElementId(), road.mPredecessor->GetContactPoint());
+	if (road.mSuccessor!=NULL)
+		mSuccessor = new RoadLink(road.mSuccessor->GetElementType(), road.mSuccessor->GetElementId(), road.mSuccessor->GetContactPoint());
+	if (road.mNeighbor1!=NULL)
+		mNeighbor1 = new RoadNeighbor(road.mNeighbor1->GetSide(), road.mNeighbor1->GetElementId(), road.mNeighbor1->GetDirection());
+	if (road.mNeighbor2!=NULL)
+		mNeighbor2 = new RoadNeighbor(road.mNeighbor2->GetSide(), road.mNeighbor2->GetElementId(), road.mNeighbor2->GetDirection());
+
+	mRoadTypeVector=road.mRoadTypeVector;
+	mGeometryBlockVector=road.mGeometryBlockVector;
+	mElevationVector=road.mElevationVector;
+	mSuperElevationVector=road.mSuperElevationVector;
+	mCrossfallVector=road.mCrossfallVector;
+	mLaneSectionsVector=road.mLaneSectionsVector;
+	mObjectsVector=road.mObjectsVector;
+	mSignalsVector=road.mSignalsVector;
+}
+
+/**
+ * Assignment operator overload
+ */
+const Road& Road::operator=(const Road& otherRoad)
+{
+	if (this!= &otherRoad)
+	{
+		mName=otherRoad.mName;
+		mLength=otherRoad.mLength;
+		mId=otherRoad.mId;
+		mJunction=otherRoad.mJunction;
+
+		delete mPredecessor;
+		delete mSuccessor;
+		delete mNeighbor1;
+		delete mNeighbor2;
+
+		mPredecessor=NULL;
+		mSuccessor=NULL;
+		mNeighbor1=NULL;
+		mNeighbor2=NULL;
+
+		if (otherRoad.mPredecessor!=NULL)
+			mPredecessor = new RoadLink(otherRoad.mPredecessor->GetElementType(), otherRoad.mPredecessor->GetElementId(), otherRoad.mPredecessor->GetContactPoint());
+		if (otherRoad.mSuccessor!=NULL)
+			mSuccessor = new RoadLink(otherRoad.mSuccessor->GetElementType(), otherRoad.mSuccessor->GetElementId(), otherRoad.mSuccessor->GetContactPoint());
+		if (otherRoad.mNeighbor1!=NULL)
+			mNeighbor1 = new RoadNeighbor(otherRoad.mNeighbor1->GetSide(), otherRoad.mNeighbor1->GetElementId(), otherRoad.mNeighbor1->GetDirection());
+		if (otherRoad.mNeighbor2!=NULL)
+			mNeighbor2 = new RoadNeighbor(otherRoad.mNeighbor2->GetSide(), otherRoad.mNeighbor2->GetElementId(), otherRoad.mNeighbor2->GetDirection());
+
+		mRoadTypeVector=otherRoad.mRoadTypeVector;
+		mGeometryBlockVector=otherRoad.mGeometryBlockVector;
+		mElevationVector=otherRoad.mElevationVector;
+		mSuperElevationVector=otherRoad.mSuperElevationVector;
+		mCrossfallVector=otherRoad.mCrossfallVector;
+		mLaneSectionsVector=otherRoad.mLaneSectionsVector;
+		mObjectsVector=otherRoad.mObjectsVector;
+		mSignalsVector=otherRoad.mSignalsVector;
+	}
+	return *this;
+}
+//-------------------------------------------------
+
+/**
+ * Recalculates the chordline geometry of the road
+ */
+void Road::RecalculateGeometry()
+{
+	// Goes through geometry blocks and recalculates their coordinates and headings starting with the second record
+	// so the second geometry will start at the coordinates where the first one ended
+	double length=0;
+	unsigned int lGeometryVectorSize = mGeometryBlockVector.size();
+	if(lGeometryVectorSize>0)
+	{
+		double lS=0;
+		double lX=0;
+		double lY=0;
+		double lHdg=0;
+		mGeometryBlockVector.at(0).GetLastCoords(lS,lX,lY,lHdg);
+		length+=mGeometryBlockVector.at(0).GetBlockLength();
+
+		GeometryBlock *lGeometry;
+		for(unsigned int i=1; i<lGeometryVectorSize; i++)
+		{
+			lGeometry=&mGeometryBlockVector.at(i);
+			lGeometry->Recalculate(lS,lX,lY,lHdg);
+			lGeometry->GetLastCoords(lS,lX,lY,lHdg);
+			length+=lGeometry->GetBlockLength();
+		}
+	}
+
+	mLength=length;
+}
+
+/**
+ * Getters for the basic properties of the road
+ */
+string Road::GetRoadName() const
+{
+	return mName;
+}
+double Road::GetRoadLength() const
+{
+	return mLength;
+}
+string Road::GetRoadId() const
+{
+	return mId;
+}
+string Road::GetRoadJunction() const
+{
+	return mJunction;
+}
+
+/**
+ * Getters for the linking properties of the road
+ */
+RoadLink* Road::GetPredecessor()
+{	
+	return mPredecessor;	
+}
+RoadLink* Road::GetSuccessor()
+{	
+	return mSuccessor;	
+}
+RoadNeighbor* Road::GetNeighbor1()
+{	
+	return mNeighbor1;	
+}
+RoadNeighbor* Road::GetNeighbor2()
+{	
+	return mNeighbor2;	
+}
+
+
+/**
+ * Getters for the child records and their vectors
+ */
+// Road type records
+vector<RoadType> *Road::GetRoadTypeVector()
+{
+	return &mRoadTypeVector;
+}
+RoadType* Road::GetRoadType(unsigned int i)
+{	
+	if ((mRoadTypeVector.size()>0)&&(i<mRoadTypeVector.size()))
+		return &mRoadTypeVector.at(i);
+	else
+		return NULL;
+}
+unsigned int Road::GetRoadTypeCount()
+{
+	return mRoadTypeVector.size();
+}
+// Road geometry records
+vector<GeometryBlock> *Road::GetGeometryBlockVector()
+{
+	return &mGeometryBlockVector;
+}
+GeometryBlock* Road::GetGeometryBlock(unsigned int i)
+{	
+	if ((mGeometryBlockVector.size()>0)&&(i<mGeometryBlockVector.size()))
+		return &mGeometryBlockVector.at(i);
+	else
+		return NULL;
+}
+unsigned int Road::GetGeometryBlockCount()
+{
+	return mGeometryBlockVector.size();
+}
+// Road elevation records
+vector<Elevation> *Road::GetElevationVector()
+{
+	return &mElevationVector;
+}
+Elevation*	Road::GetElevation(unsigned int i)
+{	
+	if ((mElevationVector.size()>0)&&(i<mElevationVector.size()))
+		return &mElevationVector.at(i);
+	else
+		return NULL;
+}
+unsigned int Road::GetElevationCount()
+{
+	return mElevationVector.size();
+}
+// Road superelevation records
+vector<SuperElevation> *Road::GetSuperElevationVector()
+{
+	return &mSuperElevationVector;
+}
+SuperElevation*	Road::GetSuperElevation(unsigned int i)
+{	
+	if ((mSuperElevationVector.size()>0)&&(i<mSuperElevationVector.size()))
+		return &mSuperElevationVector.at(i);
+	else
+		return NULL;
+}
+unsigned int Road::GetSuperElevationCount()
+{
+	return mSuperElevationVector.size();
+}
+// Road crossfall records
+vector<Crossfall> *Road::GetCrossfallVector()
+{
+	return &mCrossfallVector;
+}
+Crossfall*	Road::GetCrossfall(unsigned int i)
+{	
+	if ((mCrossfallVector.size()>0)&&(i<mCrossfallVector.size()))
+		return &mCrossfallVector.at(i);
+	else
+		return NULL;
+}
+unsigned int Road::GetCrossfallCount()
+{
+	return mCrossfallVector.size();
+}
+// Road lane section records
+vector<LaneSection> *Road::GetLaneSectionVector()
+{
+	return &mLaneSectionsVector;
+}
+LaneSection*	Road::GetLaneSection(unsigned int i)
+{	
+	if ((mLaneSectionsVector.size()>0)&&(i<mLaneSectionsVector.size()))
+		return &mLaneSectionsVector.at(i);
+	else
+		return NULL;
+}
+unsigned int Road::GetLaneSectionCount()
+{
+	return mLaneSectionsVector.size();
+}
+// Road object records
+vector<Object> *Road::GetObjectVector()
+{
+	return &mObjectsVector;
+}
+Object*	Road::GetObject(unsigned int i)
+{	
+	if ((mObjectsVector.size()>0)&&(i<mObjectsVector.size()))
+		return &mObjectsVector.at(i);
+	else
+		return NULL;
+}
+unsigned int Road::GetObjectCount()
+{
+	return mObjectsVector.size();
+}
+// Road signal records
+vector<Signal> *Road::GetSignalVector()
+{
+	return &mSignalsVector;
+}
+Signal*	Road::GetSignal(unsigned int i)
+{	
+	if ((mSignalsVector.size()>0)&&(i<mSignalsVector.size()))
+		return &mSignalsVector.at(i);
+	else
+		return NULL;
+}
+unsigned int Road::GetSignalCount()
+{
+	return mSignalsVector.size();
+}
+//-------------------------------------------------
+
+/**
+ * Getters for the last child records in their respective vectors
+ */
+RoadType* Road::GetLastRoadType()
+{	
+	if (mRoadTypeVector.size()>0)
+		return &mRoadTypeVector.at(mRoadTypeVector.size()-1);
+	else
+		return NULL;
+}
+GeometryBlock* Road::GetLastGeometryBlock()
+{	
+	if (mGeometryBlockVector.size()>0)
+		return &mGeometryBlockVector.at(mGeometryBlockVector.size()-1);
+	else
+		return NULL;
+}
+Elevation*	Road::GetLastElevation()
+{	
+	if (mElevationVector.size()>0)
+		return &mElevationVector.at(mElevationVector.size()-1);
+	else
+		return NULL;
+}
+SuperElevation*	Road::GetLastSuperElevation()
+{	
+	if (mSuperElevationVector.size()>0)
+		return &mSuperElevationVector.at(mSuperElevationVector.size()-1);
+	else
+		return NULL;
+}
+Crossfall*	Road::GetLastCrossfall()
+{	
+	if (mCrossfallVector.size()>0)
+		return &mCrossfallVector.at(mCrossfallVector.size()-1);
+	else
+		return NULL;
+}
+LaneSection*	Road::GetLastLaneSection()
+{	
+	if (mLaneSectionsVector.size()>0)
+		return &mLaneSectionsVector.at(mLaneSectionsVector.size()-1);
+	else
+		return NULL;
+}
+Object*	Road::GetLastObject()
+{	
+	if (mObjectsVector.size()>0)
+		return &mObjectsVector.at(mObjectsVector.size()-1);
+	else
+		return NULL;
+}
+Signal*	Road::GetLastSignal()
+{	
+	if (mSignalsVector.size()>0)
+		return &mSignalsVector.at(mSignalsVector.size()-1);
+	else
+		return NULL;
+}
+
+
+/**
+ * Getters for the last added child records in their respective vectors
+ */
+RoadType* Road::GetLastAddedRoadType()
+{
+	if(mLastAddedRoadType<mRoadTypeVector.size())
+		return &mRoadTypeVector.at(mLastAddedRoadType);
+	else
+		return NULL;
+}
+GeometryBlock* Road::GetLastAddedGeometryBlock()
+{
+	if(mLastAddedGeometryBlock<mGeometryBlockVector.size())
+		return &mGeometryBlockVector.at(mLastAddedGeometryBlock);
+	else
+		return NULL;
+}
+Elevation* Road::GetLastAddedElevation()
+{
+	if(mLastAddedElevation<mElevationVector.size())
+		return &mElevationVector.at(mLastAddedElevation);
+	else
+		return NULL;
+}
+SuperElevation* Road::GetLastAddedSuperElevation()
+{
+	if(mLastAddedSuperElevation<mSuperElevationVector.size())
+		return &mSuperElevationVector.at(mLastAddedSuperElevation);
+	else
+		return NULL;
+}
+Crossfall* Road::GetLastAddedCrossfall()
+{
+	if(mLastAddedCrossfall<mCrossfallVector.size())
+		return &mCrossfallVector.at(mLastAddedCrossfall);
+	else
+		return NULL;
+}
+LaneSection* Road::GetLastAddedLaneSection()
+{
+	if(mLastAddedLaneSection<mLaneSectionsVector.size())
+		return &mLaneSectionsVector.at(mLastAddedLaneSection);
+	else
+		return NULL;
+}
+Object* Road::GetLastAddedObject()
+{
+	if(mLastAddedObject<mObjectsVector.size())
+		return &mObjectsVector.at(mLastAddedObject);
+	else
+		return NULL;
+}
+Signal* Road::GetLastAddedSignal()
+{
+	if(mLastAddedSignal<mSignalsVector.size())
+		return &mSignalsVector.at(mLastAddedSignal);
+	else
+		return NULL;
+}
+//-------------------------------------------------
+
+/**
+ * Setters for the basic road properties
+ */
+void Road::SetRoadName(string name)
+{
+	mName=name;
+}
+void Road::SetRoadLength(double length)
+{
+	mLength=length;
+}
+void Road::SetRoadId(string id)
+{
+	mId=id;
+}
+void Road::SetRoadJunction(string junction)
+{
+	mJunction=junction;
+}
+
+/**
+ * Setters for the linking road properties
+ */
+void Road::SetPredecessor(string elementType, string elementId, string contactPoint)
+{
+	if(mPredecessor!=NULL)
+	{
+		mPredecessor->SetElementType(elementType);
+		mPredecessor->SetElementId(elementId);
+		mPredecessor->SetContactPoint(contactPoint);
+	}
+	else mPredecessor = new RoadLink(elementType, elementId,contactPoint);	
+}
+void Road::SetSuccessor(string elementType, string elementId, string contactPoint)
+{
+	if(mSuccessor!=NULL)
+	{
+		mSuccessor->SetElementType(elementType);
+		mSuccessor->SetElementId(elementId);
+		mSuccessor->SetContactPoint(contactPoint);
+	}
+	else mSuccessor=new RoadLink(elementType, elementId,contactPoint);	
+}
+void Road::SetNeighbor(string side, string elementId, string direction)
+{
+	if (mNeighbor1==NULL)
+		mNeighbor1=new RoadNeighbor(side, elementId, direction);
+	else
+		mNeighbor2=new RoadNeighbor(side, elementId, direction);
+}
+void Road::SetNeighbor1(string side, string elementId, string direction)
+{
+	if (mNeighbor1==NULL) mNeighbor1=new RoadNeighbor(side, elementId, direction);
+}
+void Road::SetNeighbor2(string side, string elementId, string direction)
+{
+	if (mNeighbor2==NULL) mNeighbor2=new RoadNeighbor(side, elementId, direction);
+}
+
+/**
+ * Removers for the linking road properties
+ */
+void Road::RemovePredecessor()
+{
+	if(mPredecessor!=NULL)
+	{
+		delete mPredecessor;
+		mPredecessor = NULL;
+	}
+}
+void Road::RemoveSuccessor()
+{
+	if(mSuccessor!=NULL)
+	{
+		delete mSuccessor;
+		mSuccessor = NULL;
+	}
+}
+void Road::RemoveNeighbor1()
+{
+	if(mNeighbor1!=NULL)
+	{
+		delete mNeighbor1;
+		mNeighbor1 = NULL;
+	}
+}
+void Road::RemoveNeighbor2()
+{
+	if(mNeighbor2!=NULL)
+	{
+		delete mNeighbor2;
+		mNeighbor2 = NULL;
+	}
+}
+//-------------------------------------------------
+
+/**
+ * Methods used to add child records to the respective vectors
+ */
+unsigned int Road::AddRoadType(double s, string type)
+{	
+	// Gets the index where the record should be inserted in the vector
+	unsigned int index = CheckRoadTypeInterval(s)+1;
+	// If larger than the record count - push to the back
+	if(index>=GetRoadTypeCount()) mRoadTypeVector.push_back(RoadType(s, type));
+	// else insert in the middle
+	else mRoadTypeVector.insert(mRoadTypeVector.begin()+index, RoadType(s, type));
+	// Save the last added record index
+	mLastAddedRoadType=index;
+	return index;
+}
+//-------------
+unsigned int Road::AddGeometryBlock()
+{	
+	// Check the first method in the group for details
+
+	unsigned int index=GetGeometryBlockCount();
+	mGeometryBlockVector.push_back(GeometryBlock());
+	mLastAddedGeometryBlock=index;
+	return index;
+}
+//-------------
+unsigned int Road::AddElevation(double s, double a, double b, double c, double d)
+{	
+	// Check the first method in the group for details
+
+	unsigned int index = CheckElevationInterval(s)+1;
+	if(index>=GetElevationCount()) mElevationVector.push_back(Elevation(s,a,b,c,d));
+	else mElevationVector.insert(mElevationVector.begin()+index, Elevation(s,a,b,c,d));
+	mLastAddedElevation=index;
+	return index;
+}
+//-------------
+unsigned int Road::AddSuperElevation(double s, double a, double b, double c, double d)
+{	
+	// Check the first method in the group for details
+
+	unsigned int index = CheckSuperElevationInterval(s)+1;
+	if(index>=GetSuperElevationCount()) mSuperElevationVector.push_back(SuperElevation(s,a,b,c,d));
+	else mSuperElevationVector.insert(mSuperElevationVector.begin()+index, SuperElevation(s,a,b,c,d));
+	mLastAddedSuperElevation=index;
+	return index;
+}
+//-------------
+unsigned int Road::AddCrossfall (string side, double s, double a, double b, double c, double d)
+{	
+	// Check the first method in the group for details
+
+	unsigned int index = CheckCrossfallInterval(s)+1;
+	if(index>=GetCrossfallCount()) mCrossfallVector.push_back(Crossfall(side,s,a,b,c,d));
+	else mCrossfallVector.insert(mCrossfallVector.begin()+index, Crossfall(side,s,a,b,c,d));
+	mLastAddedCrossfall=index;
+	return index;
+}
+//-------------
+unsigned int Road::AddLaneSection(double s)
+{
+	// Check the first method in the group for details
+
+	unsigned int index = CheckLaneSectionInterval(s)+1;
+	if(index>=GetLaneSectionCount()) mLaneSectionsVector.push_back(LaneSection(s));
+	else mLaneSectionsVector.insert(mLaneSectionsVector.begin()+index, LaneSection(s));
+	mLastAddedLaneSection=index;
+	return index;
+}
+//-------------
+unsigned int Road::AddObject()
+{	
+	// Check the first method in the group for details
+
+	unsigned int index=GetObjectCount();
+	mObjectsVector.push_back(Object());
+	mLastAddedObject=index;
+	return index;
+}
+//-------------
+unsigned int Road::AddSignal(double s,double t,string id,string name,bool dynamic,string orientation,double zOffset,string type,string country,string countryRevision,
+                             string subtype,double hOffset,double pitch,double roll ,double height,double width)
+{
+	// Check the first method in the group for details
+
+	unsigned int index=GetSignalCount();
+    Signal x(s,t,id,name,dynamic,orientation,zOffset,type,country,countryRevision,
+             subtype,hOffset,pitch,roll,height,width);
+    mSignalsVector.push_back(x);
+
+//    mSignalsVector.push_back(Signal(s,t,id,name,dynamic,orientation,zOffset,type,country,countryRevision,
+//                                    subtype,hOffset,pitch,roll,height,width));
+	mLastAddedSignal=index;
+	return index;
+}
+//-----------
+
+
+/**
+ * Methods used to clone child records in the respective vectors
+ */
+unsigned int Road::CloneRoadType(unsigned int index)
+{
+	// Clone the object and insert it in the middle of the vector
+	if(index<mRoadTypeVector.size()-1)
+		mRoadTypeVector.insert(mRoadTypeVector.begin()+index+1, mRoadTypeVector[index]);
+	// or just push it to the back
+	else if(index==mRoadTypeVector.size()-1)
+		mRoadTypeVector.push_back(mRoadTypeVector[index]);
+	// Save the last added record index
+	mLastAddedRoadType=index+1;
+	return mLastAddedRoadType;
+}
+unsigned int Road::CloneElevation(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mElevationVector.size()-1)
+		mElevationVector.insert(mElevationVector.begin()+index+1, mElevationVector[index]);
+	else if(index==mElevationVector.size()-1)
+		mElevationVector.push_back(mElevationVector[index]);
+	mLastAddedElevation=index+1;
+	return mLastAddedElevation;
+}
+unsigned int Road::CloneSuperElevation(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mSuperElevationVector.size()-1)
+		mSuperElevationVector.insert(mSuperElevationVector.begin()+index+1, mSuperElevationVector[index]);
+	else if(index==mSuperElevationVector.size()-1)
+		mSuperElevationVector.push_back(mSuperElevationVector[index]);
+	mLastAddedSuperElevation=index+1;
+	return mLastAddedSuperElevation;
+}
+unsigned int Road::CloneCrossfall(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mCrossfallVector.size()-1)
+		mCrossfallVector.insert(mCrossfallVector.begin()+index+1, mCrossfallVector[index]);
+	else if(index==mCrossfallVector.size()-1)
+		mCrossfallVector.push_back(mCrossfallVector[index]);
+	mLastAddedCrossfall=index+1;
+	return mLastAddedCrossfall;
+}
+unsigned int Road::CloneLaneSection(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mLaneSectionsVector.size()-1)
+		mLaneSectionsVector.insert(mLaneSectionsVector.begin()+index+1, mLaneSectionsVector[index]);
+	else if(index==mLaneSectionsVector.size()-1)
+		mLaneSectionsVector.push_back(mLaneSectionsVector[index]);
+	mLastAddedLaneSection=index+1;
+	return mLastAddedLaneSection;
+}
+unsigned int Road::CloneLaneSectionEnd(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	// Clones the lane section, duplicating only the last records in each child category
+	LaneSection lNewLaneSection(mLaneSectionsVector[index].GetS());
+	unsigned int iLaneCount=mLaneSectionsVector[index].GetLaneCount();
+
+	double lHighestS = 0;
+
+	for(unsigned int iLane=0; iLane<iLaneCount; iLane++)
+	{
+		Lane *lLane = mLaneSectionsVector[index].GetLane(iLane);
+		lNewLaneSection.AddLane(lLane->GetSide(), lLane->GetId(), lLane->GetType(), lLane->GetLevel(),false);
+
+		Lane *lNewLane = lNewLaneSection.GetLastAddedLane();
+
+		//width
+		LaneWidth *lWidth = lLane->GetLaneWidth(lLane->GetLaneWidthCount()-1);
+		if(lWidth!=NULL) 
+		{
+			lNewLane->AddWidthRecord(0.0, lWidth->GetA(), lWidth->GetB(), lWidth->GetC(), lWidth->GetD());
+			if(lWidth->GetS()>lHighestS) lHighestS=lWidth->GetS();
+		}
+
+		//road mark
+		LaneRoadMark *lRoadMark = lLane->GetLaneRoadMark(lLane->GetLaneRoadMarkCount()-1);
+		if(lRoadMark!=NULL) 
+		{
+			lNewLane->AddRoadMarkRecord(0.0, lRoadMark->GetType(), lRoadMark->GetWeight(), lRoadMark->GetColor(), lRoadMark->GetWidth(), lRoadMark->GetLaneChange());
+			if(lRoadMark->GetS()>lHighestS) lHighestS=lRoadMark->GetS();
+		}
+
+		//material
+		LaneMaterial *lMaterial = lLane->GetLaneMaterial(lLane->GetLaneMaterialCount()-1);
+		if(lMaterial!=NULL) 
+		{
+			lNewLane->AddMaterialRecord(0.0, lMaterial->GetSurface(), lMaterial->GetFriction(), lMaterial->GetRoughness());
+			if(lMaterial->GetS()>lHighestS) lHighestS=lMaterial->GetS();
+		}
+
+		//visibility
+		LaneVisibility *lVisibility = lLane->GetLaneVisibility(lLane->GetLaneVisibilityCount()-1);
+		if(lVisibility!=NULL) 
+		{
+			lNewLane->AddVisibilityRecord(0.0, lVisibility->GetForward(), lVisibility->GetBack(), lVisibility->GetLeft(), lVisibility->GetRight());
+			if(lVisibility->GetS()>lHighestS) lHighestS=lVisibility->GetS();
+		}
+
+		//speed
+		LaneSpeed *lSpeed = lLane->GetLaneSpeed(lLane->GetLaneSpeedCount()-1);
+		if(lSpeed!=NULL) 
+		{
+			lNewLane->AddSpeedRecord(0.0, lSpeed->GetMax());
+			if(lSpeed->GetS()>lHighestS) lHighestS=lSpeed->GetS();
+		}
+
+		//access
+		LaneAccess *lAccess = lLane->GetLaneAccess(lLane->GetLaneAccessCount()-1);
+		if(lAccess!=NULL) 
+		{
+			lNewLane->AddAccessRecord(0.0, lAccess->GetRestriction());
+			if(lAccess->GetS()>lHighestS) lHighestS=lAccess->GetS();
+		}
+
+		//height
+		LaneHeight *lHeight = lLane->GetLaneHeight(lLane->GetLaneHeightCount()-1);
+		if(lHeight!=NULL) 
+		{
+			lNewLane->AddHeightRecord(0.0, lHeight->GetInner(), lHeight->GetOuter());
+			if(lHeight->GetS()>lHighestS) lHighestS=lHeight->GetS();
+		}
+	}
+
+	lHighestS += mLaneSectionsVector[index].GetS();
+
+	if(index+1 < mLaneSectionsVector.size())
+	{
+		if(lHighestS < mLaneSectionsVector[index+1].GetS())
+			lNewLaneSection.SetS(lHighestS);
+	}
+
+
+	if(index<mLaneSectionsVector.size()-1)
+		mLaneSectionsVector.insert(mLaneSectionsVector.begin()+index+1, lNewLaneSection);
+	else if(index==mLaneSectionsVector.size()-1)
+		mLaneSectionsVector.push_back(lNewLaneSection);
+	mLastAddedLaneSection=index+1;
+	return mLastAddedLaneSection;
+}
+unsigned int Road::CloneObject(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mSignalsVector.size()-1)
+		mSignalsVector.insert(mSignalsVector.begin()+index+1, mSignalsVector[index]);
+	else if(index==mSignalsVector.size()-1)
+		mSignalsVector.push_back(mSignalsVector[index]);
+	mLastAddedObject=index+1;
+	return mLastAddedObject;
+}
+unsigned int Road::CloneSignal(unsigned int index)
+{
+	// Check the first method in the group for details
+
+	if(index<mSignalsVector.size()-1)
+		mSignalsVector.insert(mSignalsVector.begin()+index+1, mSignalsVector[index]);
+	else if(index==mSignalsVector.size()-1)
+		mSignalsVector.push_back(mSignalsVector[index]);
+	mLastAddedSignal=index+1;
+	return mLastAddedSignal;
+}
+
+/**
+ * Methods used to delete child records from the respective vectors
+ */
+void Road::DeleteRoadType(unsigned int index)
+{
+	mRoadTypeVector.erase(mRoadTypeVector.begin()+index);
+}
+void Road::DeleteGeometryBlock(unsigned int index)
+{
+	mGeometryBlockVector.erase(mGeometryBlockVector.begin()+index);
+}
+void Road::DeleteElevation(unsigned int index)
+{
+	mElevationVector.erase(mElevationVector.begin()+index);
+}
+void Road::DeleteSuperElevation(unsigned int index)
+{
+	mSuperElevationVector.erase(mSuperElevationVector.begin()+index);
+}
+void Road::DeleteCrossfall(unsigned int index)
+{
+	mCrossfallVector.erase(mCrossfallVector.begin()+index);
+}
+void Road::DeleteLaneSection(unsigned int index)
+{
+	mLaneSectionsVector.erase(mLaneSectionsVector.begin()+index);
+}
+void Road::DeleteObject(unsigned int index)
+{
+	mObjectsVector.erase(mObjectsVector.begin()+index);
+}
+void Road::DeleteSignal(unsigned int index)
+{
+	mSignalsVector.erase(mSignalsVector.begin()+index);
+}
+
+//-------------------------------------------------
+// EVALUATION METHODS
+
+/**
+ * Geometry evaluation
+ */
+bool Road::CheckGeometryInterval (double s_check)
+{
+	string tmp;
+	return CheckGeometryInterval(s_check,tmp);
+}
+//-----------
+bool Road::CheckGeometryInterval (double s_check, string &roadId)
+{
+	for (unsigned int i=0;i<mGeometryBlockVector.size();i++)
+	{
+		if (mGeometryBlockVector.at(i).CheckInterval(s_check))
+		{
+			roadId=mId;
+			return true;
+		}
+	}
+	roadId="N/A";
+	return false;
+}
+//-----------
+short int Road::GetGeometryCoords(double s_check, double &retX, double &retY)
+{
+	double tmp;
+	return GetGeometryCoords(s_check,retX,retY, tmp);
+}
+//-------------
+short int Road::GetGeometryCoords(double s_check, double &retX, double &retY, double &retHDG)
+{
+	//go trough all of the blocks
+	for (unsigned int i=0; i<mGeometryBlockVector.size();i++)
+	{
+		//Check the block and get coords.
+		short int res=mGeometryBlockVector.at(i).GetCoords(s_check,retX,retY, retHDG);
+		// If the returned value is one of the geometry types (for 0=line,1=arc and 2=spiral) then the result has been found and parameters filled, so, return the value
+		if (res>=0  ) 
+			return res;
+	}
+	//if s_check does not belong to the road, return -999
+	return -999;
+}
+//-----------
+
+/**
+ * Other evaluation
+ */
+int  Road::CheckRoadTypeInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the road type records
+	for (unsigned int i=0;i<mRoadTypeVector.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (s_check >= mRoadTypeVector.at(i).GetS())
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+//-----------
+string  Road::GetRoadTypeValue(double s_check)
+{
+	string retType="unknown";
+	//find the record where s_check belongs
+	int index=	CheckRoadTypeInterval(s_check);
+	//If found, return the type
+	if (index>=0)
+		retType= mRoadTypeVector.at(index).GetType();
+	return retType;
+}
+//-----------
+int  Road::CheckElevationInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the road type records
+	for (unsigned int i=0;i<mElevationVector.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (mElevationVector.at(i).CheckInterval(s_check))
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+//-----------
+double  Road::GetElevationValue (double s_check)
+{
+	double retVal=0;
+	//find the record where s_check belongs
+	int index=CheckElevationInterval(s_check);
+	//If found, return the type
+	if (index>=0)
+		retVal= (mElevationVector.at(index).GetValue(s_check));
+	return retVal;
+
+}
+//-----------
+int  Road::CheckSuperElevationInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the road type records
+	for (unsigned int i=0;i<mSuperElevationVector.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (mSuperElevationVector.at(i).CheckInterval(s_check))
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+//-----------
+double  Road::GetSuperElevationValue (double s_check)
+{
+	double retVal=0;
+	//find the record where s_check belongs
+	int index=CheckSuperElevationInterval(s_check);
+	//If found, return the type
+	if (index>=0)
+		retVal= (mSuperElevationVector.at(index).GetValue(s_check));
+
+	return retVal;
+}
+//-----------
+int  Road::CheckCrossfallInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the road type records
+	for (unsigned int i=0;i<mCrossfallVector.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (mCrossfallVector.at(i).CheckInterval(s_check))
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+//-----------
+void  Road::GetCrossfallValue (double s_check, double &angleLeft, double &angleRight)
+{
+	angleLeft=0.0;
+	angleRight=0.0;
+	//find the record where s_check belongs
+	int index=CheckCrossfallInterval(s_check);
+	//If found, return the type
+	string side;
+	double angle=0.0;
+	if (index>=0)
+	{
+		angle =(mCrossfallVector.at(index).GetValue(s_check));
+		side=(mCrossfallVector.at(index).GetSide());
+	}
+	
+	if (side.compare("left")==0)
+	{
+		angleLeft=-angle;
+	}
+	else if (side.compare("right")==0)
+	{
+		angleRight=-angle;
+	}
+	else
+	{
+		angleLeft=-angle;
+		angleRight=-angle;
+	}
+}
+//-----------
+int  Road::CheckLaneSectionInterval(double s_check)
+{
+	int res=-1;
+	//Go through all the lane section records
+	for (unsigned int i=0;i<mLaneSectionsVector.size();i++)
+	{
+		//check if the s_check belongs to the current record
+		if (mLaneSectionsVector.at(i).CheckInterval(s_check))
+			res=i;	//assign it to the result id
+		else 
+			break;	//if not, break;
+	}
+	return res;		//return the result: 0 to MaxInt as the index to the record containing s_check or -1 if nothing found
+}
+//-----------
+void  Road::FillLaneSectionSample(double s_check, LaneSectionSample& laneSectionSample)
+{
+	int index=CheckLaneSectionInterval(s_check);
+	if (index>=0)
+		mLaneSectionsVector.at(index).FillLaneSectionSample(s_check,laneSectionSample);
+}
+
+//-------------------------------------------------
+
+/**
+ * Destructor
+ */
+Road::~Road()
+{
+	delete mPredecessor;
+	delete mSuccessor;
+	delete mNeighbor1;
+	delete mNeighbor2;
+
+	// DELETING ROAD TYPES
+	mRoadTypeVector.clear();
+
+	// DELETING GEOMETRY BLOKS
+	mGeometryBlockVector.clear();
+
+	// DELETING ELEVATIONS
+	mElevationVector.clear();
+
+	// DELETING SUPERELEVATION
+	mSuperElevationVector.clear();
+
+	// DELETING CROSSFALL
+	mCrossfallVector.clear();
+
+	// DELETING LANE SECTIONS
+	mLaneSectionsVector.clear();
+
+	// DELETING OBJECTS
+	mObjectsVector.clear();
+
+	// DELETING SIGNALS
+	mSignalsVector.clear();
+}
+
+
+
+
+//***********************************************************************************
+//Road Link Record
+//***********************************************************************************
+/**
+ * Constructor which intializes the basic properties
+ */
+RoadLink::RoadLink(string elementType, string elementId, string contactPoint)
+{
+	mElementType=elementType;
+	mElementId=elementId;
+	mContactPoint=contactPoint;
+}
+
+/**
+ * Getters for the basic properties
+ */
+string RoadLink::GetElementType()
+{	
+	return mElementType;	
+}
+string RoadLink::GetElementId()
+{	
+	return mElementId;	
+}
+string RoadLink::GetContactPoint()
+{	
+	return mContactPoint;	
+}
+
+/**
+ * Setters for the basic properties
+ */
+void RoadLink::SetElementType(string elementType)
+{	
+	mElementType=elementType;	
+}
+void RoadLink::SetElementId(string elementId)
+{	
+	mElementId=elementId;
+}
+void RoadLink::SetContactPoint(string contactPoint)
+{	
+	mContactPoint=contactPoint;	
+}
+
+
+//***********************************************************************************
+//Road Neighbor Record
+//***********************************************************************************
+/**
+ * Constructor which intializes the basic properties
+ */
+RoadNeighbor::RoadNeighbor(string side, string elementId, string direction)
+{
+	mSide=side;
+	mElementId=elementId;
+	mDirection=direction;
+}
+/**
+ * Getters for the basic properties
+ */
+string RoadNeighbor::GetSide()
+{	
+	return mSide;	
+}
+string RoadNeighbor::GetElementId()
+{	
+	return mElementId;	
+}
+string RoadNeighbor::GetDirection()
+{	
+	return mDirection;	
+}
+
+/**
+ * Setters for the basic properties
+ */
+void RoadNeighbor::SetSide(string side)
+{	
+	mSide=side;	
+}
+void RoadNeighbor::SetElementId(string elementId)
+{	
+	mElementId=elementId;	
+}
+void RoadNeighbor::SetDirection(string direction)
+{	
+	mDirection=direction;	
+}
+
+
+//***********************************************************************************
+//Road Type
+//***********************************************************************************
+/**
+ * Constructor which intializes the basic properties
+ */
+RoadType::RoadType (double s, string type)
+{	
+	mS=s; mType=type;	
+}
+
+/**
+ * Setters for the basic properties
+ */
+void RoadType::SetS(double value)
+{
+	mS=value;
+}
+void RoadType::SetType(string type)
+{
+	mType=type;
+}
+
+/**
+ * Getters for the basic properties
+ */
+double RoadType::GetS()
+{
+	return mS;
+}
+string RoadType::GetType()
+{
+	return mType;
+}
+
+
+
+
+//***********************************************************************************
+//Elevation record
+//***********************************************************************************
+/**
+ * Constructor which intializes the basic properties
+ */
+Elevation::Elevation(double s, double a, double b, double c, double d): ThirdOrderPolynom(s,a,b,c,d)
+{}
+
+
+
+
+
+//***********************************************************************************
+//Elevation record
+//***********************************************************************************
+/**
+ * Constructor which intializes the basic properties
+ */
+SuperElevation::SuperElevation(double s, double a, double b, double c, double d): ThirdOrderPolynom(s,a,b,c,d)
+{}
+
+
+
+
+
+//***********************************************************************************
+//Crossfall Record
+//***********************************************************************************
+/**
+ * Constructor which intializes the basic properties
+ */
+Crossfall::Crossfall (string side, double s, double a, double b, double c, double d):ThirdOrderPolynom(s,a,b,c,d)
+{	
+	mSide=side;	
+}
+
+/**
+ * Getters for the crossfall side
+ */
+string Crossfall::GetSide()
+{
+	return mSide;
+}
+
+/**
+ * Setters for the crossfall side
+ */
+void Crossfall::SetSide(string side)
+{
+	mSide=side;
+}
+

+ 490 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/Road.h

@@ -0,0 +1,490 @@
+#ifndef ROAD_H
+#define ROAD_H
+
+#include <vector>
+#include <string>
+
+#include "RoadGeometry.h"
+#include "Lane.h"
+#include "Junction.h"
+#include "ObjectSignal.h"
+#include "OtherStructures.h"
+
+//--Prototypes--
+//road
+class Road;
+class RoadLink;
+class RoadNeighbor;
+class RoadType;
+class GeometryBlock;
+class Elevation;
+class SuperElevation;
+class Crossfall;
+//lanes
+class LaneSection;
+class LaneSectionSample;
+//objects, signals
+class Object;
+class Signal;
+//--------------
+
+using std::vector;
+using std::string;
+
+/**
+ * One of the main classes in OpenDrive structure
+ * Holds the properties of the Road record and vectors for child records
+ * Has methods to add, clone, get and delete those child records
+ * as well as evaluation methods used, for example, to render the road
+ *
+ */
+class Road
+{
+private:
+	// Main road record properties
+	string mName;
+	double mLength;
+	string mId;
+	string mJunction;
+
+	// Linking complex properties (have multiple sub-properties)
+	RoadLink* mPredecessor;
+	RoadLink* mSuccessor;
+	RoadNeighbor* mNeighbor1;
+	RoadNeighbor* mNeighbor2;
+
+	/**
+	 * Vectors used to store the child records of the road
+	 * such as chordline geometry, elevation profiles, etc
+	 */
+	// Road type vector
+	vector<RoadType> mRoadTypeVector;
+	// Geometry block vector
+	vector<GeometryBlock> mGeometryBlockVector; 
+	// Elevation Profile vector
+	vector<Elevation> mElevationVector;
+	// Superelevation vector
+	vector<SuperElevation> mSuperElevationVector;
+	// Crossfall vector
+	vector<Crossfall> mCrossfallVector;
+	// Lane Section vector
+	vector<LaneSection> mLaneSectionsVector;
+	// Objects vectors
+	vector<Object> mObjectsVector;
+	// Signal vector
+	vector<Signal> mSignalsVector;
+
+	/**
+	 * Indices of the last added child records
+	 */
+	unsigned int mLastAddedRoadType;
+	unsigned int mLastAddedGeometryBlock;
+	unsigned int mLastAddedElevation;
+	unsigned int mLastAddedSuperElevation;
+	unsigned int mLastAddedCrossfall;
+	unsigned int mLastAddedLaneSection;
+	unsigned int mLastAddedObject;
+	unsigned int mLastAddedSignal;
+
+public:
+	/**
+	 * Constructor
+	 */
+	Road();
+
+	/**
+	 * Constructor that initializes the road with base properties
+	 * 
+	 * @param name Name of the road
+	 * @param length Length of the road
+	 * @param id Unique ID of the road
+	 * @param junction ID of the junction, this road might be a part of
+	 */
+	Road(string name, double length, string id, string junction);
+
+	/**
+	 * Copy constructor
+	 */
+	Road (const Road& road);
+
+	/**
+	 * Assignment operator overload
+	 */
+	const Road& operator=(const Road& rhs);
+	//-------------------------------------------------
+
+	/**
+	 * Getters for the base properties of the road
+	 */
+	string GetRoadName() const;
+	double GetRoadLength() const;
+	string GetRoadId() const;
+	string GetRoadJunction() const;
+	
+	/**
+	 * Getters for the linking properties of the road
+	 */
+	RoadLink* GetPredecessor();
+	RoadLink* GetSuccessor();
+	RoadNeighbor* GetNeighbor1();
+	RoadNeighbor* GetNeighbor2();
+
+	/**
+	 * Getters for the child records and their vectors
+	 */
+	// Road type records
+	vector<RoadType> *GetRoadTypeVector();
+	RoadType* GetRoadType(unsigned int i);
+	unsigned int GetRoadTypeCount();
+	// Road geometry records
+	vector<GeometryBlock> *GetGeometryBlockVector();
+	GeometryBlock* GetGeometryBlock(unsigned int i);
+	unsigned int GetGeometryBlockCount();
+	// Road elevation records
+	vector<Elevation> *GetElevationVector();
+	Elevation*	GetElevation(unsigned int i);
+	unsigned int GetElevationCount();
+	// Road superelevation records
+	vector<SuperElevation> *GetSuperElevationVector();
+	SuperElevation*	GetSuperElevation(unsigned int i);
+	unsigned int GetSuperElevationCount();
+	// Road crossfall records
+	vector<Crossfall> *GetCrossfallVector();
+	Crossfall*	GetCrossfall(unsigned int i);
+	unsigned int GetCrossfallCount();
+	// Road lane section records
+	vector<LaneSection> *GetLaneSectionVector();
+	LaneSection*	GetLaneSection(unsigned int i);
+	unsigned int GetLaneSectionCount();
+	// Road object records
+	vector<Object> *GetObjectVector();
+	Object*	GetObject(unsigned int i);
+	unsigned int GetObjectCount();
+	// Road signal records
+	vector<Signal> *GetSignalVector();
+	Signal*	GetSignal(unsigned int i);
+	unsigned int GetSignalCount();
+	//-------------------------------------------------
+
+	/**
+	 * Getters for the last child records in their respective vectors
+	 */
+	RoadType*		GetLastRoadType();
+	GeometryBlock*	GetLastGeometryBlock();
+	Elevation*		GetLastElevation();
+	SuperElevation*	GetLastSuperElevation();
+	Crossfall*		GetLastCrossfall();
+	LaneSection*	GetLastLaneSection();
+	Object*			GetLastObject();
+	Signal*			GetLastSignal();
+
+	/**
+	 * Getters for the last added child records in their respective vectors
+	 */
+	RoadType*		GetLastAddedRoadType();
+	GeometryBlock*	GetLastAddedGeometryBlock();
+	Elevation*		GetLastAddedElevation();
+	SuperElevation*	GetLastAddedSuperElevation();
+	Crossfall*		GetLastAddedCrossfall();
+	LaneSection*	GetLastAddedLaneSection();
+	Object*			GetLastAddedObject();
+	Signal*			GetLastAddedSignal();
+
+	//-------------------------------------------------
+
+	/**
+	 * Setters for the base road properties
+	 */
+	void SetRoadName(string name);
+	void SetRoadLength(double length);
+	void SetRoadId(string roadId);
+	void SetRoadJunction(string junction);
+
+	/**
+	 * Setters for the linking road properties
+	 */
+	void SetPredecessor(string elementType, string elementId, string contactPoint);
+	void SetSuccessor(string elementType, string elementId, string contactPoint);
+	void SetNeighbor(string side, string elementId, string direction);
+	void SetNeighbor1(string side, string elementId, string direction);
+	void SetNeighbor2(string side, string elementId, string direction);
+	
+	/**
+	 * Removers for the linking road properties
+	 */
+	void RemovePredecessor();
+	void RemoveSuccessor();
+	void RemoveNeighbor1();
+	void RemoveNeighbor2();
+
+	//-------------------------------------------------
+
+	/**
+	 * Methods used to add child records to the respective vectors
+	 */
+	unsigned int AddRoadType(double s, string type);
+	unsigned int AddGeometryBlock();
+	unsigned int AddElevation(double s, double a, double b, double c, double d);
+	unsigned int AddSuperElevation(double s, double a, double b, double c, double d);
+	unsigned int AddCrossfall (string side, double s, double a, double b, double c, double d);
+	unsigned int AddLaneSection(double s);
+	unsigned int AddObject();
+    unsigned int AddSignal(double s,double t,string id,string name,bool dynamic,string orientation,double zOffset,string type,string country,string countryRevision,
+                           string subtype,double hOffset,double pitch,double roll ,double height,double width);
+
+	/**
+	 * Methods used to clone child records in the respective vectors
+	 */
+	unsigned int CloneRoadType(unsigned int index);
+	unsigned int CloneElevation(unsigned int index);
+	unsigned int CloneSuperElevation(unsigned int index);
+	unsigned int CloneCrossfall(unsigned int index);
+	unsigned int CloneLaneSection(unsigned int index);
+	unsigned int CloneLaneSectionEnd(unsigned int index);
+	unsigned int CloneObject(unsigned int index);
+	unsigned int CloneSignal(unsigned int index);
+
+	/**
+	 * Methods used to delete child records from the respective vectors
+	 */
+	void DeleteRoadType(unsigned int index);
+	void DeleteGeometryBlock(unsigned int index);
+	void DeleteElevation(unsigned int index);
+	void DeleteSuperElevation(unsigned int index);
+	void DeleteCrossfall(unsigned int index);
+	void DeleteLaneSection(unsigned int index);
+	void DeleteObject(unsigned int index);
+	void DeleteSignal(unsigned int index);
+	
+	//-------------------------------------------------
+
+	/**
+	 * Recalculates the chordline geometry of the road
+	 */
+	void RecalculateGeometry();
+
+	//-------------------------------------------------
+	// EVALUATION METHODS
+
+	/**
+	 * Geometry evaluation
+	 */
+	bool CheckGeometryInterval (double s_check);
+	bool CheckGeometryInterval (double s_check, string &roadId);
+	short int GetGeometryCoords(double s_check, double &retX, double &retY);
+	short int GetGeometryCoords(double s_check, double &retX, double &retY, double &retHDG);
+	
+
+	/**
+	 * Other evaluation
+	 */
+	int CheckRoadTypeInterval(double s_check);
+	string GetRoadTypeValue(double s_check);
+
+	int CheckElevationInterval(double s_check);
+	double GetElevationValue (double s_check);
+
+	int CheckSuperElevationInterval(double s_check);
+	double GetSuperElevationValue (double s_check);
+
+	int CheckCrossfallInterval(double s_check);
+	void GetCrossfallValue (double s_check, double &angleLeft, double &angleRight);
+
+	int CheckLaneSectionInterval(double s_check);
+	void FillLaneSectionSample(double s_check, LaneSectionSample &laneSectionSample);
+	
+	//-------------------------------------------------
+
+	/**
+	 * Destructor
+	 */
+	~Road();
+};
+
+
+//----------------------------------------------------------------------------------
+/**
+ * RoadLink class is used to store information about road's predecessors/successors
+ *
+ *
+ *
+ *
+ */
+class RoadLink
+{
+private:
+	/**
+	 * Base properties of a successor/predecessor record
+	 */
+	string mElementType;
+	string mElementId;
+	string mContactPoint;
+public:
+	/**
+	 * Constructor which intializes the base properties
+	 */
+	RoadLink(string elementType, string elementId, string contactPoint);
+	
+	/**
+	 * Setters for the base properties
+	 */
+	void SetElementType(string elementType);
+	void SetElementId(string elementId);
+	void SetContactPoint(string contactPoint);
+	
+
+	/**
+	 * Getters for the base properties
+	 */
+	string GetElementType();
+	string GetElementId();
+	string GetContactPoint();
+};
+
+
+
+//----------------------------------------------------------------------------------
+/**
+ * RoadLink class is used to store information about road's neighbors
+ *
+ *
+ *
+ *
+ */
+class RoadNeighbor
+{
+private:
+	/**
+	 * Base properties of a neighbor record
+	 */
+	string mSide;
+	string mElementId;
+	string mDirection;
+public:
+	/**
+	 * Constructor which intializes the base properties
+	 */
+	RoadNeighbor(string side, string elementId, string direction);
+	
+	/**
+	 * Setters for the base properties
+	 */
+	void SetSide(string side);
+	void SetElementId(string elementId);
+	void SetDirection(string direction);
+	
+	/**
+	 * Getters for the base properties
+	 */
+	string GetSide();
+	string GetElementId();
+	string GetDirection();
+};
+
+//----------------------------------------------------------------------------------
+/**
+ * RoadType class is used to store information about a road type record
+ *
+ *
+ *
+ *
+ */
+class RoadType
+{
+private:
+	/**
+	 * Base properties of a road type
+	 */
+	double mS;
+	string mType;
+public:
+	/**
+	 * Constructor which intializes the base properties
+	 */
+	RoadType (double s, string type);
+	
+	/**
+	 * Setters for the base properties
+	 */
+	void SetS(double value);
+	void SetType(string type);
+	
+	/**
+	 * Getters for the base properties
+	 */
+	double GetS();
+	string GetType();
+};
+
+//----------------------------------------------------------------------------------
+/**
+ * Elevation class is used to store information about a road elevation record
+ * It inherits the Polynom class and has no additional properties
+ *
+ *
+ *
+ */
+class Elevation : public ThirdOrderPolynom
+{
+public:
+	/**
+	 * Constructor which intializes the base properties
+	 */
+	Elevation(double s, double a, double b, double c, double d);
+};
+//----------------------------------------------------------------------------------
+
+
+/**
+ * Superlevation class is used to store information about a road superelevation record
+ * It inherits the Polynom class and has no additional properties
+ *
+ *
+ *
+ */
+class SuperElevation : public ThirdOrderPolynom
+{
+public:
+	/**
+	 * Constructor which intializes the base properties
+	 */
+	SuperElevation(double s, double a, double b, double c, double d);
+};
+//----------------------------------------------------------------------------------
+
+/**
+ * Crossfall class is used to store information about a road superelevation record
+ * It inherits the Polynom class and has one additional properties
+ *
+ *
+ *
+ */
+class Crossfall : public ThirdOrderPolynom
+{
+private:
+	/**
+	 * Base crossfall property
+	 */
+	string mSide;
+	
+public:
+	/**
+	 * Constructor which intializes the base properties
+	 */
+	Crossfall (string side, double s, double a, double b, double c, double d);
+	
+	/**
+	 * Setter for the crossfall side
+	 */
+	void SetSide(string side);
+	
+	/**
+	 * Getter for the crossfall side
+	 */
+	string GetSide();
+};
+
+//----------------------------------------------------------------------------------
+
+
+#endif

+ 853 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/RoadGeometry.cpp

@@ -0,0 +1,853 @@
+#include "RoadGeometry.h"
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+//#define PI 3.14159265358979323846264338327950288
+extern int fresnl( double , double *, double * );
+
+
+//***********************************************************************************
+//Road Geometry Base Class
+//***********************************************************************************
+/**
+ * Constructor that initializes the base properties of teh record
+ */
+RoadGeometry::RoadGeometry(double s, double x, double y, double hdg, double length)
+{
+	mS=s;	mX=x; mY=y, mHdg=hdg, mLength=length;
+	mS2=s+length;
+}
+
+/**
+ * Computes the required vars
+ */
+void RoadGeometry::ComputeVars()
+{}
+
+/**
+ * Clones and returns the new geometry record
+ */
+RoadGeometry* RoadGeometry::Clone() const
+{
+	return new RoadGeometry(mS,mX,mY, mHdg, mLength);
+}
+//-------------------------------------------------
+
+/**
+ * Sets the type of the geometry
+ * 0: Line, 1: Arc, 2: Spiral
+ */
+void RoadGeometry::SetGeomType(short int geomType)
+{	
+	mGeomType = geomType;	
+}
+
+
+/**
+ * Setter for the base properties
+ */
+void RoadGeometry::SetBase(double s, double x, double y, double hdg, double length, bool recalculate)
+{
+	mS=s;
+	mX=x;
+	mY=y;
+	mHdg=hdg;
+	mLength=length;
+	mS2=mS+mLength;
+	if(recalculate) ComputeVars();
+}
+void RoadGeometry::SetS(double s)
+{
+	mS=s;
+	mS2=mS+mLength;
+	ComputeVars();
+}
+void RoadGeometry::SetX(double x)
+{
+	mX=x;
+}
+void RoadGeometry::SetY(double y)
+{
+	mY=y;
+}
+void RoadGeometry::SetHdg(double hdg)
+{
+	mHdg=hdg;
+	ComputeVars();
+}
+void RoadGeometry::SetLength(double length)
+{
+	mLength=length;
+	mS2=mS+mLength;
+	ComputeVars();
+}
+//-------------------------------------------------
+
+/**
+ * Getter for the geometry type
+ */
+short int RoadGeometry::GetGeomType()
+{	
+	return mGeomType;
+}
+
+/**
+ * Getter for the base properties
+ */
+double RoadGeometry::GetS()
+{
+	return mS;
+}
+double RoadGeometry::GetS2()
+{
+	return mS2;
+}
+double RoadGeometry::GetX()
+{
+	return mX;
+}
+double RoadGeometry::GetY()
+{
+	return mY;
+}
+double RoadGeometry::GetHdg()
+{
+	return mHdg;
+}
+double RoadGeometry::GetLength()
+{
+	return mLength;
+}
+
+//-------------------------------------------------
+
+/**
+ * Checks if the sample S gets in the current block interval
+ */
+bool RoadGeometry::CheckInterval (double s_check)
+{
+	if ((s_check >= mS) && (s_check<=mS2))
+		return true;
+	else
+		return false;
+}
+
+/**
+ * Gets the coordinates at the sample S offset
+ */
+void  RoadGeometry::GetCoords(double s_check, double &retX, double &retY)
+{
+	double tmp;
+	GetCoords(s_check, retX, retY, tmp);
+}
+void RoadGeometry::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
+{}
+
+
+
+//***********************************************************************************
+//Line geometry 
+//***********************************************************************************
+/**
+ * Constructor that initializes the base properties of the record
+ */
+GeometryLine::GeometryLine (double s, double x, double y, double hdg, double length):	RoadGeometry(s, x, y, hdg, length)
+{	
+	SetGeomType(0);	
+}
+
+/**
+ * Clones and returns the new geometry record
+ */
+RoadGeometry* GeometryLine::Clone() const
+{
+	GeometryLine* ret=new GeometryLine(mS,mX,mY, mHdg, mLength);
+	return ret;
+}
+
+//-------------------------------------------------
+
+/**
+ * Setter for the base properties
+ */
+void GeometryLine::SetAll(double s, double x, double y, double hdg, double length)
+{
+	SetBase(s,x,y,hdg,length,false);
+	ComputeVars();
+}
+
+//-------------------------------------------------
+
+/**
+ * Gets the coordinates at the sample S offset
+ */
+void GeometryLine::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
+{
+	double newLength=s_check-mS;
+	//find the end of the chord line
+	retX=mX+cos(mHdg)*newLength;
+	retY=mY+sin(mHdg)*newLength;
+
+	retHDG=mHdg;
+}
+
+
+
+
+
+//***********************************************************************************
+//Arc geometry
+//***********************************************************************************
+/**
+ * Constructor that initializes the base properties of the record
+ */
+GeometryArc::GeometryArc (double s, double x, double y, double hdg, double length, double curvature):	RoadGeometry(s, x, y, hdg, length)
+{
+    SetGeomType(2);
+	mCurvature=curvature;
+
+	ComputeVars();
+}
+
+/**
+ * Computes the required vars
+ */
+void GeometryArc::ComputeVars()
+{
+	double radius=0.0;
+	//if curvature is 0, radius is also 0, otherwise, radius is 1/curvature
+	if (fabs(mCurvature)>1.00e-15)
+	{
+		radius = fabs(1.0/mCurvature);
+	}
+	//calculate the start angle for the arc plot
+	if (mCurvature<=0)
+		mStartAngle=mHdg+M_PI_2; 
+	else
+		mStartAngle=mHdg-M_PI_2;
+
+	mCircleX=mX+cos(mStartAngle-M_PI)*radius;
+	mCircleY=mY+sin(mStartAngle-M_PI)*radius;
+}
+
+/**
+ * Clones and returns the new geometry record
+ */
+RoadGeometry* GeometryArc::Clone() const
+{
+	GeometryArc* ret=new GeometryArc(mS,mX,mY, mHdg, mLength, mCurvature);
+	return ret;
+}
+
+//-------------------------------------------------
+
+/**
+ * Setter for the base properties
+ */
+void GeometryArc::SetAll(double s, double x, double y, double hdg, double length, double curvature)
+{
+	SetBase(s,x,y,hdg,length,false);
+	mCurvature=curvature;
+	
+	ComputeVars();
+}
+void GeometryArc::SetCurvature(double curvature)
+{
+	mCurvature=curvature;
+	ComputeVars();
+}
+
+//-------------------------------------------------
+
+/**
+ * Getter for the base properties
+ */
+double GeometryArc::GetCurvature()
+{
+	return mCurvature;
+}
+
+//-------------------------------------------------
+
+/**
+ * Gets the coordinates at the sample S offset
+ */
+void GeometryArc::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
+{
+	//s from the beginning of the segment
+	double currentLength = s_check - mS;
+	double endAngle=mStartAngle;
+	double radius=0.0;
+	//if curvature is 0, radius is also 0, so don't add anything to the initial radius, 
+	//otherwise, radius is 1/curvature so the central angle can be calculated and added to the initial direction
+	if (fabs(mCurvature)>1.00e-15)
+	{
+		endAngle+= currentLength/(1.0/mCurvature);
+		radius = fabs(1.0/mCurvature);
+	}
+
+	//coords on the arc for given s value
+	retX=mCircleX+cos(endAngle)*radius;
+	retY=mCircleY+sin(endAngle)*radius;
+
+	//heading at the given position
+	if (mCurvature<=0)
+		retHDG=endAngle-M_PI_2; 
+	else
+		retHDG=endAngle+M_PI_2;
+}
+
+
+
+
+
+
+//***********************************************************************************
+//Spiral geometry
+//***********************************************************************************
+const double GeometrySpiral::sqrtPiO2=sqrt(M_PI_2);
+/**
+ * Constructor that initializes the base properties of the record
+ */
+GeometrySpiral::GeometrySpiral (double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd):	RoadGeometry(s, x, y, hdg, length)
+{
+    SetGeomType(1);
+	mCurvatureStart=curvatureStart;
+	mCurvatureEnd=curvatureEnd;
+	ComputeVars();
+}
+
+/**
+ * Computes the required vars
+ */
+void GeometrySpiral::ComputeVars()
+{
+	mA=0;
+
+	//if the curvatureEnd is the non-zero curvature, then the motion is in normal direction along the spiral
+	if ((fabs(mCurvatureEnd)>1.00e-15)&&(fabs(mCurvatureStart)<=1.00e-15))
+	{
+		mNormalDir=true;
+		mCurvature=mCurvatureEnd;
+		//Calculate the normalization term : a = 1.0/sqrt(2*End_Radius*Total_Curve_Length) 
+		mA=1.0/sqrt(2*1.0/fabs(double(mCurvature))*mLength);			
+		//Denormalization Factor
+		mDenormalizeFactor=1.0/mA;	
+
+		//Calculate the sine and cosine of the heading angle used to rotate the spiral according to the heading
+		mRotCos=cos(mHdg);
+		mRotSin=sin(mHdg);
+	}
+	//else the motion is in the inverse direction along the spiral
+	else
+	{
+		mNormalDir=false;
+		mCurvature=mCurvatureStart;
+		//Calculate the normalization term : a = 1.0/sqrt(2*End_Radius*Total_Curve_Length) 
+		mA=1.0/sqrt(2*1.0/fabs(mCurvature)*mLength);			
+
+		//Because we move in the inverse direction, we need to rotate the curve according to the heading
+		//around the last point of the normalized spiral
+		//Calculate the total length, normalize it and divide by sqrtPiO2, then, calculate the position of the final point.
+		double L=(mS2-mS)*mA/sqrtPiO2;							
+		fresnl(L,&mEndY,&mEndX);
+		//Invert the curve if the curvature is negative
+		if (mCurvature<0)
+			mEndY=-mEndY;
+
+		//Denormalization factor
+		mDenormalizeFactor=1.0/mA;									
+		//Find the x,y coords of the final point of the curve in local curve coordinates
+		mEndX*=mDenormalizeFactor*sqrtPiO2;						
+		mEndY*=mDenormalizeFactor*sqrtPiO2;
+
+		//Calculate the tangent angle
+		differenceAngle=L*L*(sqrtPiO2*sqrtPiO2);
+		double diffAngle;
+		//Calculate the tangent and heading angle difference that will be used to rotate the spiral
+		if (mCurvature<0)
+		{
+			diffAngle=mHdg-differenceAngle-M_PI;
+		}
+		else
+		{
+			diffAngle=mHdg+differenceAngle-M_PI;
+		}
+
+		//Calculate the sine and cosine of the difference angle
+		mRotCos=cos(diffAngle);
+		mRotSin=sin(diffAngle);
+	}
+}
+
+/**
+ * Clones and returns the new geometry record
+ */
+RoadGeometry* GeometrySpiral::Clone() const
+{
+	GeometrySpiral* ret=new GeometrySpiral(mS,mX,mY, mHdg, mLength, mCurvatureStart, mCurvatureEnd);
+	return ret;
+}
+
+
+//-------------------------------------------------
+
+/**
+ * Setter for the base properties
+ */
+void GeometrySpiral::SetAll(double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd)
+{
+	SetBase(s,x,y,hdg,length,false);
+	mCurvatureStart=curvatureStart;
+	mCurvatureEnd=curvatureEnd;
+	ComputeVars();
+}
+void GeometrySpiral::SetCurvatureStart(double curvature)
+{
+	mCurvatureStart=curvature;
+	ComputeVars();
+}
+void GeometrySpiral::SetCurvatureEnd(double curvature)
+{
+	mCurvatureEnd=curvature;
+	ComputeVars();
+}
+
+//-------------------------------------------------
+
+/**
+ * Getter for the base properties
+ */
+double GeometrySpiral::GetCurvatureStart()
+{
+	return mCurvatureStart;
+}
+double GeometrySpiral::GetCurvatureEnd()
+{
+	return mCurvatureEnd;
+}
+
+//-------------------------------------------------
+/**
+ * Gets the coordinates at the sample S offset
+ */
+void GeometrySpiral::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
+{
+	double l=0.0;
+	double tmpX=0.0, tmpY=0.0;
+
+	//Depending on the moving direction, calculate the length of the curve from its beginning to the current point and normalize
+	//it by multiplying with the "a" normalization term
+	//Cephes lib for solving Fresnel Integrals, uses cos/sin (PI/2 * X^2) format in its function.
+	//So, in order to use the function, transform the argument (which is just L) by dividing it by the sqrt(PI/2) factor and multiply the results by it.
+	if (mNormalDir)
+	{ 
+		l=(s_check-mS)*mA/sqrtPiO2;
+	}
+	else
+	{
+		l=(mS2-s_check)*mA/sqrtPiO2;		
+	}
+
+	//Solve the Fresnel Integrals
+	fresnl(l,&tmpY,&tmpX);
+	//If the curvature is negative, invert the curve on the Y axis
+	if (mCurvature<0)
+		tmpY=-tmpY;
+
+	//Denormalize the results and multiply by the sqrt(PI/2) term
+	tmpX*=mDenormalizeFactor*sqrtPiO2;	
+	tmpY*=mDenormalizeFactor*sqrtPiO2;
+
+	//Calculate the heading at the found position. Kill the sqrt(PI/2) term that was added to the L
+	l=(s_check-mS)*mA;
+	double tangentAngle = l*l;
+	if (mCurvature<0)
+		tangentAngle=-tangentAngle;
+	retHDG=mHdg+tangentAngle;
+
+
+	if (!mNormalDir)
+	{
+		//If we move in the inverse direction, translate the spiral in order to rotate around its final point
+		tmpX-=mEndX;	
+		tmpY-=mEndY;
+		//also invert the spiral in the y axis
+		tmpY=-tmpY;
+	}
+
+	//Translate the curve to the required position and rotate it according to the heading
+	retX=mX+ tmpX*mRotCos-tmpY*mRotSin;
+	retY=mY+ tmpY*mRotCos+tmpX*mRotSin;
+}
+
+
+
+
+
+//***********************************************************************************
+//Cubic Polynom geometry. Has to be implemented
+//***********************************************************************************
+/**
+ * Constructor that initializes the base properties of the record
+ */
+GeometryPoly3::GeometryPoly3 (double s, double x, double y, double hdg, double length, double a, double b,double c, double d ):	RoadGeometry(s, x, y, hdg, length)
+{	
+	SetGeomType(3); mA=a; mB=b; mC=c; mD=d;	
+}
+
+/**
+ * Clones and returns the new geometry record
+ */
+RoadGeometry* GeometryPoly3::Clone() const
+{
+	GeometryPoly3* ret=new GeometryPoly3(mS,mX,mY, mHdg, mLength, mA, mB, mC, mD);
+	return ret;
+}
+
+//-------------------------------------------------
+/**
+ * Setter for the base properties
+ */
+void GeometryPoly3::SetAll(double s, double x, double y, double hdg, double length, double a,double b,double c,double d)
+{
+	SetBase(s,x,y,hdg,length,false);
+	mA=a;
+	mB=b;
+	mC=c;
+	mD=d;
+	ComputeVars();
+}
+
+
+//***********************************************************************************
+//Cubic Polynom geometry. Has to be implemented.  Added By Yuchuli
+//***********************************************************************************
+
+/**
+ * Constructor that initializes the base properties of the record
+ */
+GeometryParamPoly3::GeometryParamPoly3 (double s, double x, double y, double hdg, double length,double ua,double ub,double uc,double ud,double va, double vb, double vc,double vd  ):	RoadGeometry(s, x, y, hdg, length)
+{
+    SetGeomType(4); muA=ua; muB=ub; muC=uc; muD=ud;mvA=va; mvB=vb; mvC=vc; mvD=vd;
+}
+
+/**
+ * Clones and returns the new geometry record
+ */
+RoadGeometry* GeometryParamPoly3::Clone() const
+{
+    GeometryParamPoly3* ret=new GeometryParamPoly3(mS,mX,mY, mHdg, mLength, muA, muB, muC, muD,mvA,mvB,mvC,mvD);
+    return ret;
+}
+
+//-------------------------------------------------
+/**
+ * Setter for the base properties
+ */
+void GeometryParamPoly3::SetAll(double s, double x, double y, double hdg, double length, double ua,double ub,double uc,double ud,double va, double vb, double vc,double vd )
+{
+    SetBase(s,x,y,hdg,length,false);
+    muA=ua;
+    muB=ub;
+    muC=uc;
+    muD=ud;
+    mvA=va;
+    mvB=vb;
+    mvC=vc;
+    mvD=vd;
+    ComputeVars();
+}
+
+double GeometryParamPoly3::GetuA(){return muA;}
+double GeometryParamPoly3::GetuB(){return muB;}
+double GeometryParamPoly3::GetuC(){return muC;}
+double GeometryParamPoly3::GetuD(){return muD;}
+double GeometryParamPoly3::GetvA(){return mvA;}
+double GeometryParamPoly3::GetvB(){return mvB;}
+double GeometryParamPoly3::GetvC(){return mvC;}
+double GeometryParamPoly3::GetvD(){return mvD;}
+
+//***********************************************************************************
+//Base class for Geometry blocks
+//***********************************************************************************
+/**
+ * Constructor
+ */
+GeometryBlock::GeometryBlock()
+{}
+
+/**
+ * Copy constructor
+ */
+GeometryBlock::GeometryBlock(const GeometryBlock& geomBlock)
+{
+	for (vector<RoadGeometry*>::const_iterator member = geomBlock.mGeometryBlockElement.begin();	member != geomBlock.mGeometryBlockElement.end();	 member++)
+		mGeometryBlockElement.push_back((*member)->Clone());
+
+}
+
+/**
+ * Assignment operator overload
+ */
+const GeometryBlock& GeometryBlock::operator=(const GeometryBlock& otherGeomBlock)
+{
+	if (this!= &otherGeomBlock)
+	{
+
+		for (vector<RoadGeometry*>::iterator member = mGeometryBlockElement.begin();	member != mGeometryBlockElement.end();	 member++)
+		{
+			if(GeometryLine *line = dynamic_cast<GeometryLine *>(*member))
+			{
+				delete line;
+			}
+			else if(GeometryArc *arc = dynamic_cast<GeometryArc *>(*member))
+			{
+				delete arc;
+			}
+			else if(GeometrySpiral *spiral = dynamic_cast<GeometrySpiral *>(*member))
+			{
+				delete spiral;
+			}
+			else if(GeometryPoly3 *poly = dynamic_cast<GeometryPoly3 *>(*member))
+			{
+				delete poly;
+			}
+		}
+		mGeometryBlockElement.clear();
+
+		for (vector<RoadGeometry*>::const_iterator member = otherGeomBlock.mGeometryBlockElement.begin();	member != otherGeomBlock.mGeometryBlockElement.end();	 member++)
+			mGeometryBlockElement.push_back((*member)->Clone());
+	}
+	return *this;
+}
+
+
+//-------------------------------------------------
+
+/**
+ * Methods used to add geometry recors to the geometry record vector
+ */
+void GeometryBlock::AddGeometryLine(double s, double x, double y, double hdg, double length)
+{	
+	mGeometryBlockElement.push_back(new GeometryLine(s, x, y, hdg, length));	
+}
+void GeometryBlock::AddGeometryArc(double s, double x, double y, double hdg, double length, double curvature)
+{	
+	mGeometryBlockElement.push_back(new GeometryArc(s, x, y, hdg, length, curvature));	
+}
+void GeometryBlock::AddGeometrySpiral(double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd)
+{	
+	mGeometryBlockElement.push_back(new GeometrySpiral(s, x, y, hdg, length, curvatureStart, curvatureEnd));	
+}
+void GeometryBlock::AddGeometryPoly3(double s, double x, double y, double hdg, double length, double a,double b,double c,double d)
+{	
+	mGeometryBlockElement.push_back(new GeometryPoly3(s, x, y, hdg, length, a, b, c, d));	
+}
+void GeometryBlock::AddGeometryParamPoly3(double s, double x, double y, double hdg, double length, double ua, double ub, double uc, double ud, double va, double vb, double vc, double vd)
+{
+    mGeometryBlockElement.push_back(new GeometryParamPoly3(s,x,y,hdg,length,ua,ub,uc,ud,va,vb,vc,vd));
+}
+
+//-------------------------------------------------
+
+/**
+ * Getter for the geometry record at a given index position of the vector
+ */
+RoadGeometry* GeometryBlock::GetGeometryAt(int index)
+{
+	return mGeometryBlockElement.at(index);
+}
+
+/**
+ * Getter for the overal block length (summ of geometry record lengths)
+ */
+double GeometryBlock::GetBlockLength()
+{
+	double lTotal=0;
+	for (unsigned int i=0;i<mGeometryBlockElement.size();i++)
+	{
+		lTotal+=mGeometryBlockElement.at(i)->GetLength();
+	}
+	return lTotal;
+}
+
+/**
+ *  Checks if the block is a straight line block or a turn
+ */
+bool GeometryBlock::CheckIfLine()
+{
+	if(mGeometryBlockElement.size()>1) return false;
+	else return true;
+}
+
+//-------------------------------------------------
+
+/**
+ * Recalculates the geometry blocks when one of the geometry records is modified
+ * Makes sure that every geometry records starts where the previous record ends
+ */
+void GeometryBlock::Recalculate(double s, double x, double y, double hdg)
+{
+	double lS=s;
+	double lX=x;
+	double lY=y;
+	double lHdg=hdg;
+
+	if(mGeometryBlockElement.size()==1)
+	{
+		GeometryLine *lGeometryLine	=  static_cast<GeometryLine*>(mGeometryBlockElement.at(0));
+		if(lGeometryLine!=NULL)
+		{
+			// Updates the line to reflect the changes of the previous block
+			lGeometryLine->SetBase(lS,lX,lY,lHdg,lGeometryLine->GetLength());
+		}
+	}
+	else if(mGeometryBlockElement.size()==3)
+	{
+		GeometrySpiral *lGeometrySpiral1	=  static_cast<GeometrySpiral*>(mGeometryBlockElement.at(0));
+		GeometryArc *lGeometryArc			=  static_cast<GeometryArc*>(mGeometryBlockElement.at(1));
+		GeometrySpiral *lGeometrySpiral2	=  static_cast<GeometrySpiral*>(mGeometryBlockElement.at(2));
+		if(lGeometrySpiral1!=NULL && lGeometryArc!=NULL && lGeometrySpiral2!=NULL)
+		{
+			// Updates the first spiral to reflect the changes of the previous block
+			lGeometrySpiral1->SetBase(lS,lX,lY,lHdg,lGeometrySpiral1->GetLength());
+
+			// Reads the new coords of the spiral
+			lS=lGeometrySpiral1->GetS2();
+			lGeometrySpiral1->GetCoords(lS,lX,lY,lHdg);
+
+			// Updates the arc to reflect the changes to the first spiral
+			lGeometryArc->SetBase(lS,lX,lY,lHdg,lGeometryArc->GetLength());
+
+			// Reads the new coords of the arc
+			lS=lGeometryArc->GetS2();
+			lGeometryArc->GetCoords(lS,lX,lY,lHdg);
+
+			// Updates the second spiral to reflect hte changes to the arc
+			lGeometrySpiral2->SetBase(lS,lX,lY,lHdg,lGeometrySpiral2->GetLength());
+		}
+	}
+}
+
+//-------------------------------------------------
+
+/**
+ *  Gets the S at the end of the block
+ */
+double GeometryBlock::GetLastS2()
+{
+	if(mGeometryBlockElement.size()>0)
+		return mGeometryBlockElement.at(mGeometryBlockElement.size()-1)->GetS2();
+	else
+		return 0;
+}
+
+/**
+ *  Gets the last geometry in the geometry vector
+ */
+RoadGeometry* GeometryBlock::GetLastGeometry()
+{
+	return mGeometryBlockElement.at(mGeometryBlockElement.size()-1);
+}
+
+/**
+ *  Gets the coordinates at the end of the last geometry
+ */
+short int GeometryBlock::GetLastCoords(double &s, double &retX, double &retY, double &retHDG)
+{
+	int lSize = mGeometryBlockElement.size();
+	if(lSize>0)
+	{
+		RoadGeometry* lGeometry = mGeometryBlockElement.at(lSize-1);
+		s = lGeometry->GetS2();
+		lGeometry->GetCoords(s, retX, retY, retHDG);
+	}
+	else
+	{
+		s=0;
+		retX=0;
+		retY=0;
+		retHDG=0;
+	}
+	return 0;
+}
+
+/**
+ *  Check if sample S belongs to this block
+ */
+bool GeometryBlock::CheckInterval(double s_check)
+{
+	for (unsigned int i=0;i<mGeometryBlockElement.size();i++)
+	{
+		//if the s_check belongs to one of the geometries
+		if (mGeometryBlockElement.at(i)->CheckInterval(s_check))
+			return true;
+	}
+	return false;
+}
+
+/**
+ *  Gets the coordinates at the sample S offset
+ */
+short int GeometryBlock::GetCoords(double s_check, double &retX, double &retY)
+{
+	double tmp;
+	return GetCoords(s_check, retX, retY, tmp);
+}
+
+/**
+ *  Gets the coordinates and heading at the end of the last geometry 
+ */
+short int  GeometryBlock::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
+{
+	// go through all the elements
+	for (unsigned int i=0;i<mGeometryBlockElement.size();i++)
+	{
+		//if the s_check belongs to one of the geometries
+		if (mGeometryBlockElement.at(i)->CheckInterval(s_check))
+		{
+			//get the x,y coords and return the type of the geometry
+			mGeometryBlockElement.at(i)->GetCoords(s_check, retX, retY, retHDG);
+			return mGeometryBlockElement.at(i)->GetGeomType();
+		}
+	}
+	//if nothing found, return -999
+	return -999;
+
+}
+
+//-------------------------------------------------
+/**
+ *  Destructor
+ */
+GeometryBlock::~GeometryBlock()
+{
+	// Clears the geometry record vector
+	for (vector<RoadGeometry*>::iterator member = mGeometryBlockElement.begin();	member != mGeometryBlockElement.end();	 member++)
+	{
+		if(GeometryLine *line = dynamic_cast<GeometryLine *>(*member))
+		{
+			delete line;
+		}
+		else if(GeometryArc *arc = dynamic_cast<GeometryArc *>(*member))
+		{
+			delete arc;
+		}
+		else if(GeometrySpiral *spiral = dynamic_cast<GeometrySpiral *>(*member))
+		{
+			delete spiral;
+		}
+		else if(GeometryPoly3 *poly = dynamic_cast<GeometryPoly3 *>(*member))
+		{
+			delete poly;
+		}
+        else if(GeometryParamPoly3 *parampoly = dynamic_cast<GeometryParamPoly3 *>(*member))
+        {
+            delete parampoly;
+        }
+	}
+	mGeometryBlockElement.clear();
+}
+
+//----------------------------------------------------------------------------------

+ 435 - 0
天津大学/tjuvv7-src/src/common/common/xodr/OpenDrive/RoadGeometry.h

@@ -0,0 +1,435 @@
+#ifndef ROADGEOMETRY_H
+#define ROADGEOMETRY_H
+
+#include <vector>
+#include <string>
+
+//Prototypes
+class RoadGeometry;
+class GeometryLine;
+class GeometrySpiral;
+class GeometryArc;
+
+using std::vector;
+using std::string;
+
+
+/**
+ * RoadGeometry class is responsible for storing the basic chordline geometry properties
+ *
+ */
+class RoadGeometry
+{
+protected:
+	/**
+	 * Base record properties
+	 */
+	double mS;
+	double mX;
+	double mY;
+	double mHdg;
+	double mLength;
+	double mS2;
+    short int mGeomType;	//0-line, 1-arc, 2-spiral 3-poly3 4-parampoly3
+public:
+	/**
+	 * Constructor that initializes the base properties of teh record
+	 */
+	RoadGeometry(double s, double x, double y, double hdg, double length);
+	
+	/**
+	 * Clones and returns the new geometry record
+	 */
+	virtual RoadGeometry* Clone() const;
+	
+	//-------------------------------------------------
+
+	/**
+	 * Sets the type of the geometry
+	 * 0: Line, 1: Arc, 2: Spiral
+	 */
+	void SetGeomType(short int geomType);
+	
+	/**
+	 * Setter for the base properties
+	 */
+	void SetBase(double s, double x, double y, double hdg, double length, bool recalculate=true);
+	void SetS(double s);
+	void SetX(double x);
+	void SetY(double y);
+	void SetHdg(double hdg);
+	void SetLength(double length);
+
+	//-------------------------------------------------
+	/**
+	 * Getter for the geometry type
+	 */
+	short int GetGeomType();
+	
+	/**
+	 * Getter for the base properties
+	 */
+	double GetS();
+	double GetS2();
+	double GetX();
+	double GetY();
+	double GetHdg();
+	double GetLength();
+
+	//-------------------------------------------------
+
+	/**
+	 * Evaluation methods
+	 */
+	virtual bool CheckInterval (double s_check);
+	virtual void GetCoords(double s_check, double &retX, double &retY);
+	virtual void GetCoords(double s_check, double &retX, double &retY, double &retHDG);
+protected:
+
+	/**
+	 * Computes the required vars
+	 */
+	virtual void ComputeVars();
+};
+
+
+//----------------------------------------------------------------------------------
+/**
+ * GeometryLine inherits the RoadGeometry class but adds no additional properties
+ *
+ */
+class GeometryLine:public RoadGeometry
+{
+public:
+	/**
+	 * Constructor that initializes the base properties of the record
+	 */
+	GeometryLine (double s, double x, double y, double hdg, double length);
+
+	/**
+	 * Clones and returns the new geometry record
+	 */
+	RoadGeometry* Clone() const;
+	
+	//-------------------------------------------------
+
+	/**
+	 * Setter for the base properties
+	 */
+	void SetAll(double s, double x, double y, double hdg, double length);
+
+	//-------------------------------------------------
+
+	/**
+	 * Gets the coordinates at the sample S offset
+	 */
+	void GetCoords(double s_check, double &retX, double &retY, double &retHDG);
+
+};
+//----------------------------------------------------------------------------------
+/**
+ * GeometryArc inherits the RoadGeometry class and adds Curvature property
+ *
+ */
+class GeometryArc: public RoadGeometry
+{
+private:
+	/**
+	 * Base record properties
+	 */
+	double mCurvature;
+	
+	/**
+	 * Optimization related variables
+	 */ 
+	double mCircleX;
+	double mCircleY;
+
+	/**
+	 * Computation variables
+	 */
+	double mStartAngle;
+
+public:
+	/**
+	 * Constructor that initializes the base properties of the record
+	 */
+	GeometryArc (double s, double x, double y, double hdg, double length, double curvature);
+
+	/**
+	 * Clones and returns the new geometry record
+	 */
+	RoadGeometry* Clone() const;
+
+	//-------------------------------------------------
+	
+	/**
+	 * Setter for the base properties
+	 */
+	void SetAll(double s, double x, double y, double hdg, double length, double curvature);
+	void SetCurvature(double curvature);
+
+	//-------------------------------------------------
+
+	/**
+	 * Getter for the base properties
+	 */
+	double GetCurvature();
+	
+	//-------------------------------------------------
+
+	/**
+	 * Gets the coordinates at the sample S offset
+	 */
+	void GetCoords(double s_check, double &retX, double &retY, double &retHDG);
+protected:
+
+	/**
+	 * Computes the required vars
+	 */
+	virtual void ComputeVars();
+};
+
+
+
+//----------------------------------------------------------------------------------
+/**
+ * GeometrySpiral inherits the RoadGeometry class and adds Curvature properties
+ *
+ */
+class GeometrySpiral: public RoadGeometry
+{
+private:
+	/**
+	 * Base record properties
+	 */
+	double mCurvatureStart;
+	double mCurvatureEnd;
+
+	/**
+	 * Computation variables
+	 */
+	static const double sqrtPiO2;
+	double mA;
+	double mCurvature;
+	double mDenormalizeFactor;
+	double mEndX;
+	double mEndY;
+	bool mNormalDir;
+
+	double differenceAngle;
+	double mRotCos;
+	double mRotSin;
+
+public:
+	/**
+	 * Constructor that initializes the base properties of the record
+	 */
+	GeometrySpiral (double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd);
+
+	/**
+	 * Clones and returns the new geometry record
+	 */
+	RoadGeometry* Clone() const;
+
+	//-------------------------------------------------
+
+	/**
+	 * Setter for the base properties
+	 */
+	void SetAll(double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd);
+	void SetCurvatureStart(double curvature);
+	void SetCurvatureEnd(double curvature);
+	
+	//-------------------------------------------------
+	/**
+	 * Getter for the base properties
+	 */
+	double GetCurvatureStart();
+	double GetCurvatureEnd();
+	
+	//-------------------------------------------------
+	/**
+	 * Gets the coordinates at the sample S offset
+	 */
+	void GetCoords(double s_check, double &retX, double &retY, double &retHDG);
+protected:
+
+	/**
+	 * Computes the required vars
+	 */
+	virtual void ComputeVars();
+};
+
+
+//----------------------------------------------------------------------------------
+/**
+ * GeometryPoly3 inherits the RoadGeometry class and adds polynomial properties
+ *
+ */
+class GeometryPoly3: public RoadGeometry
+{
+private:
+	/**
+	 * Base record properties
+	 */
+	double mA;
+	double mB;
+	double mC;
+	double mD;
+public:
+	/**
+	 * Constructor that initializes the base properties of the record
+	 */
+	GeometryPoly3 (double s, double x, double y, double hdg, double length, double a,double b,double c,double d );
+
+	/**
+	 * Clones and returns the new geometry record
+	 */
+	RoadGeometry* Clone() const;
+	
+	//-------------------------------------------------
+	/**
+	 * Setter for the base properties
+	 */
+	void SetAll(double s, double x, double y, double hdg, double length, double a,double b,double c,double d);
+
+};
+
+//----------------------------------------------------------------------------------
+/**
+ * GeometryPoly3 inherits the RoadGeometry class and adds polynomial properties, Added By Yuchuli,2019.11.1
+ *
+ */
+class GeometryParamPoly3: public RoadGeometry
+{
+private:
+    /**
+     * Base record properties
+     */
+    double muA;
+    double muB;
+    double muC;
+    double muD;
+
+    double mvA;
+    double mvB;
+    double mvC;
+    double mvD;
+public:
+    /**
+     * Constructor that initializes the base properties of the record
+     */
+    GeometryParamPoly3 (double s, double x, double y, double hdg, double length, double ua,double ub,double uc,double ud,double va, double vb, double vc,double vd );
+
+    /**
+     * Clones and returns the new geometry record
+     */
+    RoadGeometry* Clone() const;
+
+    //-------------------------------------------------
+    /**
+     * Setter for the base properties
+     */
+    void SetAll(double s, double x, double y, double hdg, double length, double a,double b,double c,double d,double va, double vb, double vc,double vd );
+
+
+    double GetuA();
+    double GetuB();
+    double GetuC();
+    double GetuD();
+    double GetvA();
+    double GetvB();
+    double GetvC();
+    double GetvD();
+};
+
+
+
+//----------------------------------------------------------------------------------
+/**
+ * GeometryBlock is a class used to combine multiple geometry records into blocks.
+ * The basic use for this is to combine spiral-arc-spiral sequence of records into 
+ * a signel "Turn" block for an easier way to define turns, keeping close to the
+ * road building practice of curvature use for transitions between straight segments and arcs
+ */
+class GeometryBlock
+{
+private:
+	/**
+	 * Vector of geometry records that make up a block
+	 */
+	vector<RoadGeometry*> mGeometryBlockElement;
+public:
+	/**
+	 * Constructor
+	 */
+	GeometryBlock();
+	
+	/**
+	 * Copy constructor
+	 */
+	GeometryBlock(const GeometryBlock& geomBlock);
+
+	/**
+	 * Assignment operator overload
+	 */
+	const GeometryBlock& operator=(const GeometryBlock& otherGeomBlock);
+	
+	//-------------------------------------------------
+
+	/**
+	 * Methods used to add geometry recors to the geometry record vector
+	 */
+	void AddGeometryLine(double s, double x, double y, double hdg, double length);
+	void AddGeometryArc(double s, double x, double y, double hdg, double length, double curvature);
+	void AddGeometrySpiral(double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd);
+	void AddGeometryPoly3(double s, double x, double y, double hdg, double length, double a,double b,double c,double d);
+    void AddGeometryParamPoly3(double s, double x, double y, double hdg, double length, double ua,double ub,double uc,double ud,double va,double vb,double vc,double vd);
+	
+	//-------------------------------------------------
+
+	/**
+	 * Getter for the geometry record at a given index position of the vector
+	 */
+	RoadGeometry* GetGeometryAt(int index);
+
+	/**
+	 * Getter for the overal block length (summ of geometry record lengths)
+	 */
+	double GetBlockLength();
+
+	/**
+	 *  Checks if the block is a straight line block or a turn
+	 */
+	bool CheckIfLine();
+	
+	//-------------------------------------------------
+
+	/**
+	 * Recalculates the geometry blocks when one of the geometry records is modified
+	 * Makes sure that every geometry records starts where the previous record ends
+	 */
+	void Recalculate(double s, double x, double y, double hdg);
+
+	//-------------------------------------------------
+
+	/**
+	 *  Evaluation methods
+	 */
+	double GetLastS2();
+	RoadGeometry* GetLastGeometry();
+	virtual short int GetLastCoords(double &s, double &retX, double &retY, double &retHDG);
+	bool CheckInterval(double s_check);
+	virtual short int GetCoords(double s_check, double &retX, double &retY);
+	virtual short int GetCoords(double s_check, double &retX, double &retY, double &retHDG);
+
+	//-------------------------------------------------
+	/**
+	 *  Destructor
+	 */
+	~GeometryBlock();
+};
+
+
+#endif

+ 116 - 0
天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinystr.cpp

@@ -0,0 +1,116 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
+ */
+
+
+#ifndef TIXML_USE_STL
+
+#include "tinystr.h"
+
+// Error value for find primitive
+const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
+
+
+// Null rep.
+TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
+
+
+void TiXmlString::reserve (size_type cap)
+{
+	if (cap > capacity())
+	{
+		TiXmlString tmp;
+		tmp.init(length(), cap);
+		memcpy(tmp.start(), data(), length());
+		swap(tmp);
+	}
+}
+
+
+TiXmlString& TiXmlString::assign(const char* str, size_type len)
+{
+	size_type cap = capacity();
+	if (len > cap || cap > 3*(len + 8))
+	{
+		TiXmlString tmp;
+		tmp.init(len);
+		memcpy(tmp.start(), str, len);
+		swap(tmp);
+	}
+	else
+	{
+		memmove(start(), str, len);
+		set_size(len);
+	}
+	return *this;
+}
+
+
+TiXmlString& TiXmlString::append(const char* str, size_type len)
+{
+	size_type newsize = length() + len;
+	if (newsize > capacity())
+	{
+		reserve (newsize + capacity());
+	}
+	memmove(finish(), str, len);
+	set_size(newsize);
+	return *this;
+}
+
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	tmp.reserve(a.length() + b.length());
+	tmp += a;
+	tmp += b;
+	return tmp;
+}
+
+TiXmlString operator + (const TiXmlString & a, const char* b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
+	tmp.reserve(a.length() + b_len);
+	tmp += a;
+	tmp.append(b, b_len);
+	return tmp;
+}
+
+TiXmlString operator + (const char* a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
+	tmp.reserve(a_len + b.length());
+	tmp.append(a, a_len);
+	tmp += b;
+	return tmp;
+}
+
+
+#endif	// TIXML_USE_STL

+ 319 - 0
天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinystr.h

@@ -0,0 +1,319 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
+ *
+ * - completely rewritten. compact, clean, and fast implementation.
+ * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
+ * - fixed reserve() to work as per specification.
+ * - fixed buggy compares operator==(), operator<(), and operator>()
+ * - fixed operator+=() to take a const ref argument, following spec.
+ * - added "copy" constructor with length, and most compare operators.
+ * - added swap(), clear(), size(), capacity(), operator+().
+ */
+
+#ifndef TIXML_USE_STL
+
+#ifndef TIXML_STRING_INCLUDED
+#define TIXML_STRING_INCLUDED
+
+#include <assert.h>
+#include <string.h>
+
+/*	The support for explicit isn't that universal, and it isn't really
+	required - it is used to check that the TiXmlString class isn't incorrectly
+	used. Be nice to old compilers and macro it here:
+*/
+#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
+	// Microsoft visual studio, version 6 and higher.
+	#define TIXML_EXPLICIT explicit
+#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+	// GCC version 3 and higher.s
+	#define TIXML_EXPLICIT explicit
+#else
+	#define TIXML_EXPLICIT
+#endif
+
+
+/*
+   TiXmlString is an emulation of a subset of the std::string template.
+   Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
+   Only the member functions relevant to the TinyXML project have been implemented.
+   The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
+   a string and there's no more room, we allocate a buffer twice as big as we need.
+*/
+class TiXmlString
+{
+  public :
+	// The size type used
+  	typedef size_t size_type;
+
+	// Error value for find primitive
+	static const size_type npos; // = -1;
+
+
+	// TiXmlString empty constructor
+	TiXmlString () : rep_(&nullrep_)
+	{
+	}
+
+	// TiXmlString copy constructor
+	TiXmlString ( const TiXmlString & copy) : rep_(0)
+	{
+		init(copy.length());
+		memcpy(start(), copy.data(), length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
+	{
+		init( static_cast<size_type>( strlen(copy) ));
+		memcpy(start(), copy, length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
+	{
+		init(len);
+		memcpy(start(), str, len);
+	}
+
+	// TiXmlString destructor
+	~TiXmlString ()
+	{
+		quit();
+	}
+
+	// = operator
+	TiXmlString& operator = (const char * copy)
+	{
+		return assign( copy, (size_type)strlen(copy));
+	}
+
+	// = operator
+	TiXmlString& operator = (const TiXmlString & copy)
+	{
+		return assign(copy.start(), copy.length());
+	}
+
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const char * suffix)
+	{
+		return append(suffix, static_cast<size_type>( strlen(suffix) ));
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (char single)
+	{
+		return append(&single, 1);
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const TiXmlString & suffix)
+	{
+		return append(suffix.data(), suffix.length());
+	}
+
+
+	// Convert a TiXmlString into a null-terminated char *
+	const char * c_str () const { return rep_->str; }
+
+	// Convert a TiXmlString into a char * (need not be null terminated).
+	const char * data () const { return rep_->str; }
+
+	// Return the length of a TiXmlString
+	size_type length () const { return rep_->size; }
+
+	// Alias for length()
+	size_type size () const { return rep_->size; }
+
+	// Checks if a TiXmlString is empty
+	bool empty () const { return rep_->size == 0; }
+
+	// Return capacity of string
+	size_type capacity () const { return rep_->capacity; }
+
+
+	// single char extraction
+	const char& at (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// [] operator
+	char& operator [] (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// find a char in a string. Return TiXmlString::npos if not found
+	size_type find (char lookup) const
+	{
+		return find(lookup, 0);
+	}
+
+	// find a char in a string from an offset. Return TiXmlString::npos if not found
+	size_type find (char tofind, size_type offset) const
+	{
+		if (offset >= length()) return npos;
+
+		for (const char* p = c_str() + offset; *p != '\0'; ++p)
+		{
+		   if (*p == tofind) return static_cast< size_type >( p - c_str() );
+		}
+		return npos;
+	}
+
+	void clear ()
+	{
+		//Lee:
+		//The original was just too strange, though correct:
+		//	TiXmlString().swap(*this);
+		//Instead use the quit & re-init:
+		quit();
+		init(0,0);
+	}
+
+	/*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
+		function DOES NOT clear the content of the TiXmlString if any exists.
+	*/
+	void reserve (size_type cap);
+
+	TiXmlString& assign (const char* str, size_type len);
+
+	TiXmlString& append (const char* str, size_type len);
+
+	void swap (TiXmlString& other)
+	{
+		Rep* r = rep_;
+		rep_ = other.rep_;
+		other.rep_ = r;
+	}
+
+  private:
+
+	void init(size_type sz) { init(sz, sz); }
+	void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
+	char* start() const { return rep_->str; }
+	char* finish() const { return rep_->str + rep_->size; }
+
+	struct Rep
+	{
+		size_type size, capacity;
+		char str[1];
+	};
+
+	void init(size_type sz, size_type cap)
+	{
+		if (cap)
+		{
+			// Lee: the original form:
+			//	rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
+			// doesn't work in some cases of new being overloaded. Switching
+			// to the normal allocation, although use an 'int' for systems
+			// that are overly picky about structure alignment.
+			const size_type bytesNeeded = sizeof(Rep) + cap;
+			const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); 
+			rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
+
+			rep_->str[ rep_->size = sz ] = '\0';
+			rep_->capacity = cap;
+		}
+		else
+		{
+			rep_ = &nullrep_;
+		}
+	}
+
+	void quit()
+	{
+		if (rep_ != &nullrep_)
+		{
+			// The rep_ is really an array of ints. (see the allocator, above).
+			// Cast it back before delete, so the compiler won't incorrectly call destructors.
+			delete [] ( reinterpret_cast<int*>( rep_ ) );
+		}
+	}
+
+	Rep * rep_;
+	static Rep nullrep_;
+
+} ;
+
+
+inline bool operator == (const TiXmlString & a, const TiXmlString & b)
+{
+	return    ( a.length() == b.length() )				// optimization on some platforms
+	       && ( strcmp(a.c_str(), b.c_str()) == 0 );	// actual compare
+}
+inline bool operator < (const TiXmlString & a, const TiXmlString & b)
+{
+	return strcmp(a.c_str(), b.c_str()) < 0;
+}
+
+inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
+inline bool operator >  (const TiXmlString & a, const TiXmlString & b) { return b < a; }
+inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
+inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
+
+inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
+inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
+inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
+inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
+TiXmlString operator + (const TiXmlString & a, const char* b);
+TiXmlString operator + (const char* a, const TiXmlString & b);
+
+
+/*
+   TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
+   Only the operators that we need for TinyXML have been developped.
+*/
+class TiXmlOutStream : public TiXmlString
+{
+public :
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const TiXmlString & in)
+	{
+		*this += in;
+		return *this;
+	}
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const char * in)
+	{
+		*this += in;
+		return *this;
+	}
+
+} ;
+
+#endif	// TIXML_STRING_INCLUDED
+#endif	// TIXML_USE_STL

+ 1856 - 0
天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinyxml.cpp

@@ -0,0 +1,1856 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include <ctype.h>
+
+#ifdef TIXML_USE_STL
+#include <sstream>
+#include <iostream>
+#endif
+
+#include "tinyxml.h"
+
+FILE* TiXmlFOpen( const char* filename, const char* mode );
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+// Microsoft compiler security
+FILE* TiXmlFOpen( const char* filename, const char* mode )
+{
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		FILE* fp = 0;
+		errno_t err = fopen_s( &fp, filename, mode );
+		if ( !err && fp )
+			return fp;
+		return 0;
+	#else
+		return fopen( filename, mode );
+	#endif
+}
+
+void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
+{
+	int i=0;
+
+	while( i<(int)str.length() )
+	{
+		unsigned char c = (unsigned char) str[i];
+
+		if (    c == '&' 
+		     && i < ( (int)str.length() - 2 )
+			 && str[i+1] == '#'
+			 && str[i+2] == 'x' )
+		{
+			// Hexadecimal character reference.
+			// Pass through unchanged.
+			// &#xA9;	-- copyright symbol, for example.
+			//
+			// The -1 is a bug fix from Rob Laveaux. It keeps
+			// an overflow from happening if there is no ';'.
+			// There are actually 2 ways to exit this loop -
+			// while fails (error case) and break (semicolon found).
+			// However, there is no mechanism (currently) for
+			// this function to return an error.
+			while ( i<(int)str.length()-1 )
+			{
+				outString->append( str.c_str() + i, 1 );
+				++i;
+				if ( str[i] == ';' )
+					break;
+			}
+		}
+		else if ( c == '&' )
+		{
+			outString->append( entity[0].str, entity[0].strLength );
+			++i;
+		}
+		else if ( c == '<' )
+		{
+			outString->append( entity[1].str, entity[1].strLength );
+			++i;
+		}
+		else if ( c == '>' )
+		{
+			outString->append( entity[2].str, entity[2].strLength );
+			++i;
+		}
+		else if ( c == '\"' )
+		{
+			outString->append( entity[3].str, entity[3].strLength );
+			++i;
+		}
+		else if ( c == '\'' )
+		{
+			outString->append( entity[4].str, entity[4].strLength );
+			++i;
+		}
+		else if ( c < 32 )
+		{
+			// Easy pass at non-alpha/numeric/symbol
+			// Below 32 is symbolic.
+			char buf[ 32 ];
+			
+			#if defined(TIXML_SNPRINTF)		
+				TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#else
+				sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#endif		
+
+			//*ME:	warning C4267: convert 'size_t' to 'int'
+			//*ME:	Int-Cast to make compiler happy ...
+			outString->append( buf, (int)strlen( buf ) );
+			++i;
+		}
+		else
+		{
+			//char realc = (char) c;
+			//outString->append( &realc, 1 );
+			*outString += (char) c;	// somewhat more efficient function call.
+			++i;
+		}
+	}
+}
+
+
+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
+{
+	parent = 0;
+	type = _type;
+	firstChild = 0;
+	lastChild = 0;
+	prev = 0;
+	next = 0;
+}
+
+
+TiXmlNode::~TiXmlNode()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+}
+
+
+void TiXmlNode::CopyTo( TiXmlNode* target ) const
+{
+	target->SetValue (value.c_str() );
+	target->userData = userData; 
+	target->location = location;
+}
+
+
+void TiXmlNode::Clear()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+
+	firstChild = 0;
+	lastChild = 0;
+}
+
+
+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
+{
+	assert( node->parent == 0 || node->parent == this );
+	assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
+
+	if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		delete node;
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	node->parent = this;
+
+	node->prev = lastChild;
+	node->next = 0;
+
+	if ( lastChild )
+		lastChild->next = node;
+	else
+		firstChild = node;			// it was an empty list.
+
+	lastChild = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
+{
+	if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+
+	return LinkEndChild( node );
+}
+
+
+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
+{	
+	if ( !beforeThis || beforeThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->next = beforeThis;
+	node->prev = beforeThis->prev;
+	if ( beforeThis->prev )
+	{
+		beforeThis->prev->next = node;
+	}
+	else
+	{
+		assert( firstChild == beforeThis );
+		firstChild = node;
+	}
+	beforeThis->prev = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
+{
+	if ( !afterThis || afterThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->prev = afterThis;
+	node->next = afterThis->next;
+	if ( afterThis->next )
+	{
+		afterThis->next->prev = node;
+	}
+	else
+	{
+		assert( lastChild == afterThis );
+		lastChild = node;
+	}
+	afterThis->next = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
+{
+	if ( !replaceThis )
+		return 0;
+
+	if ( replaceThis->parent != this )
+		return 0;
+
+	if ( withThis.ToDocument() ) {
+		// A document can never be a child.	Thanks to Noam.
+		TiXmlDocument* document = GetDocument();
+		if ( document ) 
+			document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = withThis.Clone();
+	if ( !node )
+		return 0;
+
+	node->next = replaceThis->next;
+	node->prev = replaceThis->prev;
+
+	if ( replaceThis->next )
+		replaceThis->next->prev = node;
+	else
+		lastChild = node;
+
+	if ( replaceThis->prev )
+		replaceThis->prev->next = node;
+	else
+		firstChild = node;
+
+	delete replaceThis;
+	node->parent = this;
+	return node;
+}
+
+
+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
+{
+	if ( !removeThis ) {
+		return false;
+	}
+
+	if ( removeThis->parent != this )
+	{	
+		assert( 0 );
+		return false;
+	}
+
+	if ( removeThis->next )
+		removeThis->next->prev = removeThis->prev;
+	else
+		lastChild = removeThis->prev;
+
+	if ( removeThis->prev )
+		removeThis->prev->next = removeThis->next;
+	else
+		firstChild = removeThis->next;
+
+	delete removeThis;
+	return true;
+}
+
+const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 
+{
+	const TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+void TiXmlElement::RemoveAttribute( const char * name )
+{
+    #ifdef TIXML_USE_STL
+	TIXML_STRING str( name );
+	TiXmlAttribute* node = attributeSet.Find( str );
+	#else
+	TiXmlAttribute* node = attributeSet.Find( name );
+	#endif
+	if ( node )
+	{
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlDocument* TiXmlNode::GetDocument() const
+{
+	const TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+
+TiXmlElement::TiXmlElement (const char * _value)
+	: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlElement::TiXmlElement( const std::string& _value ) 
+	: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+#endif
+
+
+TiXmlElement::TiXmlElement( const TiXmlElement& copy)
+	: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
+{
+	firstChild = lastChild = 0;
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlElement::operator=( const TiXmlElement& base )
+{
+	ClearThis();
+	base.CopyTo( this );
+}
+
+
+TiXmlElement::~TiXmlElement()
+{
+	ClearThis();
+}
+
+
+void TiXmlElement::ClearThis()
+{
+	Clear();
+	while( attributeSet.First() )
+	{
+		TiXmlAttribute* node = attributeSet.First();
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+
+const char* TiXmlElement::Attribute( const char* name ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+		return node->Value();
+	return 0;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( attrib )
+		return &attrib->ValueStr();
+	return 0;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, int* i ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const char* result = 0;
+
+	if ( attrib ) {
+		result = attrib->Value();
+		if ( i ) {
+			attrib->QueryIntValue( i );
+		}
+	}
+	return result;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const std::string* result = 0;
+
+	if ( attrib ) {
+		result = &attrib->ValueStr();
+		if ( i ) {
+			attrib->QueryIntValue( i );
+		}
+	}
+	return result;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, double* d ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const char* result = 0;
+
+	if ( attrib ) {
+		result = attrib->Value();
+		if ( d ) {
+			attrib->QueryDoubleValue( d );
+		}
+	}
+	return result;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const std::string* result = 0;
+
+	if ( attrib ) {
+		result = &attrib->ValueStr();
+		if ( d ) {
+			attrib->QueryDoubleValue( d );
+		}
+	}
+	return result;
+}
+#endif
+
+
+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryIntValue( ival );
+}
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryIntValue( ival );
+}
+#endif
+
+
+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryDoubleValue( dval );
+}
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryDoubleValue( dval );
+}
+#endif
+
+
+void TiXmlElement::SetAttribute( const char * name, int val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetIntValue( val );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& name, int val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetIntValue( val );
+	}
+}
+#endif
+
+
+void TiXmlElement::SetDoubleAttribute( const char * name, double val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetDoubleValue( val );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetDoubleValue( val );
+	}
+}
+#endif 
+
+
+void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
+{
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
+	if ( attrib ) {
+		attrib->SetValue( cvalue );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
+{
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
+	if ( attrib ) {
+		attrib->SetValue( _value );
+	}
+}
+#endif
+
+
+void TiXmlElement::Print( FILE* cfile, int depth ) const
+{
+	int i;
+	assert( cfile );
+	for ( i=0; i<depth; i++ ) {
+		fprintf( cfile, "    " );
+	}
+
+	fprintf( cfile, "<%s", value.c_str() );
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{
+		fprintf( cfile, " " );
+		attrib->Print( cfile, depth );
+	}
+
+	// There are 3 different formatting approaches:
+	// 1) An element without children is printed as a <foo /> node
+	// 2) An element with only a text child is printed as <foo> text </foo>
+	// 3) An element with children is printed on multiple lines.
+	TiXmlNode* node;
+	if ( !firstChild )
+	{
+		fprintf( cfile, " />" );
+	}
+	else if ( firstChild == lastChild && firstChild->ToText() )
+	{
+		fprintf( cfile, ">" );
+		firstChild->Print( cfile, depth + 1 );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+	else
+	{
+		fprintf( cfile, ">" );
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			if ( !node->ToText() )
+			{
+				fprintf( cfile, "\n" );
+			}
+			node->Print( cfile, depth+1 );
+		}
+		fprintf( cfile, "\n" );
+		for( i=0; i<depth; ++i ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+}
+
+
+void TiXmlElement::CopyTo( TiXmlElement* target ) const
+{
+	// superclass:
+	TiXmlNode::CopyTo( target );
+
+	// Element class: 
+	// Clone the attributes, then clone the children.
+	const TiXmlAttribute* attribute = 0;
+	for(	attribute = attributeSet.First();
+	attribute;
+	attribute = attribute->Next() )
+	{
+		target->SetAttribute( attribute->Name(), attribute->Value() );
+	}
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}
+}
+
+bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this, attributeSet.First() ) ) 
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+TiXmlNode* TiXmlElement::Clone() const
+{
+	TiXmlElement* clone = new TiXmlElement( Value() );
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+const char* TiXmlElement::GetText() const
+{
+	const TiXmlNode* child = this->FirstChild();
+	if ( child ) {
+		const TiXmlText* childText = child->ToText();
+		if ( childText ) {
+			return childText->Value();
+		}
+	}
+	return 0;
+}
+
+
+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	ClearError();
+}
+
+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	value = documentName;
+	ClearError();
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+    value = documentName;
+	ClearError();
+}
+#endif
+
+
+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDocument::operator=( const TiXmlDocument& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
+{
+	return LoadFile( Value(), encoding );
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+	return SaveFile( Value() );
+}
+
+bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
+{
+	TIXML_STRING filename( _filename );
+	value = filename;
+
+	// reading in binary mode so that tinyxml can normalize the EOL
+	FILE* file = TiXmlFOpen( value.c_str (), "rb" );	
+
+	if ( file )
+	{
+		bool result = LoadFile( file, encoding );
+		fclose( file );
+		return result;
+	}
+	else
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+}
+
+bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
+{
+	if ( !file ) 
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// Delete the existing data:
+	Clear();
+	location.Clear();
+
+	// Get the file size, so we can pre-allocate the string. HUGE speed impact.
+	long length = 0;
+	fseek( file, 0, SEEK_END );
+	length = ftell( file );
+	fseek( file, 0, SEEK_SET );
+
+	// Strange case, but good to handle up front.
+	if ( length <= 0 )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// If we have a file, assume it is all one big XML file, and read it in.
+	// The document parser may decide the document ends sooner than the entire file, however.
+	TIXML_STRING data;
+	data.reserve( length );
+
+	// Subtle bug here. TinyXml did use fgets. But from the XML spec:
+	// 2.11 End-of-Line Handling
+	// <snip>
+	// <quote>
+	// ...the XML processor MUST behave as if it normalized all line breaks in external 
+	// parsed entities (including the document entity) on input, before parsing, by translating 
+	// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
+	// a single #xA character.
+	// </quote>
+	//
+	// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
+	// Generally, you expect fgets to translate from the convention of the OS to the c/unix
+	// convention, and not work generally.
+
+	/*
+	while( fgets( buf, sizeof(buf), file ) )
+	{
+		data += buf;
+	}
+	*/
+
+	char* buf = new char[ length+1 ];
+	buf[0] = 0;
+
+	if ( fread( buf, length, 1, file ) != 1 ) {
+		delete [] buf;
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	const char* lastPos = buf;
+	const char* p = buf;
+
+	buf[length] = 0;
+	while( *p ) {
+		assert( p < (buf+length) );
+		if ( *p == 0xa ) {
+			// Newline character. No special rules for this. Append all the characters
+			// since the last string, and include the newline.
+			data.append( lastPos, (p-lastPos+1) );	// append, include the newline
+			++p;									// move past the newline
+			lastPos = p;							// and point to the new buffer (may be 0)
+			assert( p <= (buf+length) );
+		}
+		else if ( *p == 0xd ) {
+			// Carriage return. Append what we have so far, then
+			// handle moving forward in the buffer.
+			if ( (p-lastPos) > 0 ) {
+				data.append( lastPos, p-lastPos );	// do not add the CR
+			}
+			data += (char)0xa;						// a proper newline
+
+			if ( *(p+1) == 0xa ) {
+				// Carriage return - new line sequence
+				p += 2;
+				lastPos = p;
+				assert( p <= (buf+length) );
+			}
+			else {
+				// it was followed by something else...that is presumably characters again.
+				++p;
+				lastPos = p;
+				assert( p <= (buf+length) );
+			}
+		}
+		else {
+			++p;
+		}
+	}
+	// Handle any left over characters.
+	if ( p-lastPos ) {
+		data.append( lastPos, p-lastPos );
+	}		
+	delete [] buf;
+	buf = 0;
+
+	Parse( data.c_str(), 0, encoding );
+
+	if (  Error() )
+        return false;
+    else
+		return true;
+}
+
+
+bool TiXmlDocument::SaveFile( const char * filename ) const
+{
+	// The old c stuff lives on...
+	FILE* fp = TiXmlFOpen( filename, "w" );
+	if ( fp )
+	{
+		bool result = SaveFile( fp );
+		fclose( fp );
+		return result;
+	}
+	return false;
+}
+
+
+bool TiXmlDocument::SaveFile( FILE* fp ) const
+{
+	if ( useMicrosoftBOM ) 
+	{
+		const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+		const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+		const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+		fputc( TIXML_UTF_LEAD_0, fp );
+		fputc( TIXML_UTF_LEAD_1, fp );
+		fputc( TIXML_UTF_LEAD_2, fp );
+	}
+	Print( fp, 0 );
+	return (ferror(fp) == 0);
+}
+
+
+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->error = error;
+	target->errorId = errorId;
+	target->errorDesc = errorDesc;
+	target->tabsize = tabsize;
+	target->errorLocation = errorLocation;
+	target->useMicrosoftBOM = useMicrosoftBOM;
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}	
+}
+
+
+TiXmlNode* TiXmlDocument::Clone() const
+{
+	TiXmlDocument* clone = new TiXmlDocument();
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlDocument::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->Print( cfile, depth );
+		fprintf( cfile, "\n" );
+	}
+}
+
+
+bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this ) )
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+const TiXmlAttribute* TiXmlAttribute::Next() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Next()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+*/
+
+const TiXmlAttribute* TiXmlAttribute::Previous() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Previous()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+*/
+
+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	TIXML_STRING n, v;
+
+	EncodeString( name, &n );
+	EncodeString( value, &v );
+
+	if (value.find ('\"') == TIXML_STRING::npos) {
+		if ( cfile ) {
+		fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
+		}
+	}
+	else {
+		if ( cfile ) {
+		fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
+		}
+	}
+}
+
+
+int TiXmlAttribute::QueryIntValue( int* ival ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+int TiXmlAttribute::QueryDoubleValue( double* dval ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+void TiXmlAttribute::SetIntValue( int _value )
+{
+	char buf [64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
+	#else
+		sprintf (buf, "%d", _value);
+	#endif
+	SetValue (buf);
+}
+
+void TiXmlAttribute::SetDoubleValue( double _value )
+{
+	char buf [256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
+	#else
+		sprintf (buf, "%g", _value);
+	#endif
+	SetValue (buf);
+}
+
+int TiXmlAttribute::IntValue() const
+{
+	return atoi (value.c_str ());
+}
+
+double  TiXmlAttribute::DoubleValue() const
+{
+	return atof (value.c_str ());
+}
+
+
+TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlComment::operator=( const TiXmlComment& base )
+{
+	Clear();
+	base.CopyTo( this );
+}
+
+
+void TiXmlComment::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( int i=0; i<depth; i++ )
+	{
+		fprintf( cfile,  "    " );
+	}
+	fprintf( cfile, "<!--%s-->", value.c_str() );
+}
+
+
+void TiXmlComment::CopyTo( TiXmlComment* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+	TiXmlComment* clone = new TiXmlComment();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlText::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	if ( cdata )
+	{
+		int i;
+		fprintf( cfile, "\n" );
+		for ( i=0; i<depth; i++ ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );	// unformatted output
+	}
+	else
+	{
+		TIXML_STRING buffer;
+		EncodeString( value, &buffer );
+		fprintf( cfile, "%s", buffer.c_str() );
+	}
+}
+
+
+void TiXmlText::CopyTo( TiXmlText* target ) const
+{
+	TiXmlNode::CopyTo( target );
+	target->cdata = cdata;
+}
+
+
+bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlText::Clone() const
+{	
+	TiXmlText* clone = 0;
+	clone = new TiXmlText( "" );
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlDeclaration::TiXmlDeclaration( const char * _version,
+									const char * _encoding,
+									const char * _standalone )
+	: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDeclaration::TiXmlDeclaration(	const std::string& _version,
+									const std::string& _encoding,
+									const std::string& _standalone )
+	: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+#endif
+
+
+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
+	: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
+{
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	if ( cfile ) fprintf( cfile, "<?xml " );
+	if ( str )	 (*str) += "<?xml ";
+
+	if ( !version.empty() ) {
+		if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
+		if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
+	}
+	if ( !encoding.empty() ) {
+		if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+		if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
+	}
+	if ( !standalone.empty() ) {
+		if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+		if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
+	}
+	if ( cfile ) fprintf( cfile, "?>" );
+	if ( str )	 (*str) += "?>";
+}
+
+
+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->version = version;
+	target->encoding = encoding;
+	target->standalone = standalone;
+}
+
+
+bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlDeclaration::Clone() const
+{	
+	TiXmlDeclaration* clone = new TiXmlDeclaration();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlUnknown::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+		fprintf( cfile, "    " );
+	fprintf( cfile, "<%s>", value.c_str() );
+}
+
+
+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlUnknown::Clone() const
+{
+	TiXmlUnknown* clone = new TiXmlUnknown();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlAttributeSet::TiXmlAttributeSet()
+{
+	sentinel.next = &sentinel;
+	sentinel.prev = &sentinel;
+}
+
+
+TiXmlAttributeSet::~TiXmlAttributeSet()
+{
+	assert( sentinel.next == &sentinel );
+	assert( sentinel.prev == &sentinel );
+}
+
+
+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
+{
+    #ifdef TIXML_USE_STL
+	assert( !Find( TIXML_STRING( addMe->Name() ) ) );	// Shouldn't be multiply adding to the set.
+	#else
+	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+	#endif
+
+	addMe->next = &sentinel;
+	addMe->prev = sentinel.prev;
+
+	sentinel.prev->next = addMe;
+	sentinel.prev      = addMe;
+}
+
+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node == removeMe )
+		{
+			node->prev->next = node->next;
+			node->next->prev = node->prev;
+			node->next = 0;
+			node->prev = 0;
+			return;
+		}
+	}
+	assert( 0 );		// we tried to remove a non-linked attribute.
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
+{
+	TiXmlAttribute* attrib = Find( _name );
+	if ( !attrib ) {
+		attrib = new TiXmlAttribute();
+		Add( attrib );
+		attrib->SetName( _name );
+	}
+	return attrib;
+}
+#endif
+
+
+TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( strcmp( node->name.c_str(), name ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
+{
+	TiXmlAttribute* attrib = Find( _name );
+	if ( !attrib ) {
+		attrib = new TiXmlAttribute();
+		Add( attrib );
+		attrib->SetName( _name );
+	}
+	return attrib;
+}
+
+
+#ifdef TIXML_USE_STL	
+std::istream& operator>> (std::istream & in, TiXmlNode & base)
+{
+	TIXML_STRING tag;
+	tag.reserve( 8 * 1000 );
+	base.StreamIn( &in, &tag );
+
+	base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
+	return in;
+}
+#endif
+
+
+#ifdef TIXML_USE_STL	
+std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out << printer.Str();
+
+	return out;
+}
+
+
+std::string& operator<< (std::string& out, const TiXmlNode& base )
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out.append( printer.Str() );
+
+	return out;
+}
+#endif
+
+
+TiXmlHandle TiXmlHandle::FirstChild() const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement() const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += element.Value();
+
+	for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
+	{
+		buffer += " ";
+		attrib->Print( 0, 0, &buffer );
+	}
+
+	if ( !element.FirstChild() ) 
+	{
+		buffer += " />";
+		DoLineBreak();
+	}
+	else 
+	{
+		buffer += ">";
+		if (    element.FirstChild()->ToText()
+			  && element.LastChild() == element.FirstChild()
+			  && element.FirstChild()->ToText()->CDATA() == false )
+		{
+			simpleTextPrint = true;
+			// no DoLineBreak()!
+		}
+		else
+		{
+			DoLineBreak();
+		}
+	}
+	++depth;	
+	return true;
+}
+
+
+bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
+{
+	--depth;
+	if ( !element.FirstChild() ) 
+	{
+		// nothing.
+	}
+	else 
+	{
+		if ( simpleTextPrint )
+		{
+			simpleTextPrint = false;
+		}
+		else
+		{
+			DoIndent();
+		}
+		buffer += "</";
+		buffer += element.Value();
+		buffer += ">";
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlText& text )
+{
+	if ( text.CDATA() )
+	{
+		DoIndent();
+		buffer += "<![CDATA[";
+		buffer += text.Value();
+		buffer += "]]>";
+		DoLineBreak();
+	}
+	else if ( simpleTextPrint )
+	{
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+	}
+	else
+	{
+		DoIndent();
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
+{
+	DoIndent();
+	declaration.Print( 0, 0, &buffer );
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlComment& comment )
+{
+	DoIndent();
+	buffer += "<!--";
+	buffer += comment.Value();
+	buffer += "-->";
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += unknown.Value();
+	buffer += ">";
+	DoLineBreak();
+	return true;
+}
+

+ 1802 - 0
天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinyxml.h

@@ -0,0 +1,1802 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+#define TIXML_USE_STL
+
+
+#ifndef TINYXML_INCLUDED
+#define TINYXML_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable : 4530 )
+#pragma warning( disable : 4786 )
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+// Help out windows:
+#if defined( _DEBUG ) && !defined( DEBUG )
+#define DEBUG
+#endif
+
+#ifdef TIXML_USE_STL
+	#include <string>
+ 	#include <iostream>
+	#include <sstream>
+	#define TIXML_STRING		std::string
+#else
+	#include "tinystr.h"
+	#define TIXML_STRING		TiXmlString
+#endif
+
+// Deprecated library function hell. Compilers want to use the
+// new safe versions. This probably doesn't fully address the problem,
+// but it gets closer. There are too many compilers for me to fully
+// test. If you get compilation troubles, undefine TIXML_SAFE
+#define TIXML_SAFE
+
+#ifdef TIXML_SAFE
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		// Microsoft visual studio, version 2005 and higher.
+		#define TIXML_SNPRINTF _snprintf_s
+		#define TIXML_SNSCANF  _snscanf_s
+		#define TIXML_SSCANF   sscanf_s
+	#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
+		// Microsoft visual studio, version 6 and higher.
+		//#pragma message( "Using _sn* functions." )
+		#define TIXML_SNPRINTF _snprintf
+		#define TIXML_SNSCANF  _snscanf
+		#define TIXML_SSCANF   sscanf
+	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+		// GCC version 3 and higher.s
+		//#warning( "Using sn* functions." )
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SNSCANF  snscanf
+		#define TIXML_SSCANF   sscanf
+	#else
+		#define TIXML_SSCANF   sscanf
+	#endif
+#endif	
+
+class TiXmlDocument;
+class TiXmlElement;
+class TiXmlComment;
+class TiXmlUnknown;
+class TiXmlAttribute;
+class TiXmlText;
+class TiXmlDeclaration;
+class TiXmlParsingData;
+
+const int TIXML_MAJOR_VERSION = 2;
+const int TIXML_MINOR_VERSION = 6;
+const int TIXML_PATCH_VERSION = 0;
+
+/*	Internal structure for tracking location of items 
+	in the XML file.
+*/
+struct TiXmlCursor
+{
+	TiXmlCursor()		{ Clear(); }
+	void Clear()		{ row = col = -1; }
+
+	int row;	// 0 based.
+	int col;	// 0 based.
+};
+
+
+/**
+	Implements the interface to the "Visitor pattern" (see the Accept() method.)
+	If you call the Accept() method, it requires being passed a TiXmlVisitor
+	class to handle callbacks. For nodes that contain other nodes (Document, Element)
+	you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
+	are simply called with Visit().
+
+	If you return 'true' from a Visit method, recursive parsing will continue. If you return
+	false, <b>no children of this node or its sibilings</b> will be Visited.
+
+	All flavors of Visit methods have a default implementation that returns 'true' (continue 
+	visiting). You need to only override methods that are interesting to you.
+
+	Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
+
+	You should never change the document from a callback.
+
+	@sa TiXmlNode::Accept()
+*/
+class TiXmlVisitor
+{
+public:
+	virtual ~TiXmlVisitor() {}
+
+	/// Visit a document.
+	virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )			{ return true; }
+	/// Visit a document.
+	virtual bool VisitExit( const TiXmlDocument& /*doc*/ )			{ return true; }
+
+	/// Visit an element.
+	virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )	{ return true; }
+	/// Visit an element.
+	virtual bool VisitExit( const TiXmlElement& /*element*/ )		{ return true; }
+
+	/// Visit a declaration
+	virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )	{ return true; }
+	/// Visit a text node
+	virtual bool Visit( const TiXmlText& /*text*/ )					{ return true; }
+	/// Visit a comment node
+	virtual bool Visit( const TiXmlComment& /*comment*/ )			{ return true; }
+	/// Visit an unknow node
+	virtual bool Visit( const TiXmlUnknown& /*unknown*/ )			{ return true; }
+};
+
+// Only used by Attribute::Query functions
+enum 
+{ 
+	TIXML_SUCCESS,
+	TIXML_NO_ATTRIBUTE,
+	TIXML_WRONG_TYPE
+};
+
+
+// Used by the parsing routines.
+enum TiXmlEncoding
+{
+	TIXML_ENCODING_UNKNOWN,
+	TIXML_ENCODING_UTF8,
+	TIXML_ENCODING_LEGACY
+};
+
+const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
+
+/** TiXmlBase is a base class for every class in TinyXml.
+	It does little except to establish that TinyXml classes
+	can be printed and provide some utility functions.
+
+	In XML, the document and elements can contain
+	other elements and other types of nodes.
+
+	@verbatim
+	A Document can contain:	Element	(container or leaf)
+							Comment (leaf)
+							Unknown (leaf)
+							Declaration( leaf )
+
+	An Element can contain:	Element (container or leaf)
+							Text	(leaf)
+							Attributes (not on tree)
+							Comment (leaf)
+							Unknown (leaf)
+
+	A Decleration contains: Attributes (not on tree)
+	@endverbatim
+*/
+class TiXmlBase
+{
+	friend class TiXmlNode;
+	friend class TiXmlElement;
+	friend class TiXmlDocument;
+
+public:
+	TiXmlBase()	:	userData(0)		{}
+	virtual ~TiXmlBase()			{}
+
+	/**	All TinyXml classes can print themselves to a filestream
+		or the string class (TiXmlString in non-STL mode, std::string
+		in STL mode.) Either or both cfile and str can be null.
+		
+		This is a formatted print, and will insert 
+		tabs and newlines.
+		
+		(For an unformatted stream, use the << operator.)
+	*/
+	virtual void Print( FILE* cfile, int depth ) const = 0;
+
+	/**	The world does not agree on whether white space should be kept or
+		not. In order to make everyone happy, these global, static functions
+		are provided to set whether or not TinyXml will condense all white space
+		into a single space or not. The default is to condense. Note changing this
+		value is not thread safe.
+	*/
+	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
+
+	/// Return the current white space setting.
+	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
+
+	/** Return the position, in the original source file, of this node or attribute.
+		The row and column are 1-based. (That is the first row and first column is
+		1,1). If the returns values are 0 or less, then the parser does not have
+		a row and column value.
+
+		Generally, the row and column value will be set when the TiXmlDocument::Load(),
+		TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
+		when the DOM was created from operator>>.
+
+		The values reflect the initial load. Once the DOM is modified programmatically
+		(by adding or changing nodes and attributes) the new values will NOT update to
+		reflect changes in the document.
+
+		There is a minor performance cost to computing the row and column. Computation
+		can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
+
+		@sa TiXmlDocument::SetTabSize()
+	*/
+	int Row() const			{ return location.row + 1; }
+	int Column() const		{ return location.col + 1; }	///< See Row()
+
+	void  SetUserData( void* user )			{ userData = user; }	///< Set a pointer to arbitrary user data.
+	void* GetUserData()						{ return userData; }	///< Get a pointer to arbitrary user data.
+	const void* GetUserData() const 		{ return userData; }	///< Get a pointer to arbitrary user data.
+
+	// Table that returs, for a given lead byte, the total number of bytes
+	// in the UTF-8 sequence.
+	static const int utf8ByteTable[256];
+
+	virtual const char* Parse(	const char* p, 
+								TiXmlParsingData* data, 
+								TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+
+	/** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, 
+		or they will be transformed into entities!
+	*/
+	static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
+
+	enum
+	{
+		TIXML_NO_ERROR = 0,
+		TIXML_ERROR,
+		TIXML_ERROR_OPENING_FILE,
+		TIXML_ERROR_PARSING_ELEMENT,
+		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+		TIXML_ERROR_READING_ELEMENT_VALUE,
+		TIXML_ERROR_READING_ATTRIBUTES,
+		TIXML_ERROR_PARSING_EMPTY,
+		TIXML_ERROR_READING_END_TAG,
+		TIXML_ERROR_PARSING_UNKNOWN,
+		TIXML_ERROR_PARSING_COMMENT,
+		TIXML_ERROR_PARSING_DECLARATION,
+		TIXML_ERROR_DOCUMENT_EMPTY,
+		TIXML_ERROR_EMBEDDED_NULL,
+		TIXML_ERROR_PARSING_CDATA,
+		TIXML_ERROR_DOCUMENT_TOP_ONLY,
+
+		TIXML_ERROR_STRING_COUNT
+	};
+
+protected:
+
+	static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+
+	inline static bool IsWhiteSpace( char c )		
+	{ 
+		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
+	}
+	inline static bool IsWhiteSpace( int c )
+	{
+		if ( c < 256 )
+			return IsWhiteSpace( (char) c );
+		return false;	// Again, only truly correct for English/Latin...but usually works.
+	}
+
+	#ifdef TIXML_USE_STL
+	static bool	StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
+	static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
+	#endif
+
+	/*	Reads an XML name into the string provided. Returns
+		a pointer just past the last character of the name,
+		or 0 if the function has an error.
+	*/
+	static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
+
+	/*	Reads text. Returns a pointer past the given end tag.
+		Wickedly complex options, but it keeps the (sensitive) code in one place.
+	*/
+	static const char* ReadText(	const char* in,				// where to start
+									TIXML_STRING* text,			// the string read
+									bool ignoreWhiteSpace,		// whether to keep the white space
+									const char* endTag,			// what ends this text
+									bool ignoreCase,			// whether to ignore case in the end tag
+									TiXmlEncoding encoding );	// the current encoding
+
+	// If an entity has been found, transform it into a character.
+	static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
+
+	// Get a character, while interpreting entities.
+	// The length can be from 0 to 4 bytes.
+	inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
+	{
+		assert( p );
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			*length = utf8ByteTable[ *((const unsigned char*)p) ];
+			assert( *length >= 0 && *length < 5 );
+		}
+		else
+		{
+			*length = 1;
+		}
+
+		if ( *length == 1 )
+		{
+			if ( *p == '&' )
+				return GetEntity( p, _value, length, encoding );
+			*_value = *p;
+			return p+1;
+		}
+		else if ( *length )
+		{
+			//strncpy( _value, p, *length );	// lots of compilers don't like this function (unsafe),
+												// and the null terminator isn't needed
+			for( int i=0; p[i] && i<*length; ++i ) {
+				_value[i] = p[i];
+			}
+			return p + (*length);
+		}
+		else
+		{
+			// Not valid text.
+			return 0;
+		}
+	}
+
+	// Return true if the next characters in the stream are any of the endTag sequences.
+	// Ignore case only works for english, and should only be relied on when comparing
+	// to English words: StringEqual( p, "version", true ) is fine.
+	static bool StringEqual(	const char* p,
+								const char* endTag,
+								bool ignoreCase,
+								TiXmlEncoding encoding );
+
+	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+	TiXmlCursor location;
+
+    /// Field containing a generic user pointer
+	void*			userData;
+	
+	// None of these methods are reliable for any language except English.
+	// Good for approximation, not great for accuracy.
+	static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
+	static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
+	inline static int ToLower( int v, TiXmlEncoding encoding )
+	{
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			if ( v < 128 ) return tolower( v );
+			return v;
+		}
+		else
+		{
+			return tolower( v );
+		}
+	}
+	static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+
+private:
+	TiXmlBase( const TiXmlBase& );				// not implemented.
+	void operator=( const TiXmlBase& base );	// not allowed.
+
+	struct Entity
+	{
+		const char*     str;
+		unsigned int	strLength;
+		char		    chr;
+	};
+	enum
+	{
+		NUM_ENTITY = 5,
+		MAX_ENTITY_LENGTH = 6
+
+	};
+	static Entity entity[ NUM_ENTITY ];
+	static bool condenseWhiteSpace;
+};
+
+
+/** The parent class for everything in the Document Object Model.
+	(Except for attributes).
+	Nodes have siblings, a parent, and children. A node can be
+	in a document, or stand on its own. The type of a TiXmlNode
+	can be queried, and it can be cast to its more defined type.
+*/
+class TiXmlNode : public TiXmlBase
+{
+	friend class TiXmlDocument;
+	friend class TiXmlElement;
+
+public:
+	#ifdef TIXML_USE_STL	
+
+	    /** An input stream operator, for every class. Tolerant of newlines and
+		    formatting, but doesn't expect them.
+	    */
+	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
+
+	    /** An output stream operator, for every class. Note that this outputs
+		    without any newlines or formatting, as opposed to Print(), which
+		    includes tabs and new lines.
+
+		    The operator<< and operator>> are not completely symmetric. Writing
+		    a node to a stream is very well defined. You'll get a nice stream
+		    of output, without any extra whitespace or newlines.
+		    
+		    But reading is not as well defined. (As it always is.) If you create
+		    a TiXmlElement (for example) and read that from an input stream,
+		    the text needs to define an element or junk will result. This is
+		    true of all input streams, but it's worth keeping in mind.
+
+		    A TiXmlDocument will read nodes until it reads a root element, and
+			all the children of that root element.
+	    */	
+	    friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
+
+		/// Appends the XML node or attribute to a std::string.
+		friend std::string& operator<< (std::string& out, const TiXmlNode& base );
+
+	#endif
+
+	/** The types of XML nodes supported by TinyXml. (All the
+			unsupported types are picked up by UNKNOWN.)
+	*/
+	enum NodeType
+	{
+		TINYXML_DOCUMENT,
+		TINYXML_ELEMENT,
+		TINYXML_COMMENT,
+		TINYXML_UNKNOWN,
+		TINYXML_TEXT,
+		TINYXML_DECLARATION,
+		TINYXML_TYPECOUNT
+	};
+
+	virtual ~TiXmlNode();
+
+	/** The meaning of 'value' changes for the specific type of
+		TiXmlNode.
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+
+		The subclasses will wrap this function.
+	*/
+	const char *Value() const { return value.c_str (); }
+
+    #ifdef TIXML_USE_STL
+	/** Return Value() as a std::string. If you only use STL,
+	    this is more efficient than calling Value().
+		Only available in STL mode.
+	*/
+	const std::string& ValueStr() const { return value; }
+	#endif
+
+	const TIXML_STRING& ValueTStr() const { return value; }
+
+	/** Changes the value of the node. Defined as:
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+	*/
+	void SetValue(const char * _value) { value = _value;}
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Delete all the children of this node. Does not affect 'this'.
+	void Clear();
+
+	/// One step up the DOM.
+	TiXmlNode* Parent()							{ return parent; }
+	const TiXmlNode* Parent() const				{ return parent; }
+
+	const TiXmlNode* FirstChild()	const		{ return firstChild; }	///< The first child of this node. Will be null if there are no children.
+	TiXmlNode* FirstChild()						{ return firstChild; }
+	const TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
+	/// The first child of this node with the matching 'value'. Will be null if none found.
+	TiXmlNode* FirstChild( const char * _value ) {
+		// Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
+		// call the method, cast the return back to non-const.
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
+	}
+	const TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
+	TiXmlNode* LastChild()	{ return lastChild; }
+	
+	const TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
+	TiXmlNode* LastChild( const char * _value ) {
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* FirstChild( const std::string& _value ) const	{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* FirstChild( const std::string& _value )				{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* LastChild( const std::string& _value ) const	{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* LastChild( const std::string& _value )				{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** An alternate way to walk the children of a node.
+		One way to iterate over nodes is:
+		@verbatim
+			for( child = parent->FirstChild(); child; child = child->NextSibling() )
+		@endverbatim
+
+		IterateChildren does the same thing with the syntax:
+		@verbatim
+			child = 0;
+			while( child = parent->IterateChildren( child ) )
+		@endverbatim
+
+		IterateChildren takes the previous child as input and finds
+		the next one. If the previous child is null, it returns the
+		first. IterateChildren will return null when done.
+	*/
+	const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
+	}
+
+	/// This flavor of IterateChildren searches for children with a particular 'value'
+	const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const	{	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	#endif
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+
+		NOTE: the node to be added is passed by pointer, and will be
+		henceforth owned (and deleted) by tinyXml. This method is efficient
+		and avoids an extra copy, but should be used with care as it
+		uses a different memory model than the other insert functions.
+
+		@sa InsertEndChild
+	*/
+	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+
+	/** Add a new node related to this. Adds a child before the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+
+	/** Add a new node related to this. Adds a child after the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
+
+	/** Replace a child of this node.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+
+	/// Delete a child of this node.
+	bool RemoveChild( TiXmlNode* removeThis );
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling() const			{ return prev; }
+	TiXmlNode* PreviousSibling()						{ return prev; }
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling( const char * ) const;
+	TiXmlNode* PreviousSibling( const char *_prev ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* PreviousSibling( const std::string& _value ) const	{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* PreviousSibling( const std::string& _value ) 			{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* NextSibling( const std::string& _value) const		{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* NextSibling( const std::string& _value) 					{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* NextSibling() const				{ return next; }
+	TiXmlNode* NextSibling()							{ return next; }
+
+	/// Navigate to a sibling node with the given 'value'.
+	const TiXmlNode* NextSibling( const char * ) const;
+	TiXmlNode* NextSibling( const char* _next ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement() const;
+	TiXmlElement* NextSiblingElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement( const char * ) const;
+	TiXmlElement* NextSiblingElement( const char *_next ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* NextSiblingElement( const std::string& _value) const	{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* NextSiblingElement( const std::string& _value)				{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement()	const;
+	TiXmlElement* FirstChildElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
+	}
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement( const char * _value ) const;
+	TiXmlElement* FirstChildElement( const char * _value ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* FirstChildElement( const std::string& _value ) const	{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* FirstChildElement( const std::string& _value )				{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** Query the type (as an enumerated value, above) of this node.
+		The possible types are: DOCUMENT, ELEMENT, COMMENT,
+								UNKNOWN, TEXT, and DECLARATION.
+	*/
+	int Type() const	{ return type; }
+
+	/** Return a pointer to the Document this node lives in.
+		Returns null if not in a document.
+	*/
+	const TiXmlDocument* GetDocument() const;
+	TiXmlDocument* GetDocument() {
+		return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
+	}
+
+	/// Returns true if this node has no children.
+	bool NoChildren() const						{ return !firstChild; }
+
+	virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlElement*           ToElement()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlText*	            ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	/** Create an exact duplicate of this node and return it. The memory must be deleted
+		by the caller. 
+	*/
+	virtual TiXmlNode* Clone() const = 0;
+
+	/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the 
+		XML tree will be conditionally visited and the host will be called back
+		via the TiXmlVisitor interface.
+
+		This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
+		the XML for the callbacks, so the performance of TinyXML is unchanged by using this
+		interface versus any other.)
+
+		The interface has been based on ideas from:
+
+		- http://www.saxproject.org/
+		- http://c2.com/cgi/wiki?HierarchicalVisitorPattern 
+
+		Which are both good references for "visiting".
+
+		An example of using Accept():
+		@verbatim
+		TiXmlPrinter printer;
+		tinyxmlDoc.Accept( &printer );
+		const char* xmlcstr = printer.CStr();
+		@endverbatim
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
+
+protected:
+	TiXmlNode( NodeType _type );
+
+	// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
+	// and the assignment operator.
+	void CopyTo( TiXmlNode* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    // The real work of the input operator.
+	virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
+	#endif
+
+	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+	TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
+
+	TiXmlNode*		parent;
+	NodeType		type;
+
+	TiXmlNode*		firstChild;
+	TiXmlNode*		lastChild;
+
+	TIXML_STRING	value;
+
+	TiXmlNode*		prev;
+	TiXmlNode*		next;
+
+private:
+	TiXmlNode( const TiXmlNode& );				// not implemented.
+	void operator=( const TiXmlNode& base );	// not allowed.
+};
+
+
+/** An attribute is a name-value pair. Elements have an arbitrary
+	number of attributes, each with a unique name.
+
+	@note The attributes are not TiXmlNodes, since they are not
+		  part of the tinyXML document object model. There are other
+		  suggested ways to look at this problem.
+*/
+class TiXmlAttribute : public TiXmlBase
+{
+	friend class TiXmlAttributeSet;
+
+public:
+	/// Construct an empty attribute.
+	TiXmlAttribute() : TiXmlBase()
+	{
+		document = 0;
+		prev = next = 0;
+	}
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlAttribute( const std::string& _name, const std::string& _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+	#endif
+
+	/// Construct an attribute with a name and value.
+	TiXmlAttribute( const char * _name, const char * _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+
+	const char*		Name()  const		{ return name.c_str(); }		///< Return the name of this attribute.
+	const char*		Value() const		{ return value.c_str(); }		///< Return the value of this attribute.
+	#ifdef TIXML_USE_STL
+	const std::string& ValueStr() const	{ return value; }				///< Return the value of this attribute.
+	#endif
+	int				IntValue() const;									///< Return the value of this attribute, converted to an integer.
+	double			DoubleValue() const;								///< Return the value of this attribute, converted to a double.
+
+	// Get the tinyxml string representation
+	const TIXML_STRING& NameTStr() const { return name; }
+
+	/** QueryIntValue examines the value string. It is an alternative to the
+		IntValue() method with richer error checking.
+		If the value is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE.
+
+		A specialized but useful call. Note that for success it returns 0,
+		which is the opposite of almost all other TinyXml calls.
+	*/
+	int QueryIntValue( int* _value ) const;
+	/// QueryDoubleValue examines the value string. See QueryIntValue().
+	int QueryDoubleValue( double* _value ) const;
+
+	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
+	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
+
+	void SetIntValue( int _value );										///< Set the value from an integer.
+	void SetDoubleValue( double _value );								///< Set the value from a double.
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetName( const std::string& _name )	{ name = _name; }	
+	/// STL std::string form.	
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Get the next sibling attribute in the DOM. Returns null at end.
+	const TiXmlAttribute* Next() const;
+	TiXmlAttribute* Next() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
+	}
+
+	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
+	const TiXmlAttribute* Previous() const;
+	TiXmlAttribute* Previous() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
+	}
+
+	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
+	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
+
+	/*	Attribute parsing starts: first letter of the name
+						 returns: the next char after the value end quote
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	// Prints this Attribute to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+	void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+
+	// [internal use]
+	// Set the document pointer so the attribute can report errors.
+	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
+
+private:
+	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
+	void operator=( const TiXmlAttribute& base );	// not allowed.
+
+	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
+	TIXML_STRING name;
+	TIXML_STRING value;
+	TiXmlAttribute*	prev;
+	TiXmlAttribute*	next;
+};
+
+
+/*	A class used to manage a group of attributes.
+	It is only used internally, both by the ELEMENT and the DECLARATION.
+	
+	The set can be changed transparent to the Element and Declaration
+	classes that use it, but NOT transparent to the Attribute
+	which has to implement a next() and previous() method. Which makes
+	it a bit problematic and prevents the use of STL.
+
+	This version is implemented with circular lists because:
+		- I like circular lists
+		- it demonstrates some independence from the (typical) doubly linked list.
+*/
+class TiXmlAttributeSet
+{
+public:
+	TiXmlAttributeSet();
+	~TiXmlAttributeSet();
+
+	void Add( TiXmlAttribute* attribute );
+	void Remove( TiXmlAttribute* attribute );
+
+	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+
+	TiXmlAttribute*	Find( const char* _name ) const;
+	TiXmlAttribute* FindOrCreate( const char* _name );
+
+#	ifdef TIXML_USE_STL
+	TiXmlAttribute*	Find( const std::string& _name ) const;
+	TiXmlAttribute* FindOrCreate( const std::string& _name );
+#	endif
+
+
+private:
+	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
+	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
+	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
+	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
+
+	TiXmlAttribute sentinel;
+};
+
+
+/** The element is a container class. It has a value, the element name,
+	and can contain other elements, text, comments, and unknowns.
+	Elements also contain an arbitrary number of attributes.
+*/
+class TiXmlElement : public TiXmlNode
+{
+public:
+	/// Construct an element.
+	TiXmlElement (const char * in_value);
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlElement( const std::string& _value );
+	#endif
+
+	TiXmlElement( const TiXmlElement& );
+
+	void operator=( const TiXmlElement& base );
+
+	virtual ~TiXmlElement();
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+	*/
+	const char* Attribute( const char* name ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an integer,
+		the integer value will be put in the return 'i', if 'i'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, int* i ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an double,
+		the double value will be put in the return 'd', if 'd'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, double* d ) const;
+
+	/** QueryIntAttribute examines the attribute - it is an alternative to the
+		Attribute() method with richer error checking.
+		If the attribute is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE. If the attribute
+		does not exist, then TIXML_NO_ATTRIBUTE is returned.
+	*/	
+	int QueryIntAttribute( const char* name, int* _value ) const;
+	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
+	int QueryDoubleAttribute( const char* name, double* _value ) const;
+	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
+	int QueryFloatAttribute( const char* name, float* _value ) const {
+		double d;
+		int result = QueryDoubleAttribute( name, &d );
+		if ( result == TIXML_SUCCESS ) {
+			*_value = (float)d;
+		}
+		return result;
+	}
+
+    #ifdef TIXML_USE_STL
+	/// QueryStringAttribute examines the attribute - see QueryIntAttribute().
+	int QueryStringAttribute( const char* name, std::string* _value ) const {
+		const char* cstr = Attribute( name );
+		if ( cstr ) {
+			*_value = std::string( cstr );
+			return TIXML_SUCCESS;
+		}
+		return TIXML_NO_ATTRIBUTE;
+	}
+
+	/** Template form of the attribute query which will try to read the
+		attribute into the specified type. Very easy, very powerful, but
+		be careful to make sure to call this with the correct type.
+		
+		NOTE: This method doesn't work correctly for 'string' types that contain spaces.
+
+		@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
+	*/
+	template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+
+		std::stringstream sstream( node->ValueStr() );
+		sstream >> *outValue;
+		if ( !sstream.fail() )
+			return TIXML_SUCCESS;
+		return TIXML_WRONG_TYPE;
+	}
+
+	int QueryValueAttribute( const std::string& name, std::string* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+		*outValue = node->ValueStr();
+		return TIXML_SUCCESS;
+	}
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char* name, const char * _value );
+
+    #ifdef TIXML_USE_STL
+	const std::string* Attribute( const std::string& name ) const;
+	const std::string* Attribute( const std::string& name, int* i ) const;
+	const std::string* Attribute( const std::string& name, double* d ) const;
+	int QueryIntAttribute( const std::string& name, int* _value ) const;
+	int QueryDoubleAttribute( const std::string& name, double* _value ) const;
+
+	/// STL std::string form.
+	void SetAttribute( const std::string& name, const std::string& _value );
+	///< STL std::string form.
+	void SetAttribute( const std::string& name, int _value );
+	///< STL std::string form.
+	void SetDoubleAttribute( const std::string& name, double value );
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char * name, int value );
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetDoubleAttribute( const char * name, double value );
+
+	/** Deletes an attribute with the given name.
+	*/
+	void RemoveAttribute( const char * name );
+    #ifdef TIXML_USE_STL
+	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
+	#endif
+
+	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
+	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
+	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
+	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
+
+	/** Convenience function for easy access to the text inside an element. Although easy
+		and concise, GetText() is limited compared to getting the TiXmlText child
+		and accessing it directly.
+	
+		If the first child of 'this' is a TiXmlText, the GetText()
+		returns the character string of the Text node, else null is returned.
+
+		This is a convenient method for getting the text of simple contained text:
+		@verbatim
+		<foo>This is text</foo>
+		const char* str = fooElement->GetText();
+		@endverbatim
+
+		'str' will be a pointer to "This is text". 
+		
+		Note that this function can be misleading. If the element foo was created from
+		this XML:
+		@verbatim
+		<foo><b>This is text</b></foo> 
+		@endverbatim
+
+		then the value of str would be null. The first child node isn't a text node, it is
+		another element. From this XML:
+		@verbatim
+		<foo>This is <b>text</b></foo> 
+		@endverbatim
+		GetText() will return "This is ".
+
+		WARNING: GetText() accesses a child node - don't become confused with the 
+				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
+				 safe type casts on the referenced node.
+	*/
+	const char* GetText() const;
+
+	/// Creates a new Element and returns it - the returned element is a copy.
+	virtual TiXmlNode* Clone() const;
+	// Print the Element to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: next char past '<'
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlElement*           ToElement()	          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+
+	void CopyTo( TiXmlElement* target ) const;
+	void ClearThis();	// like clear, but initializes 'this' object as well
+
+	// Used to be public [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+	/*	[internal use]
+		Reads the "value" of the element -- another element, or text.
+		This should terminate with the current end tag.
+	*/
+	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+private:
+	TiXmlAttributeSet attributeSet;
+};
+
+
+/**	An XML comment.
+*/
+class TiXmlComment : public TiXmlNode
+{
+public:
+	/// Constructs an empty comment.
+	TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
+	/// Construct a comment from text.
+	TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
+		SetValue( _value );
+	}
+	TiXmlComment( const TiXmlComment& );
+	void operator=( const TiXmlComment& base );
+
+	virtual ~TiXmlComment()	{}
+
+	/// Returns a copy of this Comment.
+	virtual TiXmlNode* Clone() const;
+	// Write this Comment to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: at the ! of the !--
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlComment*  ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlComment*  ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlComment* target ) const;
+
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+//	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+private:
+
+};
+
+
+/** XML text. A text node can have 2 ways to output the next. "normal" output 
+	and CDATA. It will default to the mode it was parsed from the XML file and
+	you generally want to leave it alone, but you can change the output mode with 
+	SetCDATA() and query it with CDATA().
+*/
+class TiXmlText : public TiXmlNode
+{
+	friend class TiXmlElement;
+public:
+	/** Constructor for text element. By default, it is treated as 
+		normal, encoded text. If you want it be output as a CDATA text
+		element, set the parameter _cdata to 'true'
+	*/
+	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	virtual ~TiXmlText() {}
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	#endif
+
+	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT )	{ copy.CopyTo( this ); }
+	void operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); }
+
+	// Write this text object to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/// Queries whether this represents text using a CDATA section.
+	bool CDATA() const				{ return cdata; }
+	/// Turns on or off a CDATA representation of text.
+	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	///  [internal use] Creates a new Element and returns it.
+	virtual TiXmlNode* Clone() const;
+	void CopyTo( TiXmlText* target ) const;
+
+	bool Blank() const;	// returns true if all white space and new lines
+	// [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	bool cdata;			// true if this should be input and output as a CDATA style text element
+};
+
+
+/** In correct XML the declaration is the first entry in the file.
+	@verbatim
+		<?xml version="1.0" standalone="yes"?>
+	@endverbatim
+
+	TinyXml will happily read or write files without a declaration,
+	however. There are 3 possible attributes to the declaration:
+	version, encoding, and standalone.
+
+	Note: In this version of the code, the attributes are
+	handled as special cases, not generic attributes, simply
+	because there can only be at most 3 and they are always the same.
+*/
+class TiXmlDeclaration : public TiXmlNode
+{
+public:
+	/// Construct an empty declaration.
+	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
+
+#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDeclaration(	const std::string& _version,
+						const std::string& _encoding,
+						const std::string& _standalone );
+#endif
+
+	/// Construct.
+	TiXmlDeclaration(	const char* _version,
+						const char* _encoding,
+						const char* _standalone );
+
+	TiXmlDeclaration( const TiXmlDeclaration& copy );
+	void operator=( const TiXmlDeclaration& copy );
+
+	virtual ~TiXmlDeclaration()	{}
+
+	/// Version. Will return an empty string if none was found.
+	const char *Version() const			{ return version.c_str (); }
+	/// Encoding. Will return an empty string if none was found.
+	const char *Encoding() const		{ return encoding.c_str (); }
+	/// Is this a standalone document?
+	const char *Standalone() const		{ return standalone.c_str (); }
+
+	/// Creates a copy of this Declaration and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this declaration to a FILE stream.
+	virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlDeclaration* target ) const;
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+	TIXML_STRING version;
+	TIXML_STRING encoding;
+	TIXML_STRING standalone;
+};
+
+
+/** Any tag that tinyXml doesn't recognize is saved as an
+	unknown. It is a tag of text, but should not be modified.
+	It will be written back to the XML, unchanged, when the file
+	is saved.
+
+	DTD tags get thrown into TiXmlUnknowns.
+*/
+class TiXmlUnknown : public TiXmlNode
+{
+public:
+	TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )	{}
+	virtual ~TiXmlUnknown() {}
+
+	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )		{ copy.CopyTo( this ); }
+	void operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); }
+
+	/// Creates a copy of this Unknown and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this Unknown to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlUnknown*     ToUnknown()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()	    { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected:
+	void CopyTo( TiXmlUnknown* target ) const;
+
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+};
+
+
+/** Always the top level node. A document binds together all the
+	XML pieces. It can be saved, loaded, and printed to the screen.
+	The 'value' of a document node is the xml file name.
+*/
+class TiXmlDocument : public TiXmlNode
+{
+public:
+	/// Create an empty document, that has no name.
+	TiXmlDocument();
+	/// Create a document with a name. The name of the document is also the filename of the xml.
+	TiXmlDocument( const char * documentName );
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDocument( const std::string& documentName );
+	#endif
+
+	TiXmlDocument( const TiXmlDocument& copy );
+	void operator=( const TiXmlDocument& copy );
+
+	virtual ~TiXmlDocument() {}
+
+	/** Load a file using the current document value.
+		Returns true if successful. Will delete any existing
+		document data before loading.
+	*/
+	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the current document value. Returns true if successful.
+	bool SaveFile() const;
+	/// Load a file using the given filename. Returns true if successful.
+	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given filename. Returns true if successful.
+	bool SaveFile( const char * filename ) const;
+	/** Load a file using the given FILE*. Returns true if successful. Note that this method
+		doesn't stream - the entire object pointed at by the FILE*
+		will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
+		file location. Streaming may be added in the future.
+	*/
+	bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given FILE*. Returns true if successful.
+	bool SaveFile( FILE* ) const;
+
+	#ifdef TIXML_USE_STL
+	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
+	{
+		return LoadFile( filename.c_str(), encoding );
+	}
+	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
+	{
+		return SaveFile( filename.c_str() );
+	}
+	#endif
+
+	/** Parse the given null terminated block of xml data. Passing in an encoding to this
+		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
+		to use that encoding, regardless of what TinyXml might otherwise try to detect.
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+	/** Get the root element -- the only top level element -- of the document.
+		In well formed XML, there should only be one. TinyXml is tolerant of
+		multiple elements at the document level.
+	*/
+	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
+	TiXmlElement* RootElement()					{ return FirstChildElement(); }
+
+	/** If an error occurs, Error will be set to true. Also,
+		- The ErrorId() will contain the integer identifier of the error (not generally useful)
+		- The ErrorDesc() method will return the name of the error. (very useful)
+		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
+	*/	
+	bool Error() const						{ return error; }
+
+	/// Contains a textual (english) description of the error if one occurs.
+	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
+
+	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
+		prefer the ErrorId, this function will fetch it.
+	*/
+	int ErrorId()	const				{ return errorId; }
+
+	/** Returns the location (if known) of the error. The first column is column 1, 
+		and the first row is row 1. A value of 0 means the row and column wasn't applicable
+		(memory errors, for example, have no row/column) or the parser lost the error. (An
+		error in the error reporting, in that case.)
+
+		@sa SetTabSize, Row, Column
+	*/
+	int ErrorRow() const	{ return errorLocation.row+1; }
+	int ErrorCol() const	{ return errorLocation.col+1; }	///< The column where the error occured. See ErrorRow()
+
+	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
+		to report the correct values for row and column. It does not change the output
+		or input in any way.
+		
+		By calling this method, with a tab size
+		greater than 0, the row and column of each node and attribute is stored
+		when the file is loaded. Very useful for tracking the DOM back in to
+		the source file.
+
+		The tab size is required for calculating the location of nodes. If not
+		set, the default of 4 is used. The tabsize is set per document. Setting
+		the tabsize to 0 disables row/column tracking.
+
+		Note that row and column tracking is not supported when using operator>>.
+
+		The tab size needs to be enabled before the parse or load. Correct usage:
+		@verbatim
+		TiXmlDocument doc;
+		doc.SetTabSize( 8 );
+		doc.Load( "myfile.xml" );
+		@endverbatim
+
+		@sa Row, Column
+	*/
+	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
+
+	int TabSize() const	{ return tabsize; }
+
+	/** If you have handled the error, it can be reset with this call. The error
+		state is automatically cleared if you Parse a new XML block.
+	*/
+	void ClearError()						{	error = false; 
+												errorId = 0; 
+												errorDesc = ""; 
+												errorLocation.row = errorLocation.col = 0; 
+												//errorLocation.last = 0; 
+											}
+
+	/** Write the document to standard out using formatted printing ("pretty print"). */
+	void Print() const						{ Print( stdout, 0 ); }
+
+	/* Write the document to a string using formatted printing ("pretty print"). This
+		will allocate a character array (new char[]) and return it as a pointer. The
+		calling code pust call delete[] on the return char* to avoid a memory leak.
+	*/
+	//char* PrintToMemory() const; 
+
+	/// Print this Document to a FILE stream.
+	virtual void Print( FILE* cfile, int depth = 0 ) const;
+	// [internal use]
+	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+	virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	void CopyTo( TiXmlDocument* target ) const;
+
+	bool error;
+	int  errorId;
+	TIXML_STRING errorDesc;
+	int tabsize;
+	TiXmlCursor errorLocation;
+	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
+};
+
+
+/**
+	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
+	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
+	DOM structure. It is a separate utility class.
+
+	Take an example:
+	@verbatim
+	<Document>
+		<Element attributeA = "valueA">
+			<Child attributeB = "value1" />
+			<Child attributeB = "value2" />
+		</Element>
+	<Document>
+	@endverbatim
+
+	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
+	easy to write a *lot* of code that looks like:
+
+	@verbatim
+	TiXmlElement* root = document.FirstChildElement( "Document" );
+	if ( root )
+	{
+		TiXmlElement* element = root->FirstChildElement( "Element" );
+		if ( element )
+		{
+			TiXmlElement* child = element->FirstChildElement( "Child" );
+			if ( child )
+			{
+				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
+				if ( child2 )
+				{
+					// Finally do something useful.
+	@endverbatim
+
+	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
+	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe 
+	and correct to use:
+
+	@verbatim
+	TiXmlHandle docHandle( &document );
+	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
+	if ( child2 )
+	{
+		// do something useful
+	@endverbatim
+
+	Which is MUCH more concise and useful.
+
+	It is also safe to copy handles - internally they are nothing more than node pointers.
+	@verbatim
+	TiXmlHandle handleCopy = handle;
+	@endverbatim
+
+	What they should not be used for is iteration:
+
+	@verbatim
+	int i=0; 
+	while ( true )
+	{
+		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
+		if ( !child )
+			break;
+		// do something
+		++i;
+	}
+	@endverbatim
+
+	It seems reasonable, but it is in fact two embedded while loops. The Child method is 
+	a linear walk to find the element, so this code would iterate much more than it needs 
+	to. Instead, prefer:
+
+	@verbatim
+	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
+
+	for( child; child; child=child->NextSiblingElement() )
+	{
+		// do something
+	}
+	@endverbatim
+*/
+class TiXmlHandle
+{
+public:
+	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
+	/// Copy constructor
+	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
+	TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
+
+	/// Return a handle to the first child node.
+	TiXmlHandle FirstChild() const;
+	/// Return a handle to the first child node with the given name.
+	TiXmlHandle FirstChild( const char * value ) const;
+	/// Return a handle to the first child element.
+	TiXmlHandle FirstChildElement() const;
+	/// Return a handle to the first child element with the given name.
+	TiXmlHandle FirstChildElement( const char * value ) const;
+
+	/** Return a handle to the "index" child with the given name. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( const char* value, int index ) const;
+	/** Return a handle to the "index" child. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( int index ) const;
+	/** Return a handle to the "index" child element with the given name. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( const char* value, int index ) const;
+	/** Return a handle to the "index" child element. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( int index ) const;
+
+	#ifdef TIXML_USE_STL
+	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
+	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
+
+	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
+	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
+	#endif
+
+	/** Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* ToNode() const			{ return node; } 
+	/** Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* ToElement() const		{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+	/**	Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* ToText() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+	/** Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* ToUnknown() const		{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+	/** @deprecated use ToNode. 
+		Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* Node() const			{ return ToNode(); } 
+	/** @deprecated use ToElement. 
+		Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* Element() const	{ return ToElement(); }
+	/**	@deprecated use ToText()
+		Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* Text() const			{ return ToText(); }
+	/** @deprecated use ToUnknown()
+		Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* Unknown() const	{ return ToUnknown(); }
+
+private:
+	TiXmlNode* node;
+};
+
+
+/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
+
+	-# Print to memory (especially in non-STL mode)
+	-# Control formatting (line endings, etc.)
+
+	When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
+	Before calling Accept() you can call methods to control the printing
+	of the XML document. After TiXmlNode::Accept() is called, the printed document can
+	be accessed via the CStr(), Str(), and Size() methods.
+
+	TiXmlPrinter uses the Visitor API.
+	@verbatim
+	TiXmlPrinter printer;
+	printer.SetIndent( "\t" );
+
+	doc.Accept( &printer );
+	fprintf( stdout, "%s", printer.CStr() );
+	@endverbatim
+*/
+class TiXmlPrinter : public TiXmlVisitor
+{
+public:
+	TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
+					 buffer(), indent( "    " ), lineBreak( "\n" ) {}
+
+	virtual bool VisitEnter( const TiXmlDocument& doc );
+	virtual bool VisitExit( const TiXmlDocument& doc );
+
+	virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
+	virtual bool VisitExit( const TiXmlElement& element );
+
+	virtual bool Visit( const TiXmlDeclaration& declaration );
+	virtual bool Visit( const TiXmlText& text );
+	virtual bool Visit( const TiXmlComment& comment );
+	virtual bool Visit( const TiXmlUnknown& unknown );
+
+	/** Set the indent characters for printing. By default 4 spaces
+		but tab (\t) is also useful, or null/empty string for no indentation.
+	*/
+	void SetIndent( const char* _indent )			{ indent = _indent ? _indent : "" ; }
+	/// Query the indention string.
+	const char* Indent()							{ return indent.c_str(); }
+	/** Set the line breaking string. By default set to newline (\n). 
+		Some operating systems prefer other characters, or can be
+		set to the null/empty string for no indenation.
+	*/
+	void SetLineBreak( const char* _lineBreak )		{ lineBreak = _lineBreak ? _lineBreak : ""; }
+	/// Query the current line breaking string.
+	const char* LineBreak()							{ return lineBreak.c_str(); }
+
+	/** Switch over to "stream printing" which is the most dense formatting without 
+		linebreaks. Common when the XML is needed for network transmission.
+	*/
+	void SetStreamPrinting()						{ indent = "";
+													  lineBreak = "";
+													}	
+	/// Return the result.
+	const char* CStr()								{ return buffer.c_str(); }
+	/// Return the length of the result string.
+	size_t Size()									{ return buffer.size(); }
+
+	#ifdef TIXML_USE_STL
+	/// Return the result.
+	const std::string& Str()						{ return buffer; }
+	#endif
+
+private:
+	void DoIndent()	{
+		for( int i=0; i<depth; ++i )
+			buffer += indent;
+	}
+	void DoLineBreak() {
+		buffer += lineBreak;
+	}
+
+	int depth;
+	bool simpleTextPrint;
+	TIXML_STRING buffer;
+	TIXML_STRING indent;
+	TIXML_STRING lineBreak;
+};
+
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+
+#endif
+

+ 52 - 0
天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinyxmlerror.cpp

@@ -0,0 +1,52 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include "tinyxml.h"
+
+// The goal of the seperate error file is to make the first
+// step towards localization. tinyxml (currently) only supports
+// english error messages, but the could now be translated.
+//
+// It also cleans up the code a bit.
+//
+
+const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
+{
+	"No error",
+	"Error",
+	"Failed to open file",
+	"Error parsing Element.",
+	"Failed to read Element name",
+	"Error reading Element value.",
+	"Error reading Attributes.",
+	"Error: empty tag.",
+	"Error reading end tag.",
+	"Error parsing Unknown.",
+	"Error parsing Comment.",
+	"Error parsing Declaration.",
+	"Error document empty.",
+	"Error null (0) or unexpected EOF found in input stream.",
+	"Error parsing CDATA.",
+	"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
+};

+ 1635 - 0
天津大学/tjuvv7-src/src/common/common/xodr/TinyXML/tinyxmlparser.cpp

@@ -0,0 +1,1635 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must 
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and 
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source 
+distribution.
+*/
+
+#include <ctype.h>
+#include <stddef.h>
+
+#include "tinyxml.h"
+
+//#define DEBUG_PARSER
+#if defined( DEBUG_PARSER )
+#	if defined( DEBUG ) && defined( _MSC_VER )
+#		include <windows.h>
+#		define TIXML_LOG OutputDebugString
+#	else
+#		define TIXML_LOG printf
+#	endif
+#endif
+
+// Note tha "PutString" hardcodes the same list. This
+// is less flexible than it appears. Changing the entries
+// or order will break putstring.	
+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = 
+{
+	{ "&amp;",  5, '&' },
+	{ "&lt;",   4, '<' },
+	{ "&gt;",   4, '>' },
+	{ "&quot;", 6, '\"' },
+	{ "&apos;", 6, '\'' }
+};
+
+// Bunch of unicode info at:
+//		http://www.unicode.org/faq/utf_bom.html
+// Including the basic of this table, which determines the #bytes in the
+// sequence from the lead byte. 1 placed for invalid sequences --
+// although the result will be junk, pass it through as much as possible.
+// Beware of the non-characters in UTF-8:	
+//				ef bb bf (Microsoft "lead bytes")
+//				ef bf be
+//				ef bf bf 
+
+const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+const int TiXmlBase::utf8ByteTable[256] = 
+{
+	//	0	1	2	3	4	5	6	7	8	9	a	b	c	d	e	f
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x00
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x10
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x20
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x30
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x40
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x50
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x60
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x70	End of ASCII range
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x80 0x80 to 0xc1 invalid
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x90 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xa0 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xb0 
+		1,	1,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xc0 0xc2 to 0xdf 2 byte
+		2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xd0
+		3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	// 0xe0 0xe0 to 0xef 3 byte
+		4,	4,	4,	4,	4,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1	// 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
+
+
+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
+{
+	const unsigned long BYTE_MASK = 0xBF;
+	const unsigned long BYTE_MARK = 0x80;
+	const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+	if (input < 0x80) 
+		*length = 1;
+	else if ( input < 0x800 )
+		*length = 2;
+	else if ( input < 0x10000 )
+		*length = 3;
+	else if ( input < 0x200000 )
+		*length = 4;
+	else
+		{ *length = 0; return; }	// This code won't covert this correctly anyway.
+
+	output += *length;
+
+	// Scary scary fall throughs.
+	switch (*length) 
+	{
+		case 4:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 3:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 2:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 1:
+			--output; 
+			*output = (char)(input | FIRST_BYTE_MARK[*length]);
+	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalpha( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalpha( anyByte );
+//	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalnum( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalnum( anyByte );
+//	}
+}
+
+
+class TiXmlParsingData
+{
+	friend class TiXmlDocument;
+  public:
+	void Stamp( const char* now, TiXmlEncoding encoding );
+
+	const TiXmlCursor& Cursor()	{ return cursor; }
+
+  private:
+	// Only used by the document!
+	TiXmlParsingData( const char* start, int _tabsize, int row, int col )
+	{
+		assert( start );
+		stamp = start;
+		tabsize = _tabsize;
+		cursor.row = row;
+		cursor.col = col;
+	}
+
+	TiXmlCursor		cursor;
+	const char*		stamp;
+	int				tabsize;
+};
+
+
+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
+{
+	assert( now );
+
+	// Do nothing if the tabsize is 0.
+	if ( tabsize < 1 )
+	{
+		return;
+	}
+
+	// Get the current row, column.
+	int row = cursor.row;
+	int col = cursor.col;
+	const char* p = stamp;
+	assert( p );
+
+	while ( p < now )
+	{
+		// Treat p as unsigned, so we have a happy compiler.
+		const unsigned char* pU = (const unsigned char*)p;
+
+		// Code contributed by Fletcher Dunn: (modified by lee)
+		switch (*pU) {
+			case 0:
+				// We *should* never get here, but in case we do, don't
+				// advance past the terminating null character, ever
+				return;
+
+			case '\r':
+				// bump down to the next line
+				++row;
+				col = 0;				
+				// Eat the character
+				++p;
+
+				// Check for \r\n sequence, and treat this as a single character
+				if (*p == '\n') {
+					++p;
+				}
+				break;
+
+			case '\n':
+				// bump down to the next line
+				++row;
+				col = 0;
+
+				// Eat the character
+				++p;
+
+				// Check for \n\r sequence, and treat this as a single
+				// character.  (Yes, this bizarre thing does occur still
+				// on some arcane platforms...)
+				if (*p == '\r') {
+					++p;
+				}
+				break;
+
+			case '\t':
+				// Eat the character
+				++p;
+
+				// Skip to next tab stop
+				col = (col / tabsize + 1) * tabsize;
+				break;
+
+			case TIXML_UTF_LEAD_0:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					if ( *(p+1) && *(p+2) )
+					{
+						// In these cases, don't advance the column. These are
+						// 0-width spaces.
+						if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
+							p += 3;	
+						else
+							{ p +=3; ++col; }	// A normal character.
+					}
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+
+			default:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					// Eat the 1 to 4 byte utf8 character.
+					int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
+					if ( step == 0 )
+						step = 1;		// Error case from bad encoding, but handle gracefully.
+					p += step;
+
+					// Just advance one column, of course.
+					++col;
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+		}
+	}
+	cursor.row = row;
+	cursor.col = col;
+	assert( cursor.row >= -1 );
+	assert( cursor.col >= -1 );
+	stamp = p;
+	assert( stamp );
+}
+
+
+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
+{
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+	if ( encoding == TIXML_ENCODING_UTF8 )
+	{
+		while ( *p )
+		{
+			const unsigned char* pU = (const unsigned char*)p;
+			
+			// Skip the stupid Microsoft UTF-8 Byte order marks
+			if (	*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==TIXML_UTF_LEAD_1 
+				 && *(pU+2)==TIXML_UTF_LEAD_2 )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbeU )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbfU )
+			{
+				p += 3;
+				continue;
+			}
+
+			if ( IsWhiteSpace( *p ) )		// Still using old rules for white space.
+				++p;
+			else
+				break;
+		}
+	}
+	else
+	{
+		while ( *p && IsWhiteSpace( *p ) )
+			++p;
+	}
+
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
+{
+	for( ;; )
+	{
+		if ( !in->good() ) return false;
+
+		int c = in->peek();
+		// At this scope, we can't get to a document. So fail silently.
+		if ( !IsWhiteSpace( c ) || c <= 0 )
+			return true;
+
+		*tag += (char) in->get();
+	}
+}
+
+/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
+{
+	//assert( character > 0 && character < 128 );	// else it won't work in utf-8
+	while ( in->good() )
+	{
+		int c = in->peek();
+		if ( c == character )
+			return true;
+		if ( c <= 0 )		// Silent failure: can't get document at this scope
+			return false;
+
+		in->get();
+		*tag += (char) c;
+	}
+	return false;
+}
+#endif
+
+// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
+// "assign" optimization removes over 10% of the execution time.
+//
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
+{
+	// Oddly, not supported on some comilers,
+	//name->clear();
+	// So use this:
+	*name = "";
+	assert( p );
+
+	// Names start with letters or underscores.
+	// Of course, in unicode, tinyxml has no idea what a letter *is*. The
+	// algorithm is generous.
+	//
+	// After that, they can be letters, underscores, numbers,
+	// hyphens, or colons. (Colons are valid ony for namespaces,
+	// but tinyxml can't tell namespaces from names.)
+	if (    p && *p 
+		 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
+	{
+		const char* start = p;
+		while(		p && *p
+				&&	(		IsAlphaNum( (unsigned char ) *p, encoding ) 
+						 || *p == '_'
+						 || *p == '-'
+						 || *p == '.'
+						 || *p == ':' ) )
+		{
+			//(*name) += *p; // expensive
+			++p;
+		}
+		if ( p-start > 0 ) {
+			name->assign( start, p-start );
+		}
+		return p;
+	}
+	return 0;
+}
+
+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
+{
+	// Presume an entity, and pull it out.
+    TIXML_STRING ent;
+	int i;
+	*length = 0;
+
+	if ( *(p+1) && *(p+1) == '#' && *(p+2) )
+	{
+		unsigned long ucs = 0;
+		ptrdiff_t delta = 0;
+		unsigned mult = 1;
+
+		if ( *(p+2) == 'x' )
+		{
+			// Hexadecimal.
+			if ( !*(p+3) ) return 0;
+
+			const char* q = p+3;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != 'x' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else if ( *q >= 'a' && *q <= 'f' )
+					ucs += mult * (*q - 'a' + 10);
+				else if ( *q >= 'A' && *q <= 'F' )
+					ucs += mult * (*q - 'A' + 10 );
+				else 
+					return 0;
+				mult *= 16;
+				--q;
+			}
+		}
+		else
+		{
+			// Decimal.
+			if ( !*(p+2) ) return 0;
+
+			const char* q = p+2;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != '#' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else 
+					return 0;
+				mult *= 10;
+				--q;
+			}
+		}
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			// convert the UCS to UTF-8
+			ConvertUTF32ToUTF8( ucs, value, length );
+		}
+		else
+		{
+			*value = (char)ucs;
+			*length = 1;
+		}
+		return p + delta + 1;
+	}
+
+	// Now try to match it.
+	for( i=0; i<NUM_ENTITY; ++i )
+	{
+		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
+		{
+			assert( strlen( entity[i].str ) == entity[i].strLength );
+			*value = entity[i].chr;
+			*length = 1;
+			return ( p + entity[i].strLength );
+		}
+	}
+
+	// So it wasn't an entity, its unrecognized, or something like that.
+	*value = *p;	// Don't put back the last one, since we return it!
+	//*length = 1;	// Leave unrecognized entities - this doesn't really work.
+					// Just writes strange XML.
+	return p+1;
+}
+
+
+bool TiXmlBase::StringEqual( const char* p,
+							 const char* tag,
+							 bool ignoreCase,
+							 TiXmlEncoding encoding )
+{
+	assert( p );
+	assert( tag );
+	if ( !p || !*p )
+	{
+		assert( 0 );
+		return false;
+	}
+
+	const char* q = p;
+
+	if ( ignoreCase )
+	{
+		while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )
+			return true;
+	}
+	else
+	{
+		while ( *q && *tag && *q == *tag )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
+			return true;
+	}
+	return false;
+}
+
+const char* TiXmlBase::ReadText(	const char* p, 
+									TIXML_STRING * text, 
+									bool trimWhiteSpace, 
+									const char* endTag, 
+									bool caseInsensitive,
+									TiXmlEncoding encoding )
+{
+    *text = "";
+	if (    !trimWhiteSpace			// certain tags always keep whitespace
+		 || !condenseWhiteSpace )	// if true, whitespace is always kept
+	{
+		// Keep all the white space.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding )
+			  )
+		{
+			int len;
+			char cArr[4] = { 0, 0, 0, 0 };
+			p = GetChar( p, cArr, &len, encoding );
+			text->append( cArr, len );
+		}
+	}
+	else
+	{
+		bool whitespace = false;
+
+		// Remove leading white space:
+		p = SkipWhiteSpace( p, encoding );
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding ) )
+		{
+			if ( *p == '\r' || *p == '\n' )
+			{
+				whitespace = true;
+				++p;
+			}
+			else if ( IsWhiteSpace( *p ) )
+			{
+				whitespace = true;
+				++p;
+			}
+			else
+			{
+				// If we've found whitespace, add it before the
+				// new character. Any whitespace just becomes a space.
+				if ( whitespace )
+				{
+					(*text) += ' ';
+					whitespace = false;
+				}
+				int len;
+				char cArr[4] = { 0, 0, 0, 0 };
+				p = GetChar( p, cArr, &len, encoding );
+				if ( len == 1 )
+					(*text) += cArr[0];	// more efficient
+				else
+					text->append( cArr, len );
+			}
+		}
+	}
+	if ( p && *p ) 
+		p += strlen( endTag );
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	// The basic issue with a document is that we don't know what we're
+	// streaming. Read something presumed to be a tag (and hope), then
+	// identify it, and call the appropriate stream method on the tag.
+	//
+	// This "pre-streaming" will never read the closing ">" so the
+	// sub-tag can orient itself.
+
+	if ( !StreamTo( in, '<', tag ) ) 
+	{
+		SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return;
+	}
+
+	while ( in->good() )
+	{
+		int tagIndex = (int) tag->length();
+		while ( in->good() && in->peek() != '>' )
+		{
+			int c = in->get();
+			if ( c <= 0 )
+			{
+				SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+				break;
+			}
+			(*tag) += (char) c;
+		}
+
+		if ( in->good() )
+		{
+			// We now have something we presume to be a node of 
+			// some sort. Identify it, and call the node to
+			// continue streaming.
+			TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
+
+			if ( node )
+			{
+				node->StreamIn( in, tag );
+				bool isElement = node->ToElement() != 0;
+				delete node;
+				node = 0;
+
+				// If this is the root element, we're done. Parsing will be
+				// done by the >> operator.
+				if ( isElement )
+				{
+					return;
+				}
+			}
+			else
+			{
+				SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+				return;
+			}
+		}
+	}
+	// We should have returned sooner.
+	SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+}
+
+#endif
+
+const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
+{
+	ClearError();
+
+	// Parse away, at the document level. Since a document
+	// contains nothing but other tags, most of what happens
+	// here is skipping white space.
+	if ( !p || !*p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	// Note that, for a document, this needs to come
+	// before the while space skip, so that parsing
+	// starts from the pointer we are given.
+	location.Clear();
+	if ( prevData )
+	{
+		location.row = prevData->cursor.row;
+		location.col = prevData->cursor.col;
+	}
+	else
+	{
+		location.row = 0;
+		location.col = 0;
+	}
+	TiXmlParsingData data( p, TabSize(), location.row, location.col );
+	location = data.Cursor();
+
+	if ( encoding == TIXML_ENCODING_UNKNOWN )
+	{
+		// Check for the Microsoft UTF-8 lead bytes.
+		const unsigned char* pU = (const unsigned char*)p;
+		if (	*(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
+			 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
+			 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
+		{
+			encoding = TIXML_ENCODING_UTF8;
+			useMicrosoftBOM = true;
+		}
+	}
+
+    p = SkipWhiteSpace( p, encoding );
+	if ( !p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	while ( p && *p )
+	{
+		TiXmlNode* node = Identify( p, encoding );
+		if ( node )
+		{
+			p = node->Parse( p, &data, encoding );
+			LinkEndChild( node );
+		}
+		else
+		{
+			break;
+		}
+
+		// Did we get encoding info?
+		if (    encoding == TIXML_ENCODING_UNKNOWN
+			 && node->ToDeclaration() )
+		{
+			TiXmlDeclaration* dec = node->ToDeclaration();
+			const char* enc = dec->Encoding();
+			assert( enc );
+
+			if ( *enc == 0 )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;	// incorrect, but be nice
+			else 
+				encoding = TIXML_ENCODING_LEGACY;
+		}
+
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	// Was this empty?
+	if ( !firstChild ) {
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
+		return 0;
+	}
+
+	// All is well.
+	return p;
+}
+
+void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
+{	
+	// The first error in a chain is more accurate - don't set again!
+	if ( error )
+		return;
+
+	assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
+	error   = true;
+	errorId = err;
+	errorDesc = errorString[ errorId ];
+
+	errorLocation.Clear();
+	if ( pError && data )
+	{
+		data->Stamp( pError, encoding );
+		errorLocation = data->Cursor();
+	}
+}
+
+
+TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
+{
+	TiXmlNode* returnNode = 0;
+
+	p = SkipWhiteSpace( p, encoding );
+	if( !p || !*p || *p != '<' )
+	{
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+
+	// What is this thing? 
+	// - Elements start with a letter or underscore, but xml is reserved.
+	// - Comments: <!--
+	// - Decleration: <?xml
+	// - Everthing else is unknown to tinyxml.
+	//
+
+	const char* xmlHeader = { "<?xml" };
+	const char* commentHeader = { "<!--" };
+	const char* dtdHeader = { "<!" };
+	const char* cdataHeader = { "<![CDATA[" };
+
+	if ( StringEqual( p, xmlHeader, true, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Declaration\n" );
+		#endif
+		returnNode = new TiXmlDeclaration();
+	}
+	else if ( StringEqual( p, commentHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Comment\n" );
+		#endif
+		returnNode = new TiXmlComment();
+	}
+	else if ( StringEqual( p, cdataHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing CDATA\n" );
+		#endif
+		TiXmlText* text = new TiXmlText( "" );
+		text->SetCDATA( true );
+		returnNode = text;
+	}
+	else if ( StringEqual( p, dtdHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(1)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+	else if (    IsAlpha( *(p+1), encoding )
+			  || *(p+1) == '_' )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Element\n" );
+		#endif
+		returnNode = new TiXmlElement( "" );
+	}
+	else
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(2)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+
+	if ( returnNode )
+	{
+		// Set the parent, so it can report errors
+		returnNode->parent = this;
+	}
+	return returnNode;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
+{
+	// We're called with some amount of pre-parsing. That is, some of "this"
+	// element is in "tag". Go ahead and stream to the closing ">"
+	while( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c ;
+		
+		if ( c == '>' )
+			break;
+	}
+
+	if ( tag->length() < 3 ) return;
+
+	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
+	// If not, identify and stream.
+
+	if (    tag->at( tag->length() - 1 ) == '>' 
+		 && tag->at( tag->length() - 2 ) == '/' )
+	{
+		// All good!
+		return;
+	}
+	else if ( tag->at( tag->length() - 1 ) == '>' )
+	{
+		// There is more. Could be:
+		//		text
+		//		cdata text (which looks like another node)
+		//		closing tag
+		//		another node.
+		for ( ;; )
+		{
+			StreamWhiteSpace( in, tag );
+
+			// Do we have text?
+			if ( in->good() && in->peek() != '<' ) 
+			{
+				// Yep, text.
+				TiXmlText text( "" );
+				text.StreamIn( in, tag );
+
+				// What follows text is a closing tag or another node.
+				// Go around again and figure it out.
+				continue;
+			}
+
+			// We now have either a closing tag...or another node.
+			// We should be at a "<", regardless.
+			if ( !in->good() ) return;
+			assert( in->peek() == '<' );
+			int tagIndex = (int) tag->length();
+
+			bool closingTag = false;
+			bool firstCharFound = false;
+
+			for( ;; )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->peek();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				
+				if ( c == '>' )
+					break;
+
+				*tag += (char) c;
+				in->get();
+
+				// Early out if we find the CDATA id.
+				if ( c == '[' && tag->size() >= 9 )
+				{
+					size_t len = tag->size();
+					const char* start = tag->c_str() + len - 9;
+					if ( strcmp( start, "<![CDATA[" ) == 0 ) {
+						assert( !closingTag );
+						break;
+					}
+				}
+
+				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
+				{
+					firstCharFound = true;
+					if ( c == '/' )
+						closingTag = true;
+				}
+			}
+			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
+			// If it was not, the streaming will be done by the tag.
+			if ( closingTag )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->get();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				assert( c == '>' );
+				*tag += (char) c;
+
+				// We are done, once we've found our closing tag.
+				return;
+			}
+			else
+			{
+				// If not a closing tag, id it, and stream.
+				const char* tagloc = tag->c_str() + tagIndex;
+				TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
+				if ( !node )
+					return;
+				node->StreamIn( in, tag );
+				delete node;
+				node = 0;
+
+				// No return: go around from the beginning: text, closing tag, or node.
+			}
+		}
+	}
+}
+#endif
+
+const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	TiXmlDocument* document = GetDocument();
+
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
+		return 0;
+	}
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	if ( *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p+1, encoding );
+
+	// Read the name.
+	const char* pErr = p;
+
+    p = ReadName( p, &value, encoding );
+	if ( !p || !*p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
+		return 0;
+	}
+
+    TIXML_STRING endTag ("</");
+	endTag += value;
+
+	// Check for and read attributes. Also look for an empty
+	// tag or an end tag.
+	while ( p && *p )
+	{
+		pErr = p;
+		p = SkipWhiteSpace( p, encoding );
+		if ( !p || !*p )
+		{
+			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+			return 0;
+		}
+		if ( *p == '/' )
+		{
+			++p;
+			// Empty tag.
+			if ( *p  != '>' )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );		
+				return 0;
+			}
+			return (p+1);
+		}
+		else if ( *p == '>' )
+		{
+			// Done with attributes (if there were any.)
+			// Read the value -- which can include other
+			// elements -- read the end tag, and return.
+			++p;
+			p = ReadValue( p, data, encoding );		// Note this is an Element method, and will set the error if one happens.
+			if ( !p || !*p ) {
+				// We were looking for the end tag, but found nothing.
+				// Fix for [ 1663758 ] Failure to report error on bad XML
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+
+			// We should find the end tag now
+			// note that:
+			// </foo > and
+			// </foo> 
+			// are both valid end tags.
+			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
+			{
+				p += endTag.length();
+				p = SkipWhiteSpace( p, encoding );
+				if ( p && *p && *p == '>' ) {
+					++p;
+					return p;
+				}
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+			else
+			{
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+		}
+		else
+		{
+			// Try to read an attribute:
+			TiXmlAttribute* attrib = new TiXmlAttribute();
+			if ( !attrib )
+			{
+				return 0;
+			}
+
+			attrib->SetDocument( document );
+			pErr = p;
+			p = attrib->Parse( p, data, encoding );
+
+			if ( !p || !*p )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			// Handle the strange case of double attributes:
+			#ifdef TIXML_USE_STL
+			TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() );
+			#else
+			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
+			#endif
+			if ( node )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			attributeSet.Add( attrib );
+		}
+	}
+	return p;
+}
+
+
+const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+
+	// Read in text and elements in any order.
+	const char* pWithWhiteSpace = p;
+	p = SkipWhiteSpace( p, encoding );
+
+	while ( p && *p )
+	{
+		if ( *p != '<' )
+		{
+			// Take what we have, make a text element.
+			TiXmlText* textNode = new TiXmlText( "" );
+
+			if ( !textNode )
+			{
+			    return 0;
+			}
+
+			if ( TiXmlBase::IsWhiteSpaceCondensed() )
+			{
+				p = textNode->Parse( p, data, encoding );
+			}
+			else
+			{
+				// Special case: we want to keep the white space
+				// so that leading spaces aren't removed.
+				p = textNode->Parse( pWithWhiteSpace, data, encoding );
+			}
+
+			if ( !textNode->Blank() )
+				LinkEndChild( textNode );
+			else
+				delete textNode;
+		} 
+		else 
+		{
+			// We hit a '<'
+			// Have we hit a new element or an end tag? This could also be
+			// a TiXmlText in the "CDATA" style.
+			if ( StringEqual( p, "</", false, encoding ) )
+			{
+				return p;
+			}
+			else
+			{
+				TiXmlNode* node = Identify( p, encoding );
+				if ( node )
+				{
+					p = node->Parse( p, data, encoding );
+					LinkEndChild( node );
+				}				
+				else
+				{
+					return 0;
+				}
+			}
+		}
+		pWithWhiteSpace = p;
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	if ( !p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
+	}	
+	return p;
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	if ( !p || !*p || *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
+		return 0;
+	}
+	++p;
+    value = "";
+
+	while ( p && *p && *p != '>' )
+	{
+		value += *p;
+		++p;
+	}
+
+	if ( !p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
+	}
+	if ( *p == '>' )
+		return p+1;
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+
+		if ( c == '>' 
+			 && tag->at( tag->length() - 2 ) == '-'
+			 && tag->at( tag->length() - 3 ) == '-' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	value = "";
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	const char* startTag = "<!--";
+	const char* endTag   = "-->";
+
+	if ( !StringEqual( p, startTag, false, encoding ) )
+	{
+		document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
+		return 0;
+	}
+	p += strlen( startTag );
+
+	// [ 1475201 ] TinyXML parses entities in comments
+	// Oops - ReadText doesn't work, because we don't want to parse the entities.
+	// p = ReadText( p, &value, false, endTag, false, encoding );
+	//
+	// from the XML spec:
+	/*
+	 [Definition: Comments may appear anywhere in a document outside other markup; in addition, 
+	              they may appear within the document type declaration at places allowed by the grammar. 
+				  They are not part of the document's character data; an XML processor MAY, but need not, 
+				  make it possible for an application to retrieve the text of comments. For compatibility, 
+				  the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity 
+				  references MUST NOT be recognized within comments.
+
+				  An example of a comment:
+
+				  <!-- declarations for <head> & <body> -->
+	*/
+
+    value = "";
+	// Keep all the white space.
+	while (	p && *p && !StringEqual( p, endTag, false, encoding ) )
+	{
+		value.append( p, 1 );
+		++p;
+	}
+	if ( p && *p ) 
+		p += strlen( endTag );
+
+	return p;
+}
+
+
+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p ) return 0;
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	// Read the name, the '=' and the value.
+	const char* pErr = p;
+	p = ReadName( p, &name, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+		return 0;
+	}
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p || *p != '=' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+
+	++p;	// skip '='
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+	
+	const char* end;
+	const char SINGLE_QUOTE = '\'';
+	const char DOUBLE_QUOTE = '\"';
+
+	if ( *p == SINGLE_QUOTE )
+	{
+		++p;
+		end = "\'";		// single quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else if ( *p == DOUBLE_QUOTE )
+	{
+		++p;
+		end = "\"";		// double quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else
+	{
+		// All attribute values should be in single or double quotes.
+		// But this is such a common error that the parser will try
+		// its best, even without them.
+		value = "";
+		while (    p && *p											// existence
+				&& !IsWhiteSpace( *p )								// whitespace
+				&& *p != '/' && *p != '>' )							// tag end
+		{
+			if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
+				// [ 1451649 ] Attribute values with trailing quotes not handled correctly
+				// We did not have an opening quote but seem to have a 
+				// closing one. Give up and throw an error.
+				if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+				return 0;
+			}
+			value += *p;
+			++p;
+		}
+	}
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->peek();	
+		if ( !cdata && (c == '<' ) ) 
+		{
+			return;
+		}
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+		in->get();	// "commits" the peek made above
+
+		if ( cdata && c == '>' && tag->size() >= 3 ) {
+			size_t len = tag->size();
+			if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
+				// terminator of cdata.
+				return;
+			}
+		}    
+	}
+}
+#endif
+
+const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	value = "";
+	TiXmlDocument* document = GetDocument();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	const char* const startTag = "<![CDATA[";
+	const char* const endTag   = "]]>";
+
+	if ( cdata || StringEqual( p, startTag, false, encoding ) )
+	{
+		cdata = true;
+
+		if ( !StringEqual( p, startTag, false, encoding ) )
+		{
+			document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
+			return 0;
+		}
+		p += strlen( startTag );
+
+		// Keep all the white space, ignore the encoding, etc.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, false, encoding )
+			  )
+		{
+			value += *p;
+			++p;
+		}
+
+		TIXML_STRING dummy; 
+		p = ReadText( p, &dummy, false, endTag, false, encoding );
+		return p;
+	}
+	else
+	{
+		bool ignoreWhite = true;
+
+		const char* end = "<";
+		p = ReadText( p, &value, ignoreWhite, end, false, encoding );
+		if ( p )
+			return p-1;	// don't truncate the '<'
+		return 0;
+	}
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
+{
+	p = SkipWhiteSpace( p, _encoding );
+	// Find the beginning, find the end, and look for
+	// the stuff in-between.
+	TiXmlDocument* document = GetDocument();
+	if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
+		return 0;
+	}
+	if ( data )
+	{
+		data->Stamp( p, _encoding );
+		location = data->Cursor();
+	}
+	p += 5;
+
+	version = "";
+	encoding = "";
+	standalone = "";
+
+	while ( p && *p )
+	{
+		if ( *p == '>' )
+		{
+			++p;
+			return p;
+		}
+
+		p = SkipWhiteSpace( p, _encoding );
+		if ( StringEqual( p, "version", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			version = attrib.Value();
+		}
+		else if ( StringEqual( p, "encoding", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			encoding = attrib.Value();
+		}
+		else if ( StringEqual( p, "standalone", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			standalone = attrib.Value();
+		}
+		else
+		{
+			// Read over whatever it is.
+			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
+				++p;
+		}
+	}
+	return 0;
+}
+
+bool TiXmlText::Blank() const
+{
+	for ( unsigned i=0; i<value.length(); i++ )
+		if ( !IsWhiteSpace( value[i] ) )
+			return false;
+	return true;
+}
+

+ 281 - 0
天津大学/tjuvv7-src/src/common/ivbacktrace/ivbacktrace.cpp

@@ -0,0 +1,281 @@
+#include "ivbacktrace.h"
+
+#ifndef  USE_BOOSTBACKTRACE
+#ifdef Q_OS_WIN32
+void RegisterIVBackTrace()
+{
+
+}
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <execinfo.h>
+
+#include <QDateTime>
+#include <QDir>
+
+void out_stack(char *sig);
+void signal_exit(int dunno)
+{
+    char* signal_str =  (char*)" ";
+    char dunno_str[10] = {0};
+    sprintf(dunno_str, "%d", dunno);
+    switch (dunno)
+    {
+        case 1:
+            signal_str =  (char*)"SIGHUP(1)";
+            break;
+        case 2:
+            signal_str =  (char*)"SIGINT(2:CTRL_C)"; //CTRL_C
+            break;
+        case 3:
+            signal_str =  (char*)"SIGQUIT(3)";
+            break;
+        case 6:
+        {
+            signal_str =  (char*)"SIGABRT(6)";
+            out_stack(signal_str);
+        }
+        break;
+        case 9:
+            signal_str =  (char*)"SIGKILL(9)";
+            break;
+        case 15:
+            signal_str =  (char*)"SIGTERM(15 KILL)"; //kill
+            break;
+        case 11:
+        {
+            signal_str =  (char*)"SIGSEGV(11)"; //SIGSEGV
+            out_stack(signal_str);
+        }
+        break;
+        default:
+            signal_str =  (char*)"OTHER";
+            break;
+    }
+    exit(0);
+
+}
+
+
+size_t get_executable_path( char* processdir,char* processname, size_t len)
+{
+        char* path_end;
+        int nsize;
+        if((nsize =readlink("/proc/self/exe", processdir,len)) <=0)
+                return -1;
+
+        processdir[nsize] = '\0';
+        path_end = strrchr(processdir,  '/');
+        if(path_end == NULL)
+                return -1;
+        ++path_end;
+
+
+        strcpy(processname, path_end);
+        *path_end = '\0';
+
+        return (size_t)(path_end - processdir);
+}
+
+void savetofile(char * stroutput)
+{
+    qDebug("save file");
+    char strpath[1024];
+    QDateTime dt = QDateTime::currentDateTime();
+    char path[1000];
+    char processname[1024];
+    get_executable_path(path, processname, 1000);
+    snprintf(strpath,255,"%s/log/%s-%d-%s.log",getenv("HOME"),processname, getpid(),dt.toString("yyyyMMddhhmmsszzz").toLatin1().data());
+
+
+    char strdir[1024];
+    snprintf(strdir,255,"%s/log",getenv("HOME"));
+    QDir xdir;
+    xdir.setPath(strdir);
+    if(!xdir.exists())
+    {
+        qDebug("create dir %s",strdir);
+        xdir.mkdir(strdir);
+    }
+
+    qDebug("%s\n",strpath);
+    FILE* file = fopen(strpath,"w+");
+
+    if(file != nullptr)
+    {
+        fwrite(stroutput,strnlen(stroutput,1024),1,file);
+    }
+
+    fclose(file);
+}
+
+static void output_addrline(char addr[],char * strtem)
+{
+    char cmd[256];
+    char line[256];
+    char addrline[32]={0,};
+    char *str1, *str2;
+    FILE* file;
+
+    snprintf(strtem,1000," ");
+
+//    str1 = strchr(addr,'[');
+//    str2 = strchr(addr, ']');
+
+    str1 = strchr(addr,'(');
+    str2 = strchr(addr, ')');
+    if(str1 == NULL || str2 == NULL)
+    {
+        return;
+    }
+
+    if((str2 -str1 -2)<=0)
+    {
+//        printf("can't find address,please use -g compile.");
+//        strncpy(strtem,"can't find address,please use -g compile.",256);
+        str1 = strchr(addr,'[');
+        str2 = strchr(addr, ']');
+        if(str1 == NULL || str2 == NULL)
+        {
+            return;
+        }
+        if((str2 -str1 -2)<=0)
+        {
+            printf("can't find address,please use -g compile.");
+            strncpy(strtem,"can't find address,please use -g compile.",256);
+            return;
+        }
+    }
+
+    memcpy(addrline, str1 + 1, str2 -str1 -1);
+    snprintf(cmd, sizeof(cmd), "addr2line -e /proc/%d/exe %s ", getpid(), addrline);
+    qDebug("%s\n",cmd);
+
+
+    file = popen(cmd, "r");
+    if(NULL != fgets(line, 256, file))
+    {
+        printf("%s\n", line);
+        snprintf(strtem,1000,"%s\n",line);
+    }
+    if(strnlen(line,255) == 0)
+    {
+        printf("no addr.\n");
+    }
+    pclose(file);
+}
+
+void out_stack(char *sig)
+{
+    void *array[32];
+    size_t size;
+    char **strings;
+    size_t i;
+
+    char stroutput[6000];
+    char strtem[1000];
+
+    snprintf(stroutput,3000," ");
+    printf("%s\n", sig);
+    qDebug("%s\n", sig);
+    size = backtrace (array, 32);
+    //该函数用于获取当前线程的调用堆栈,获取的信息将会被存放在array中,
+    //它是一个指针列表。参数 32 用来指定array中可以保存多少个void* 元素。
+    //函数返回值是实际获取的指针个数,最大不超过32大小.
+    strings = backtrace_symbols (array, size);
+
+    /* backtrace_symbols将从backtrace函数获取的信息转化为一个字符串数组.
+     * 参数array应该是从backtrace函数获取的指针数组,
+     * size是该数组中的元素个数(backtrace的返回值)
+     * 函数返回值是一个指向字符串数组的指针,它的大小同array相同.
+     * 每个字符串包含了一个相对于array中对应元素的可打印信息.
+     * 它包括函数名,函数的偏移地址,和实际的返回地址
+     */
+
+
+
+    if (NULL == strings)
+    {
+        printf("backtrace_symbols\n");
+        return ;
+    }
+
+
+    qDebug("size is %d",(int)size);
+
+    for (i = 0; i <size; i++)
+    {
+//        qDebug("i is %d",i);
+        printf("%s\n",strings[i]);
+        snprintf(strtem,1000,"%s\n",strings[i]);
+        strncat(stroutput,strtem,6000);
+        output_addrline(strings[i],strtem);
+        strncat(stroutput,strtem,6000);
+    }
+
+
+    free(strings);
+
+    savetofile(stroutput);
+
+    QTime x;
+    x.start();
+    while((unsigned int)(x.elapsed())<size)
+    {
+ //       qDebug("hello");
+    }
+
+
+
+}
+
+
+
+
+void RegisterIVBackTrace()
+{
+    signal(SIGHUP, signal_exit);
+    signal(SIGINT, signal_exit);
+    signal(SIGQUIT, signal_exit);
+    signal(SIGABRT, signal_exit);
+    signal(SIGKILL, signal_exit);
+    signal(SIGTERM, signal_exit);
+    signal(SIGSEGV, signal_exit);
+}
+
+#endif
+
+#endif
+
+#if 0
+C语言标准定义了6个信号。都定义在signal.h头文件中。
+SIGABRT - 异常中止。
+SIGFPE - 浮点异常。
+SIGILL - 无效指令。
+SIGINT - 交互的用户按键请求,默认情况下,这会导致进程终止。
+SIGSEGV - 无效内存访问。
+SIGTERM - 程序的中止请求。
+
+/* ISO C99 signals.  */
+#define	SIGINT		2	/* Interactive attention signal.  */
+#define	SIGILL		4	/* Illegal instruction.  */
+#define	SIGABRT		6	/* Abnormal termination.  */
+#define	SIGFPE		8	/* Erroneous arithmetic operation.  */
+#define	SIGSEGV		11	/* Invalid access to storage.  */
+#define	SIGTERM		15	/* Termination request.  */
+
+/* Historical signals specified by POSIX. */
+#define	SIGHUP		1	/* Hangup.  */
+#define	SIGQUIT		3	/* Quit.  */
+#define	SIGTRAP		5	/* Trace/breakpoint trap.  */
+#define	SIGKILL		9	/* Killed.  */
+#define SIGBUS		10	/* Bus error.  */
+#define	SIGSYS		12	/* Bad system call.  */
+#define	SIGPIPE		13	/* Broken pipe.  */
+#define	SIGALRM		14	/* Alarm clock.  */
+#endif

+ 114 - 0
天津大学/tjuvv7-src/src/common/ivbacktrace/ivbacktrace.h

@@ -0,0 +1,114 @@
+#ifndef IVBACKTRACE_H
+#define IVBACKTRACE_H
+
+#include <QtCore/qglobal.h>
+
+
+//#define USE_BOOSTBACKTRACE  //if USE_BOOSTBACKTRACE LIBS += -ldl LIBS += -lboost_system -lboost_filesystem -lbacktrace
+
+#if defined(IVBACKTRACE_LIBRARY)
+#  define IVBACKTRACE_EXPORT Q_DECL_EXPORT
+#else
+#  define IVBACKTRACE_EXPORT Q_DECL_IMPORT
+#endif
+
+#ifndef USE_BOOSTBACKTRACE
+
+
+void RegisterIVBackTrace();
+
+
+#else
+
+
+#ifndef  BOOST_STACKTRACE_USE_BACKTRACE
+#define BOOST_STACKTRACE_USE_BACKTRACE
+#endif
+
+#include <string>
+#include <boost/noncopyable.hpp>
+#include <boost/function.hpp>
+#include <boost/stacktrace.hpp>
+
+#include <signal.h>     // ::signal, ::raise
+// #include <strstream>
+#include <stdexcept>    // std::logic_error
+#include <iostream>     // std::cerr
+#include <boost/filesystem.hpp>
+
+#include <strstream>
+
+#include <iostream>
+
+#include <QFile>
+#include <QDateTime>
+#include <QDir>
+
+size_t get_executable_path( char* processdir,char* processname, size_t len)
+{
+        char* path_end;
+        int nsize;
+        if((nsize =readlink("/proc/self/exe", processdir,len)) <=0)
+                return -1;
+
+        processdir[nsize] = '\0';
+        path_end = strrchr(processdir,  '/');
+        if(path_end == NULL)
+                return -1;
+        ++path_end;
+
+
+        strcpy(processname, path_end);
+        *path_end = '\0';
+
+        return (size_t)(path_end - processdir);
+}
+
+void x_signal_handler(int signum) {
+    ::signal(signum, SIG_DFL);
+
+    std::ostrstream ostr;
+    ostr<<boost::stacktrace::stacktrace()<<std::endl;
+    std::cout << boost::stacktrace::stacktrace()<<std::endl;
+
+
+    char strpath[1024];
+    QDateTime dt = QDateTime::currentDateTime();
+    char path[1000];
+    char processname[1024];
+    get_executable_path(path, processname, 1000);
+    snprintf(strpath,255,"%s/log/%s-%d-%s.log",getenv("HOME"),processname, getpid(),dt.toString("yyyyMMddhhmmsszzz").toLatin1().data());
+
+    char strdir[1024];
+    snprintf(strdir,255,"%s/log",getenv("HOME"));
+    QDir xdir;
+    xdir.setPath(strdir);
+    if(!xdir.exists())
+    {
+        qDebug("create dir %s",strdir);
+        xdir.mkdir(strdir);
+    }
+    QFile xFile;
+    xFile.setFileName(strpath);
+    if(xFile.open(QIODevice::ReadWrite))
+    {
+        xFile.write(ostr.str());
+    }
+    else
+    {
+        std::cout<<ostr.str()<<std::endl;
+    }
+    xFile.close();
+    ::raise(SIGABRT);
+}
+
+void RegisterIVBackTrace()
+{
+    std::cout << boost::stacktrace::stacktrace()<<std::endl;
+    ::signal(SIGSEGV, &x_signal_handler);
+//    ::signal(SIGABRT, &x_signal_handler);
+}
+
+#endif
+
+#endif // IVBACKTRACE_H

+ 38 - 0
天津大学/tjuvv7-src/src/common/ivbacktrace/ivbacktrace.pro

@@ -0,0 +1,38 @@
+QT -= gui
+
+TEMPLATE = lib
+DEFINES += IVBACKTRACE_LIBRARY
+
+CONFIG += c++11
+
+CONFIG += plugin
+
+QMAKE_CXXFLAGS +=  -g
+
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+
+#LIBS += -ldl
+#LIBS += -lboost_system -lboost_filesystem -lbacktrace
+
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+    ivbacktrace.cpp
+
+HEADERS += \
+    ivbacktrace.h
+
+# Default rules for deployment.
+unix {
+    target.path = /usr/lib
+}
+!isEmpty(target.path): INSTALLS += target

+ 122 - 0
天津大学/tjuvv7-src/src/common/ivexit/ivexit.cpp

@@ -0,0 +1,122 @@
+#include "modulecomm.h"
+
+#include <iostream>
+
+#include <unistd.h>
+
+#include "ivexit.h"
+
+namespace iv {
+namespace ivexit {
+
+
+
+class ivexit_impl
+{
+  private:
+    void * mhandle;
+    IVExitFun mFun;
+    IVExitCallBack mpCall;
+    bool mbPlus = false;
+    const char * mstrsysname = "ivexit";
+    bool mbcommonexit = true;
+public:
+    ivexit_impl(){}
+
+    void RegisterCmd()
+    {
+        mhandle = iv::modulecomm::RegisterSend(mstrsysname,100000,100);
+    }
+    void ExecIVExitCmd(const char * strsyscmd)
+    {
+        qDebug("cmd is %s len is %d",strsyscmd,strlen(strsyscmd));
+        iv::modulecomm::ModuleSendMsg(mhandle,strsyscmd,strnlen(strsyscmd,256));
+    }
+
+    void * RegIVExitCall(IVExitCallBack pCall,bool bcommonexit)
+    {
+        mpCall = pCall;
+
+        ModuleFun funexit = std::bind(&ivexit_impl::ExitFunc,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4,std::placeholders::_5);
+        iv::modulecomm::RegisterRecvPlus(mstrsysname,funexit);
+
+        mbcommonexit = bcommonexit;
+    }
+
+    void * RegIVExitCallPlus(IVExitFun xFun,bool bcommonexit)
+    {
+        mFun = xFun;
+        mbPlus = true;
+        ModuleFun funexit = std::bind(&ivexit_impl::ExitFunc,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4,std::placeholders::_5);
+        iv::modulecomm::RegisterRecvPlus(mstrsysname,funexit);
+        mbcommonexit = bcommonexit;
+    }
+
+    void ExitFunc(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+    {
+        int pid = getpid();
+//        std::cout<<"exit func."<<std::endl;
+
+        char strexitcode[255];
+        snprintf(strexitcode,255,"adcivexit-%d",pid);
+
+        if(strncmp(strexitcode,strdata,nSize) != 0)
+        {
+            if(strncmp(strdata,"adcivexit-test",nSize) != 0)
+                return;
+        }
+
+
+//        std::cout<<" exit."<<std::endl;
+        if(mbPlus == false)
+        {
+            if(mpCall !=  0)
+                (*mpCall)();
+        }
+        else
+        {
+            if(mFun != 0)
+                mFun();
+        }
+        exit(0);
+//        if(mbcommonexit)
+//        {
+//            exit(0);
+//        }
+    }
+};
+
+
+
+void *  RegIVExitCmd()
+{
+    ivexit_impl * pie = new ivexit_impl();
+    void * phandle = (void *)pie;
+    pie->RegisterCmd();
+    return phandle;
+}
+void    ExecIVExitCmd(void * handle,const char * strsyscmd)
+{
+    ivexit_impl * pie = (ivexit_impl * )handle;
+    pie->ExecIVExitCmd(strsyscmd);
+}
+
+
+void * RegIVExitCall(IVExitCallBack pCall,bool bcommonexit)
+{
+    ivexit_impl * pie = new ivexit_impl();
+    void * phandle = (void *)pie;
+    pie->RegIVExitCall(pCall,bcommonexit);
+    return phandle;
+}
+void *  RegIVExitCallPlus(IVExitFun xFun,bool bcommonexit)
+{
+
+    ivexit_impl * pie = new ivexit_impl();
+    void * phandle = (void *)pie;
+    pie->RegIVExitCallPlus(xFun,bcommonexit);
+    return phandle;
+}
+
+}
+}

+ 37 - 0
天津大学/tjuvv7-src/src/common/ivexit/ivexit.h

@@ -0,0 +1,37 @@
+#ifndef IVEXIT_H
+#define IVEXIT_H
+
+#include <QtCore/qglobal.h>
+#include <QDateTime>
+
+#include <functional>
+
+#if defined(IVEXIT_LIBRARY)
+#  define IVEXITSHARED_EXPORT Q_DECL_EXPORT
+#else
+#  define IVEXITSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+
+
+//#include <iostream>
+//#include <thread>
+
+//using namespace std::placeholders;
+typedef std::function<void()> IVExitFun;
+typedef void (* IVExitCallBack)();
+
+namespace iv {
+namespace ivexit {
+void * IVEXITSHARED_EXPORT RegIVExitCmd();
+void   IVEXITSHARED_EXPORT ExecIVExitCmd(void * handle,const char * strsyscmd);
+void * IVEXITSHARED_EXPORT RegIVExitCall(IVExitCallBack pCall,bool bcommonexit = true);
+void * IVEXITSHARED_EXPORT RegIVExitCallPlus(IVExitFun xFun,bool bcommonexit = true);
+
+}
+
+}
+
+
+
+#endif 

+ 40 - 0
天津大学/tjuvv7-src/src/common/ivexit/ivexit.pro

@@ -0,0 +1,40 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2018-07-10T05:46:48
+#
+#-------------------------------------------------
+
+QT       -= gui
+
+#QT       += dbus
+
+
+#DEFINES += USELCM
+
+#DEFINES += USEDBUS
+
+TARGET = ivexit
+TEMPLATE = lib
+
+DEFINES += IVEXIT_LIBRARY
+
+#VERSION = 1.0.1
+CONFIG += plugin
+
+
+SOURCES += ivexit.cpp
+
+HEADERS += ivexit.h
+
+
+unix {
+    target.path = /usr/lib
+    INSTALLS += target
+}
+
+#INCLUDEPATH += $$PWD/../../../include/
+LIBS += -L$$PWD
+
+INCLUDEPATH += $$PWD/../../../include/
+LIBS += -L$$PWD/../../../bin/ -lmodulecomm
+

+ 16 - 0
天津大学/tjuvv7-src/src/common/ivfault/ivfault.cpp

@@ -0,0 +1,16 @@
+#include "ivfault.h"
+
+
+#include "ivfault_impl.h"
+
+iv::Ivfault::Ivfault(const char * strmodulename)
+{
+    ivfault_impl * p = new ivfault_impl(strmodulename);
+    mpimpl = (void *)p;
+}
+
+int iv::Ivfault::SetFaultState(int nFaultClass, int nFaultNum,const char * strfaultdesc)
+{
+    ivfault_impl * p = (ivfault_impl *)mpimpl;
+    return p->SetFaultState(nFaultClass,nFaultNum,strfaultdesc);
+}

+ 26 - 0
天津大学/tjuvv7-src/src/common/ivfault/ivfault.h

@@ -0,0 +1,26 @@
+#ifndef IVFAULT_H
+#define IVFAULT_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(IVFAULT_LIBRARY)
+#  define IVFAULTSHARED_EXPORT Q_DECL_EXPORT
+#else
+#  define IVFAULTSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+namespace  iv {
+
+class IVFAULTSHARED_EXPORT Ivfault
+{
+
+public:
+    Ivfault(const char * strmodulename);
+    int SetFaultState(int nFaultClass,int nFaultNum,const char * strfaultdesc);   // nFaultClasss: 0 No Fault 1 Warning 2 Fault
+
+private:
+    void * mpimpl;
+};
+}
+
+#endif // IVFAULT_H

+ 53 - 0
天津大学/tjuvv7-src/src/common/ivfault/ivfault.pro

@@ -0,0 +1,53 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2020-03-09T15:42:22
+#
+#-------------------------------------------------
+
+QT       -= gui
+
+QT       += dbus
+
+TARGET = ivfault
+TEMPLATE = lib
+
+DEFINES += IVFAULT_LIBRARY
+
+
+CONFIG += plugin
+
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        ivfault.cpp \
+    ivfault_impl.cpp \
+    ../../include/msgtype/fault.pb.cc
+
+HEADERS += \
+        ivfault.h \
+    ivfault_impl.h \
+    ../../include/msgtype/fault.pb.h
+
+unix {
+    target.path = /usr/lib
+    INSTALLS += target
+
+
+}
+
+unix: LIBS += -lprotobuf
+win32: LIBS += $$PWD\..\..\..\thirdpartylib\protobuf\lib\libprotobuf.a
+
+win32: INCLUDEPATH+= $$PWD\..\..\..\thirdpartylib\protobuf\src
+
+INCLUDEPATH += $$PWD/../../include/msgtype

+ 56 - 0
天津大学/tjuvv7-src/src/common/ivfault/ivfault_impl.cpp

@@ -0,0 +1,56 @@
+#include "ivfault_impl.h"
+
+ivfault_impl::ivfault_impl(const char * strmodulename)
+{
+    strncpy(mstrmodulename,strmodulename,255);
+    mFaultState.set_faultnum(0);
+    mFaultState.set_modulename(mstrmodulename,strnlen(mstrmodulename,255));
+    mFaultState.set_faultclass(0);
+    mFaultState.set_stateupdatetime(QDateTime::currentMSecsSinceEpoch());
+    mFaultState.set_faultdesc("No Desc.",8);
+    mpid = getpid();
+    mmsg = QDBusMessage::createSignal("/catarc/adc",  "adciv.interface", "ivfault");
+    mmsg<<1;
+    bool bconnect = QDBusConnection::sessionBus().connect(QString(),"/catarc/adc",  "adciv.interface", "ivfaultdiag",this,SLOT(onFaultDiagnosis()));
+
+//    qDebug("connect is %d",bconnect);
+}
+
+int ivfault_impl::SetFaultState(int nFaultClass,int nFaultNum,const char * strfaultdesc)
+{
+    mMutex.lock();
+    mFaultState.set_faultclass(nFaultClass);
+    mFaultState.set_faultnum(nFaultNum);
+    mFaultState.set_stateupdatetime(QDateTime::currentMSecsSinceEpoch());
+    if(strfaultdesc != 0)  mFaultState.set_faultdesc(strfaultdesc,strnlen(strfaultdesc,255));
+    mMutex.unlock();
+    return 0;
+}
+
+void ivfault_impl::onFaultDiagnosis()
+{
+    iv::fault::faultstate xFaultState;
+    mMutex.lock();
+    xFaultState.CopyFrom(mFaultState);
+    mMutex.unlock();
+
+    char * str;
+    int ndatasize = xFaultState.ByteSize();
+
+    str = new char[ndatasize];
+    std::shared_ptr<char> pstr;pstr.reset(str);
+
+    if(!xFaultState.SerializeToArray(str,ndatasize))
+    {
+        std::cout<<"ivfault_impl::onFaultDiagnosis "<<"Serialize error."<<std::endl;
+        return;
+    }
+
+    QByteArray ba;
+    ba.append(str,ndatasize);
+
+    QList<QVariant> x;
+    x<<ba;
+    mmsg.setArguments(x);
+    QDBusConnection::sessionBus().send(mmsg);
+}

+ 41 - 0
天津大学/tjuvv7-src/src/common/ivfault/ivfault_impl.h

@@ -0,0 +1,41 @@
+#ifndef IVFAULT_IMPL_H
+#define IVFAULT_IMPL_H
+
+
+#include <QObject>
+
+
+#include <QDateTime>
+#include <QtDBus/qdbusmessage.h>
+#include <QtDBus/QDBusConnection>
+
+#include <memory>
+#include <QMutex>
+#include <iostream>
+
+#include <unistd.h>
+
+#include "fault.pb.h"
+
+class ivfault_impl : public QObject
+{
+    Q_OBJECT
+public:
+    ivfault_impl(const char * strmodulename);
+private:
+    char mstrmodulename[256];
+    int mpid;
+    inline void setfault(int);
+    QDBusMessage mmsg;
+
+    iv::fault::faultstate mFaultState;
+    QMutex mMutex;
+
+private slots:
+    void onFaultDiagnosis();
+
+public:
+    int SetFaultState(int nFaultClass,int nFaultNum,const char * strfaultdesc);   // nFaultClasss: 0 No Fault 1 Warning 2 Fault
+};
+
+#endif // IVFAULT_IMPL_H

+ 153 - 0
天津大学/tjuvv7-src/src/common/ivlog/ivlog.cpp

@@ -0,0 +1,153 @@
+#include "ivlog.h"
+
+#include "ivlog_impl.h"
+
+#include <memory>
+
+namespace  iv {
+
+
+Ivlog::Ivlog(const char * strmodulename)
+{
+   ivlog_impl * p = new ivlog_impl(strmodulename);
+   p->start();
+   mpimpl = (void *)p;
+}
+
+Ivlog::~Ivlog()
+{
+    ivlog_impl * p = (ivlog_impl *)mpimpl;
+    delete p;
+}
+
+
+/*
+对于多参数的函数,stdarg 提供了上面三个宏va_start(),va_arg(),va_end(),来解决,va_list,用来存储实参,
+
+va_start用来初始化list,第一个命名参数放在list的最后,
+
+va_end(ap) 用来清除list
+*/
+void Ivlog::verbose(const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+
+    ivlog_impl * p = (ivlog_impl *)mpimpl;
+    p->verbose(strlog);
+}
+
+void Ivlog::verbose(const char * strtag,const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+
+    ivlog_impl * p = (ivlog_impl *)mpimpl;
+    p->verbose(strlog,strtag);
+}
+
+void Ivlog::debug(const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+    ivlog_impl * p = (ivlog_impl *)mpimpl;
+    p->debug(strlog);
+}
+
+void Ivlog::debug(const char * strtag,const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+    ivlog_impl * p = (ivlog_impl *)mpimpl;
+    p->debug(strlog,strtag);
+}
+
+void Ivlog::info(const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+    ivlog_impl * p = (ivlog_impl *)mpimpl;
+    p->info(strlog);
+}
+
+void Ivlog::info(const char * strtag,const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+    ivlog_impl * p = (ivlog_impl *)mpimpl;
+    p->info(strlog,strtag);
+}
+
+void Ivlog::warn(const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+   ivlog_impl * p = (ivlog_impl *)mpimpl;
+   p->warn(strlog);
+}
+
+void Ivlog::warn(const char * strtag,const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+   ivlog_impl * p = (ivlog_impl *)mpimpl;
+   p->warn(strlog,strtag);
+}
+
+void Ivlog::error(const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+    ivlog_impl * p = (ivlog_impl *)mpimpl;
+    p->error(strlog);
+}
+
+void Ivlog::error(const char * strtag, const char *str,...)
+{
+    va_list arg;
+    char * strlog = new char[65636];
+    std::shared_ptr<char> pstrlog; pstrlog.reset(strlog);
+    va_start(arg, str);
+    vsnprintf(strlog,65535,str,arg);
+    va_end(arg);
+    ivlog_impl * p = (ivlog_impl *)mpimpl;
+    p->error(strlog,strtag);
+}
+
+}

+ 41 - 0
天津大学/tjuvv7-src/src/common/ivlog/ivlog.h

@@ -0,0 +1,41 @@
+#ifndef IVLOG_H
+#define IVLOG_H
+
+
+#include <QtCore/qglobal.h>
+
+#include <stdarg.h>
+
+
+#if defined(IVLOG_LIBRARY)
+#  define IVLOGSHARED_EXPORT Q_DECL_EXPORT
+#else
+#  define IVLOGSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+namespace iv {
+class IVLOGSHARED_EXPORT Ivlog
+{
+
+public:
+    Ivlog(const char * strmodulename);
+    ~Ivlog();
+    void verbose(const char * str,...);
+    void debug(const char * str,...);
+    void info(const char * str,...);
+    void warn(const char * str,...);
+    void error(const char * str,...);
+
+    void verbose(const char * strtag,const char * str,...);
+    void debug(const char * strtag,const char * str,...);
+    void info(const char * strtag,const char * str,...);
+    void warn(const char * strtag,const char * str,...);
+    void error(const char * strtag,const char * str,...);
+
+private:
+    void * mpimpl;
+};
+}
+
+
+#endif // IVLOG_H

+ 55 - 0
天津大学/tjuvv7-src/src/common/ivlog/ivlog.pro

@@ -0,0 +1,55 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2020-03-05T21:39:06
+#
+#-------------------------------------------------
+
+QT       -= gui
+
+QT += dbus
+
+TARGET = ivlog
+TEMPLATE = lib
+
+DEFINES += IVLOG_LIBRARY
+
+CONFIG += plugin
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        ivlog.cpp \
+    ivlog_impl.cpp \
+    ../../include/msgtype/log.pb.cc
+
+HEADERS += \
+        ivlog.h \
+    ivlog_impl.h \
+    ../../include/msgtype/log.pb.h
+
+unix {
+    target.path = /usr/lib
+    INSTALLS += target
+}
+
+
+INCLUDEPATH += $$PWD/../../include/msgtype
+
+unix: LIBS += -lprotobuf
+
+win32: LIBS += $$PWD\..\..\..\thirdpartylib\protobuf\lib\libprotobuf.a
+win32: INCLUDEPATH+= $$PWD\..\..\..\thirdpartylib\protobuf\src
+
+## install
+##target.path = $$[QT_INSTALL_EXAMPLES]/dbus/remotecontrolledcar/controller
+#target.path = /home/apollo/test
+#INSTALLS += target

+ 139 - 0
天津大学/tjuvv7-src/src/common/ivlog/ivlog_impl.cpp

@@ -0,0 +1,139 @@
+#include "ivlog_impl.h"
+
+ivlog_impl::ivlog_impl(const char * strmodulename)
+{
+    strncpy(mstrmodulename,strmodulename,255);
+    mpid = getpid();
+    mmsg = QDBusMessage::createSignal("/catarc/adc",  "adciv.interface", "ivlog");
+    mmsg<<1;
+
+}
+
+ivlog_impl::~ivlog_impl()
+{
+    requestInterruption();
+    int i;
+    for(i=0;i<100;i++)
+    {
+        if(isFinished())
+            break;
+        msleep(1);
+    }
+
+}
+
+void ivlog_impl::verbose(const char *str,const char * strtag)
+{
+    setlog(iv::log::logdata_LOGCLASS_VERBOSE,str,strtag);
+}
+
+void ivlog_impl::debug(const char *str,const char * strtag)
+{
+    setlog(iv::log::logdata_LOGCLASS_DEBUG,str,strtag);
+}
+
+void ivlog_impl::info(const char *str,const char * strtag)
+{
+    setlog(iv::log::logdata_LOGCLASS_INFO,str,strtag);
+}
+
+void ivlog_impl::warn(const char *str,const char * strtag)
+{
+    setlog(iv::log::logdata_LOGCLASS_WARN,str,strtag);
+}
+
+void ivlog_impl::error(const char *str,const char * strtag)
+{
+    setlog(iv::log::logdata_LOGCLASS_ERROR,str,strtag);
+}
+
+inline void ivlog_impl::setlog(iv::log::logdata_LOGCLASS logclass, const char *logsen,const char * strtag)
+{
+    iv::log::logdata log;
+    log.set_logclass(logclass);
+    log.set_logtime(QDateTime::currentMSecsSinceEpoch());
+    log.set_logsentence(logsen,strnlen(logsen,LOGSENMAX));
+    log.set_modulename(mstrmodulename,strnlen(mstrmodulename,255));
+    log.set_pid(mpid);
+    if(strtag != 0)log.set_logtag(strtag,strnlen(strtag,256));
+    mMutexVector.lock();
+    mvectorlog.push_back(log);
+    mMutexVector.unlock();
+    int logxc = (int)logclass;
+    int logrealmin = (int)iv::log::logdata_LOGCLASS_WARN;
+    if(logxc >= logrealmin)
+    {
+        mwc.wakeAll();
+    }
+}
+
+int ivlog_impl::writelog(std::vector<iv::log::logdata> xvectorlog)
+{
+    int headsize = 4 + (xvectorlog.size() + 2)*sizeof(int);
+    int ndatasize = headsize;
+    int i;
+    for(i=0;i<xvectorlog.size();i++)
+    {
+        ndatasize = ndatasize + xvectorlog[i].ByteSize();
+    }
+    char * str = new char[ndatasize];
+    std::shared_ptr<char> pstr;
+    pstr.reset(str);
+    memcpy(str,"ilog",4);
+    int npos = 4;
+    memcpy(str+npos,&ndatasize,sizeof(int));npos = npos + sizeof(int);
+    int nvectorsize = (int)xvectorlog.size();
+    memcpy(str+npos,&nvectorsize,sizeof(int)); npos = npos + sizeof(int);
+    for(i=0;i<xvectorlog.size();i++)
+    {
+        int nlogsize = xvectorlog[i].ByteSize();
+        memcpy(str+npos,&nlogsize,sizeof(int));npos = npos + sizeof(int);
+    }
+    for(i=0;i<xvectorlog.size();i++)
+    {
+        int nlogsize = xvectorlog[i].ByteSize();
+        char * strbuf = new char[nlogsize];
+        std::shared_ptr<char> pstrbuf;
+        pstrbuf.reset(strbuf);
+        if(xvectorlog[i].SerializeToArray(strbuf,nlogsize))
+        {
+            memcpy(str+npos,strbuf,nlogsize);npos = npos + nlogsize;
+        }
+        else
+        {
+            std::cout<<"vlog_impl::writelog  serialzie error."<<std::endl;
+            return - 1;
+        }
+    }
+
+//    std::cout<<"npos is "<<npos<<"  datasize is "<<ndatasize<<std::endl;
+
+    QByteArray ba;
+    ba.append(str,ndatasize);
+
+    QList<QVariant> x;
+    x<<ba;
+    mmsg.setArguments(x);
+    QDBusConnection::sessionBus().send(mmsg);
+    return 0;
+}
+
+void ivlog_impl::run()
+{
+    std::vector<iv::log::logdata> xvectorlog;
+    while(!QThread::isInterruptionRequested())
+    {
+        mWaitMutex.lock();
+        mwc.wait(&mWaitMutex,100);
+        mWaitMutex.unlock();
+        mMutexVector.lock();
+        xvectorlog.clear();
+        xvectorlog = mvectorlog;
+        mvectorlog.clear();
+        mMutexVector.unlock();
+        if(xvectorlog.size() > 0)
+        {
+            writelog(xvectorlog);
+        }
+    }
+}

+ 48 - 0
天津大学/tjuvv7-src/src/common/ivlog/ivlog_impl.h

@@ -0,0 +1,48 @@
+#ifndef IVLOG_IMPL_H
+#define IVLOG_IMPL_H
+
+#include <QDateTime>
+#include <QtDBus/qdbusmessage.h>
+#include <QtDBus/QDBusConnection>
+
+#include <QThread>
+#include <QWaitCondition>
+#include <QMutex>
+#include <vector>
+#include <memory>
+#include <iostream>
+
+#include <unistd.h>
+
+#include "log.pb.h"
+
+class ivlog_impl:public QThread
+{
+public:
+    ivlog_impl(const char * strmodulename);
+    ~ivlog_impl();
+    void verbose(const char * str,const char * strtag = 0);
+    void debug(const char * str,const char * strtag = 0);
+    void info(const char * str,const char * strtag = 0);
+    void warn(const char * str,const char * strtag = 0);
+    void error(const char * str,const char * strtag = 0);
+private:
+    char mstrmodulename[256];
+    int mpid;
+    inline void setlog(iv::log::logdata_LOGCLASS logclass,const char * logsen,const char * strtag);
+public:
+    const static int LOGSENMAX = 66000;
+    const static int LOGLISTMAX = 10000;
+
+
+private:
+    QDBusMessage mmsg;
+    void run();
+    QWaitCondition mwc;
+    QMutex mWaitMutex;
+    std::vector<iv::log::logdata> mvectorlog;
+    QMutex mMutexVector;
+    int writelog(std::vector<iv::log::logdata>xvectorlog);
+};
+
+#endif // IVLOG_IMPL_H

+ 9 - 0
天津大学/tjuvv7-src/src/common/ivsyschange/ivsyschange.cpp

@@ -0,0 +1,9 @@
+#include "ivsyschange.h"
+
+
+#include "modulecomm.h"
+
+void changeivsysxml(void * pmsg,std::string strxmlpath)
+{
+    iv::modulecomm::ModuleSendMsg(pmsg,strxmlpath.data(),strxmlpath.size());
+}

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini