瀏覽代碼

1、输入坐标定位工具完成(暂时未提供定位后指定地图视图功能)
2、增加案件编辑页面(代码+页面)完成,相关事件代理及注册完成,具体功能尚未开发

不会爬树的猴 1 年之前
父節點
當前提交
2158e6af7d

+ 3 - 2
app/src/main/java/com/cr/common/CrUnitManager.kt

@@ -93,7 +93,8 @@ class CrUnitManager {
          * @return Boolean 是否符合要求
          */
         fun checkLongitude(longitude:String):Boolean{
-            var regex = Regex("^[\\-\\+]?(0(\\.\\d{1,10})?|([1-9](\\d)?)(\\.\\d{1,10})?|1[0-7]\\d{1}(\\.\\d{1,10})?|180\\.0{1,10})\$")
+
+            var regex = Regex("""^[\-\+]?(0?\d{1,2}\.\d{1,5}|1[0-7]?\d{1}\.\d{1,5}|180\.0{1,5})$""")
             return regex.matches(longitude)
         }
 
@@ -103,7 +104,7 @@ class CrUnitManager {
          * @return Boolean 是否符合要求
          */
         fun checkLatitude(latitude:String):Boolean{
-            var regex = Regex("^[\\-\\+]?((0|([1-8]\\d?))(\\.\\d{1,10})?|90(\\.0{1,10})?)\$")
+            var regex = Regex("""^[\-\+]?([0-8]?\d{1}\.\d{1,5}|90\.0{1,5})${'$'}""")
             return regex.matches(latitude)
         }
     }

+ 56 - 0
app/src/main/java/com/cr/cruav/AvMain.kt

@@ -64,6 +64,9 @@ class AvMain : CrActivity(), View.OnClickListener {
     // define: 2023/4/21 工具页面
     private var fragmentTools:FragmentTools? = null
 
+    // define: 2023/6/9 案件图斑编辑页面
+    private var fragmentCaseTools:FragmentCaseTools?= null
+
 
     /**
      * 入口函数
@@ -90,6 +93,7 @@ class AvMain : CrActivity(), View.OnClickListener {
         tools_mark.setOnClickListener(this)
         tools_wx.setOnClickListener(this)
         tools_tools.setOnClickListener(this)
+        tools_case_tools.setOnClickListener(this)
     }
 
     /**
@@ -143,6 +147,13 @@ class AvMain : CrActivity(), View.OnClickListener {
             addFragment(it,R.id.av_frm_left_panel)
             hideFragment(it)
         }
+        // todo: 2023/6/9 初始化案件图斑编辑页面
+        fragmentCaseTools = FragmentCaseTools()
+        fragmentCaseTools?.let {
+            it.setListener(caseToolsListener)
+            addFragment(it,R.id.av_frm_left_panel)
+            hideFragment(it)
+        }
     }
 
     /**
@@ -253,6 +264,10 @@ class AvMain : CrActivity(), View.OnClickListener {
             R.id.tools_tools->{
                 showFragment(fragmentTools!!)
             }
+            R.id.tools_case_tools->{
+                showFragment(fragmentCaseTools!!)
+            }
+
         }
     }
 
@@ -378,6 +393,47 @@ class AvMain : CrActivity(), View.OnClickListener {
     }
 
     /**
+     * 案件图斑编辑工具页面监听
+     */
+    private val caseToolsListener = object:FragmentCaseTools.OnOperationListener{
+        // todo: 2023/6/9 开启绘制案件图斑
+        override fun onStartDraw() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventCaseDrawPolygon))
+        }
+
+        // todo: 2023/6/9 结束绘制
+        override fun onStopDraw() {
+
+        }
+
+        // todo: 2023/6/9 保存
+        override fun onSave() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventCaseSavePolygon))
+        }
+
+        // todo: 2023/6/9 删除
+        override fun onRemove() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventCaseRemovePolygon))
+        }
+
+        // todo: 2023/6/9 回退
+        override fun onUndo() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventCaseDrawUndo))
+        }
+
+        // todo: 2023/6/9 重置
+        override fun onReset() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventCaseDrawReset))
+        }
+
+        // todo: 2023/6/9 移动违建点
+        override fun onMoveCasePoint() {
+
+        }
+
+    }
+
+    /**
      * 销毁
      */
     override fun onDestroy() {

+ 22 - 2
app/src/main/java/com/cr/map/MapAction.kt

@@ -78,9 +78,29 @@ enum class MapAction {
     MapTapMovingWaypoint,
 
     /**
-     * 创建违建面动作
+     * 创建案件面动作
      */
-    MapTapCreateCasePolygon,
+    EventCaseDrawPolygon,
+
+    /**
+     * 保存案件面动作
+     */
+    EventCaseSavePolygon,
+
+    /**
+     * 删除案件面动作
+     */
+    EventCaseRemovePolygon,
+
+    /**
+     * 重置案件绘制动作
+     */
+    EventCaseDrawReset,
+
+    /**
+     * 回退绘制动作
+     */
+    EventCaseDrawUndo,
 
     /**
      * 查询网络案件动作

+ 214 - 0
app/src/main/java/com/cr/pages/FragmentCaseTools.kt

@@ -0,0 +1,214 @@
+package com.cr.pages
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.CompoundButton
+import android.widget.CompoundButton.OnCheckedChangeListener
+import android.widget.Switch
+import com.cr.cruav.CrApplication
+import com.cr.cruav.R
+import com.cr.event.BarAction
+import com.cr.event.EventFragmentBarAction
+import com.cr.widget.CrButton
+import com.squareup.otto.Subscribe
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/6/9 17:12
+ * 描述:案件图斑编辑页面
+ */
+class FragmentCaseTools : CrNavigationFragment(), CrButton.OnClickListener,
+    OnCheckedChangeListener {
+    /**
+     * 操作监听接口
+     */
+    interface OnOperationListener {
+        // todo: 2023/6/9 开启绘制
+        fun onStartDraw()
+
+        // todo: 2023/6/9 停止绘制
+        fun onStopDraw()
+
+        // todo: 2023/6/9 保存
+        fun onSave()
+
+        // todo: 2023/6/9 删除
+        fun onRemove()
+
+        // todo: 2023/6/9 回退一步
+        fun onUndo()
+
+        // todo: 2023/6/9 重绘
+        fun onReset()
+
+        // todo: 2023/6/9 移动案件点
+        fun onMoveCasePoint()
+    }
+
+    private var btnSave: CrButton? = null  // define: 2023/6/9 保存
+    private var btnDelete: CrButton? = null  // define: 2023/6/9 删除
+    private var btnUndo: CrButton? = null  // define: 2023/6/9 回退一步
+    private var btnReset: CrButton? = null  // define: 2023/6/9 重新绘制
+    private var btnMovePoint: CrButton? = null // define: 2023/6/9 移动案件点
+    private var switchDraw: Switch? = null // define: 2023/6/9 开启绘制
+
+    // todo: 2023/6/9 操作监听
+    private var listener: OnOperationListener? = null
+
+    /**
+     * 创建视图
+     * @param inflater LayoutInflater
+     * @param container ViewGroup?
+     * @param savedInstanceState Bundle?
+     * @return View?
+     */
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        // todo: 2023/4/17 订阅监听
+        CrApplication.getEventBus().register(this)
+        self = this
+        mainView = inflater.inflate(R.layout.frag_case_tools, null)
+        // todo: 2023/4/17 设置导航栏
+        setBar(R.id.nv)
+        // todo: 2023/4/17 设置展现方式
+        setAnimationDirection(AnimationDirection.LEFT)
+        // todo: 2023/4/17 关联控件
+        joinControls()
+        return mainView
+    }
+
+    /**
+     * 重写挂载控件
+     */
+    override fun joinControls() {
+        // todo: 2023/6/9 挂在控件
+        switchDraw = mainView?.findViewById(R.id.case_on_draw)
+        btnSave = mainView?.findViewById(R.id.case_save)
+        btnDelete = mainView?.findViewById(R.id.cases_delete)
+        btnUndo = mainView?.findViewById(R.id.case_undo)
+        btnReset = mainView?.findViewById(R.id.case_reset)
+        btnMovePoint = mainView?.findViewById(R.id.case_move_point)
+        // todo: 2023/6/9 设置监听
+        btnSave?.setListener(this)
+        btnDelete?.setListener(this)
+        btnUndo?.setListener(this)
+        btnReset?.setListener(this)
+        btnMovePoint?.setListener(this)
+        switchDraw?.setOnCheckedChangeListener(this)
+    }
+
+    /**
+     * 关闭页面
+     */
+    override fun dismiss() {
+        CrApplication.getEventBus().post(EventFragmentBarAction(self!!, BarAction.ACTION_DISMISS))
+    }
+
+    /**
+     * 视图点击事件
+     * @param view View
+     */
+    override fun onClick(view: View) {
+        when (view?.id) {
+            R.id.case_save -> {
+                if (listener != null) listener?.onSave()
+            }
+            R.id.cases_delete -> {
+                if (listener != null) listener?.onRemove()
+            }
+            R.id.case_undo -> {
+                if (listener != null) listener?.onUndo()
+            }
+            R.id.case_reset -> {
+                if (listener != null) listener?.onReset()
+            }
+            R.id.case_move_point->{
+                if(listener != null) listener?.onMoveCasePoint()
+            }
+        }
+    }
+
+    /**
+     * 开关事件
+     * @param view CompoundButton
+     * @param isChecked Boolean
+     */
+    override fun onCheckedChanged(view: CompoundButton?, isChecked: Boolean) {
+        when (view?.id) {
+            R.id.case_on_draw -> {
+                if (isChecked) {
+                    if (listener != null) {
+                        listener?.onStartDraw()
+                    }
+                } else {
+                    if (listener != null) listener?.onStopDraw()
+                }
+
+            }
+        }
+    }
+
+    /**
+     * 重写页面初始化
+     */
+    override fun initPage() {
+        switchDraw?.isChecked = false
+    }
+
+    /**
+     * 设置操作监听
+     * @param listener OnOperationListener 操作监听
+     */
+    fun setListener(listener: OnOperationListener) {
+        this.listener = listener
+    }
+
+    /**
+     * 订阅事件执行
+     * @param event EventAction
+     */
+    @Subscribe
+    fun onAction(event: EventCaseToolsAction) {
+        when (event.action) {
+            EventCaseToolsAction.CLOSE_DRAW -> {
+                switchDraw?.isChecked = false
+            }
+        }
+    }
+
+    // todo: 2023/4/17 生命周期
+    /**
+     * 销毁
+     */
+    override fun onDestroy() {
+        // todo: 2023/4/17 解除订阅监听
+        CrApplication.getEventBus().unregister(this)
+        super.onDestroy()
+    }
+
+    // todo: 2023/4/17 订阅事件类
+    class EventCaseToolsAction @JvmOverloads constructor(
+        action: Int
+    ) {
+        // define: 2023/4/17 定义动作常量
+        companion object {
+            const val CLOSE_DRAW: Int = 0
+        }
+
+        // define: 2023/4/17 定义动作
+        var action: Int = -1
+
+        /**
+         * 初始化
+         */
+        init {
+            this.action = action
+        }
+    }
+}

+ 45 - 0
app/src/main/java/com/cr/pages/FragmentMap.kt

@@ -890,6 +890,20 @@ class FragmentMap : CrAnimationFragment() {
         appendMeasureLabel(location,String.format("经度:%s   纬度:%s",longitude,latitude))
     }
 
+    /**
+     * 添加经纬度点到地图中
+     * @param longitude String 经度值
+     * @param latitude String 纬度值
+     */
+    private fun appendWGS84PointToMap(longitude:String,latitude:String){
+        var lng = longitude.toDouble()
+        var lat = latitude.toDouble()
+        var wgs84Point = Point(lng,lat, SpatialReference.create(4326))
+        var location = GeometryEngine.project(wgs84Point,mMap?.spatialReference) as Point
+        appendLocation(location,longitude,latitude)
+    }
+
+
 
     /**
      * 测量长度
@@ -943,13 +957,32 @@ class FragmentMap : CrAnimationFragment() {
                 CrUtil.showMessage("输入的纬度值不符合要求!")
             }else{
                 self.dismiss()
+                // todo: 2023/6/8 添加到地图中
+                appendWGS84PointToMap(valueOne,valueTwo)
             }
         }
 
         // todo: 2023/6/7 点击取消按钮回调
         override fun close() {
         }
+    }
 
+    /**
+     * 开始绘制案件图斑
+     */
+    private fun caseStartDraw(){
+        CrUtil.showMessage("地图上点击开始绘制!")
+        sketchEditor?.let {
+            it.stop()
+            it.removeGeometryChangedListener(sketchGeometryChangeListener)
+            // todo: 2023/6/6 设置编辑模式
+            var model = SketchEditConfiguration()
+            model.isAllowPartSelection = true
+            model.isContextMenuEnabled = false
+            model.isRequireSelectionBeforeDrag = true
+            it.start(SketchCreationMode.POLYGON,model)
+            it.opacity = 1.0f
+        }
     }
 
     /**
@@ -1082,6 +1115,18 @@ class FragmentMap : CrAnimationFragment() {
                 dialogInput.setListener(inputLocationToMapListener)
                 dialogInput.show()
             }
+            // todo: 2023/6/9 开始绘制案件图斑
+            MapAction.EventCaseDrawPolygon->{
+                caseStartDraw()
+            }
+            // todo: 2023/6/9 重置绘制
+            MapAction.EventCaseDrawReset->{
+                caseStartDraw()
+            }
+            // todo: 2023/6/9 回退
+            MapAction.EventCaseDrawUndo->{
+                sketchEditor?.undo()
+            }
         }
     }
 

+ 0 - 1
app/src/main/java/com/cr/widget/CrButton.kt

@@ -7,7 +7,6 @@ import android.view.View
 import android.widget.LinearLayout
 import android.widget.TextView
 import com.cr.cruav.R
-import com.cr.data.CrUtil
 import com.cr.data.FontManager
 
 /**

+ 58 - 0
app/src/main/res/layout/frag_case_tools.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout 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:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/shape_back_fragment"
+    tools:ignore="MissingDefaultResource">
+    <com.cr.widget.CrNavigationBarWidget
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:crTitle="@string/nv_title_case_tools"
+        app:isGotoBack="false"
+        app:isDismiss="true"
+        android:id="@+id/nv"
+        android:layout_weight="0"/>
+    <LinearLayout
+        style="@style/view_tools_line_row">
+        <TextView
+            style="@style/view_tools_line_row_title"
+            android:text="@string/frag_case_title_on_draw"/>
+        <Switch
+            style="@style/item_layer_padding"
+            android:track="@drawable/switch_track"
+            android:thumb="@drawable/switch_thumb"
+            android:id="@+id/case_on_draw"/>
+    </LinearLayout>
+    <View style="@style/view_split_h2"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_case_title_save"
+        app:crLeftResource = "@string/ico_save"
+        android:id="@+id/case_save"/>
+    <View style="@style/view_split_h2"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_case_title_delete"
+        app:crLeftResource = "@string/ico_delete"
+        android:id="@+id/cases_delete"/>
+    <View style="@style/view_split_h2"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_case_title_back"
+        app:crLeftResource = "@string/ico_undo"
+        android:id="@+id/case_undo"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_case_title_reset"
+        app:crLeftResource = "@string/ico_remove"
+        android:id="@+id/case_reset"/>
+    <View style="@style/view_split_h2"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_case_title_move_case"
+        app:crLeftResource = "@string/ico_move"
+        android:id="@+id/case_move_point"/>
+</LinearLayout>

+ 11 - 5
app/src/main/res/layout/frag_map.xml

@@ -2,12 +2,18 @@
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:clipChildren="false"
+    android:clipToPadding="false">
+
     <com.esri.arcgisruntime.mapping.view.MapView
+        android:id="@+id/map_mapView"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        android:id="@+id/map_mapView"
-        android:layout_margin="-20dp"/>
+        android:layout_marginTop="-50dp"
+        android:layout_marginLeft="-50dp"
+        android:layout_marginBottom="-50dp"
+        android:layout_marginRight="-50dp"/>
+<!--        app:layout_constraintStart_toStartOf="parent"-->
+<!--        app:layout_constraintTop_toTopOf="parent" />-->
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 3 - 3
app/src/main/res/layout/frag_tools.xml

@@ -5,14 +5,14 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/shape_back_fragment">
+
     <com.cr.widget.CrNavigationBarWidget
+        android:id="@+id/nv"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:crTitle="@string/nv_title_tools"
-        app:isGotoBack="false"
         app:isDismiss="true"
-        android:id="@+id/nv"
-        android:layout_weight="0"/>
+        app:isGotoBack="false" />
     <com.cr.widget.CrButton
         style="@style/view_tools_line_row_button"
         app:crTitle="@string/frag_tools_measure_length"

+ 35 - 0
app/src/main/res/layout/tools_top.xml

@@ -5,6 +5,41 @@
     android:layout_height="wrap_content">
     <LinearLayout
         style="@style/tools_top_panel"
+        android:id="@+id/tools_append_point_from_uav">
+        <ImageView
+            style="@style/tools_image"
+            android:src="@drawable/ico_location"/>
+    </LinearLayout>
+    <LinearLayout
+        style="@style/tools_top_panel"
+        android:id="@+id/tools_append_point_from_map">
+        <ImageView
+            style="@style/tools_image"
+            android:src="@drawable/ico_airstate"/>
+    </LinearLayout>
+    <LinearLayout
+        style="@style/tools_top_panel"
+        android:id="@+id/tools_case_tools">
+        <ImageView
+            style="@style/tools_image"
+            android:src="@drawable/ico_case_tools"/>
+    </LinearLayout>
+    <LinearLayout
+        style="@style/tools_top_panel"
+        android:id="@+id/tools_case_local">
+        <ImageView
+            style="@style/tools_image"
+            android:src="@drawable/ico_identify_localcase"/>
+    </LinearLayout>
+    <LinearLayout
+        style="@style/tools_top_panel"
+        android:id="@+id/tools_case_net">
+        <ImageView
+            style="@style/tools_image"
+            android:src="@drawable/ico_identify_netcase"/>
+    </LinearLayout>
+    <LinearLayout
+        style="@style/tools_top_panel"
         android:id="@+id/tools_wx">
         <ImageView
             style="@style/tools_image"

+ 3 - 2
app/src/main/res/layout/wg_button.xml

@@ -6,16 +6,17 @@
     android:background="@drawable/tools_btn_selector"
     android:id="@+id/wg_button_panel"
     android:clickable="true"
+    android:focusable="true"
     android:gravity="center_vertical">
     <LinearLayout
         style="@style/view_button_panel">
         <TextView
             style="@style/view_button_image"
-            android:text="A"
+            android:text="@string/bar_lbl_left"
             android:id="@+id/wg_button_ico"/>
         <TextView
             style="@style/view_button_text"
-            android:text="Title"
+            android:text="@string/bar_lbl_title"
             android:id="@+id/wg_button_title"/>
     </LinearLayout>
 </LinearLayout>

+ 3 - 3
app/src/main/res/layout/wg_navigation_bar.xml

@@ -9,7 +9,7 @@
         android:layout_width="@dimen/cr_34_dp"
         android:layout_height="match_parent"
         android:textColor="@color/white"
-        android:text="A"
+        android:text="@string/bar_lbl_left"
         android:textSize="@dimen/sp_15"
         android:textStyle="bold"
         android:layout_weight="0"
@@ -19,7 +19,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:textSize="@dimen/sp_15"
-        android:text="标题"
+        android:text="@string/bar_lbl_title"
         android:textColor="@color/white"
         android:layout_weight="1"
         android:gravity="center"
@@ -28,7 +28,7 @@
         android:layout_width="@dimen/cr_34_dp"
         android:layout_height="match_parent"
         android:textColor="@color/white"
-        android:text="A"
+        android:text="@string/bar_lbl_right"
         android:textSize="@dimen/sp_15"
         android:textStyle="bold"
         android:layout_weight="0"

+ 17 - 1
app/src/main/res/values/strings.xml

@@ -98,6 +98,14 @@
     <string name="frag_doodle_title_on_select">选择涂鸦</string>
     <string name="frag_doodle_title_on_delete">删除涂鸦</string>
 
+    <!--图斑编辑页面相关-->
+    <string name="frag_case_title_on_draw">开启绘制</string>
+    <string name="frag_case_title_save">保存绘制图斑</string>
+    <string name="frag_case_title_delete">删除保存图斑</string>
+    <string name="frag_case_title_back">回退一步</string>
+    <string name="frag_case_title_reset">重新绘制图斑</string>
+    <string name="frag_case_title_move_case">移动绘制案件点</string>
+
     <!--标志页面相关-->
     <string name="frag_mark_title_rotate">旋转角度</string>
     <string name="frag_mark_title_type">图片类型</string>
@@ -116,10 +124,15 @@
     <!--工具箱页面相关-->
     <string name="frag_tools_measure_length">长度测量</string>
     <string name="frag_tools_measure_area">面积测量</string>
-    <string name="frag_tools_measure_clear">清除测量内容</string>
+    <string name="frag_tools_measure_clear">清除内容</string>
     <string name="frag_tools_get_location">获取经纬度</string>
     <string name="frag_tools_to_location">经纬度定位</string>
 
+    <!--Bar相关-->
+    <string name="bar_lbl_left">左</string>
+    <string name="bar_lbl_right">右</string>
+    <string name="bar_lbl_title">标题</string>
+
     <!--字体-->
     <string name="ico_nv_left" translatable="false">&#xe60b;</string>
     <string name="ico_nv_right" translatable="false">&#xe81a;</string>
@@ -133,6 +146,9 @@
     <string name="ico_remove">&#xec49;</string>
     <string name="ico_delete">&#xe604;</string>
     <string name="ico_location">&#xe636;</string>
+    <string name="ico_undo">&#xe6ce;</string>
+    <string name="ico_redo">&#xe6cc;</string>
+    <string name="ico_move">&#xe8c9;</string>
 
 
 </resources>

+ 1 - 1
app/src/main/res/values/themes.xml

@@ -331,6 +331,6 @@
     <declare-styleable name="ViewButton">
         <attr name="crTitle" />
         <attr name="crLeftResource" />
-        <attr name="crClickGround" />
+        <attr name="crClickGround" format="reference" />
     </declare-styleable>
 </resources>