|
@@ -9,11 +9,9 @@ import com.grkj.iscs_mars.util.BitmapUtil
|
|
|
import com.grkj.iscs_mars.util.Executor
|
|
import com.grkj.iscs_mars.util.Executor
|
|
|
import com.grkj.iscs_mars.util.NetApi
|
|
import com.grkj.iscs_mars.util.NetApi
|
|
|
import com.grkj.iscs_mars.util.log.LogUtil
|
|
import com.grkj.iscs_mars.util.log.LogUtil
|
|
|
-import com.grkj.iscs_mars.util.replaceLayer
|
|
|
|
|
import com.grkj.iscs_mars.view.base.BasePresenter
|
|
import com.grkj.iscs_mars.view.base.BasePresenter
|
|
|
import com.grkj.iscs_mars.view.iview.ISwitchStatusView
|
|
import com.grkj.iscs_mars.view.iview.ISwitchStatusView
|
|
|
import com.grkj.iscs_mars.view.widget.CustomSwitchStationLayer
|
|
import com.grkj.iscs_mars.view.widget.CustomSwitchStationLayer
|
|
|
-import com.grkj.iscs_mars.view.widget.RegionTileLayer
|
|
|
|
|
import com.onlylemi.mapview.library.MapView
|
|
import com.onlylemi.mapview.library.MapView
|
|
|
import java.io.File
|
|
import java.io.File
|
|
|
|
|
|
|
@@ -91,105 +89,99 @@ class SwitchStatusPresenter : BasePresenter<ISwitchStatusView>() {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 首屏快速预览(低清),仅用于先显示个底色/缩略
|
|
|
|
|
- BitmapUtil.decodePreview(
|
|
|
|
|
- tempImageFile,
|
|
|
|
|
- backgroundColor = context.getColor(R.color.color_map_base)
|
|
|
|
|
- ).also(onPreview)
|
|
|
|
|
-
|
|
|
|
|
// ===== 2) 读取后端坐标系尺寸 =====
|
|
// ===== 2) 读取后端坐标系尺寸 =====
|
|
|
val backendW = itMapInfo.width?.toFloat() ?: return
|
|
val backendW = itMapInfo.width?.toFloat() ?: return
|
|
|
val backendH = itMapInfo.height?.toFloat() ?: return
|
|
val backendH = itMapInfo.height?.toFloat() ?: return
|
|
|
|
|
+ // 首屏快速预览(低清),仅用于先显示个底色/缩略
|
|
|
|
|
+ LogUtil.i("后台设置数据:${backendW},${backendH}")
|
|
|
|
|
+ val map = BitmapUtil.loadBitmapFromFile(
|
|
|
|
|
+ tempImageFile,
|
|
|
|
|
+ outWidth = backendW.toInt(),
|
|
|
|
|
+ outHeight = backendH.toInt(),
|
|
|
|
|
+ backgroundColor = context.getColor(R.color.color_map_base)
|
|
|
|
|
+ )?.also(onPreview)
|
|
|
|
|
+
|
|
|
|
|
+ map?.let {
|
|
|
|
|
+ val points = mutableListOf<CustomSwitchStationLayer.IsolationPoint>()
|
|
|
|
|
+ val byId = mutableMapOf<Long, CustomSwitchStationLayer.IsolationPoint>()
|
|
|
|
|
+ val ratio = getInitZoom(
|
|
|
|
|
+ (mapViewRef()?.measuredWidth ?: it.width).toFloat(),
|
|
|
|
|
+ (mapViewRef()?.measuredHeight ?: it.height).toFloat(),
|
|
|
|
|
+ backendW,
|
|
|
|
|
+ backendH
|
|
|
|
|
+ )
|
|
|
|
|
+ LogUtil.i("缩放比1:${mapViewRef()?.measuredWidth},${mapViewRef()?.measuredHeight},${map.width},${map.height}")
|
|
|
|
|
+ LogUtil.i("缩放比2:${ratio}")
|
|
|
|
|
+ val offX = itMapInfo.x?.toFloatOrNull() ?: 0f
|
|
|
|
|
+ val offY = itMapInfo.y?.toFloatOrNull() ?: 0f
|
|
|
|
|
+ itMotorMapInfo?.data?.asSequence()
|
|
|
|
|
+ ?.filter { it.x != null && it.y != null && it.motorId != null }?.forEach { pt ->
|
|
|
|
|
+ // 每个点:
|
|
|
|
|
+ val gridX = (pt.x!!.toFloat() + 1.5f) * cellPx
|
|
|
|
|
+ val gridY = (pt.y!!.toFloat() + 1.5f) * cellPx
|
|
|
|
|
+
|
|
|
|
|
+ // **修正:用 ‘加’ 把子图局部坐标搬到大图坐标系**
|
|
|
|
|
+ var worldX = gridX + offX
|
|
|
|
|
+ var worldY = gridY + offY
|
|
|
|
|
+
|
|
|
|
|
+ // 如果后端以左下为原点,需要翻 Y(基于“世界高度”翻)
|
|
|
|
|
+ if (yAxisFlip) {
|
|
|
|
|
+ worldY = backendH - worldY
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- // ===== 3) 计算点位(全部落在“后端坐标系”里)=====
|
|
|
|
|
- val offX = (itMapInfo.x ?: "0").toFloat()
|
|
|
|
|
- val offY = (itMapInfo.y ?: "0").toFloat()
|
|
|
|
|
-
|
|
|
|
|
- val points = mutableListOf<CustomSwitchStationLayer.IsolationPoint>()
|
|
|
|
|
- val byId = mutableMapOf<Long, CustomSwitchStationLayer.IsolationPoint>()
|
|
|
|
|
-
|
|
|
|
|
- itMotorMapInfo?.data
|
|
|
|
|
- ?.asSequence()
|
|
|
|
|
- ?.filter { it.x != null && it.y != null && it.motorId != null }
|
|
|
|
|
- ?.forEach { pt ->
|
|
|
|
|
- // 每个点:
|
|
|
|
|
- val gridX = (pt.x!!.toFloat() + 0.5f) * cellPx
|
|
|
|
|
- val gridY = (pt.y!!.toFloat() + 0.5f) * cellPx
|
|
|
|
|
-
|
|
|
|
|
- // **修正:用 ‘加’ 把子图局部坐标搬到大图坐标系**
|
|
|
|
|
- var worldX = gridX + offX
|
|
|
|
|
- var worldY = gridY + offY
|
|
|
|
|
-
|
|
|
|
|
- // 如果后端以左下为原点,需要翻 Y(基于“世界高度”翻)
|
|
|
|
|
- if (yAxisFlip) {
|
|
|
|
|
- worldY = backendH - worldY
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 2) 去掉子图偏移(后端通常给“子图左上在大图中的偏移”)
|
|
|
|
|
- var localX = gridX - offX
|
|
|
|
|
- var localY = gridY - offY
|
|
|
|
|
-
|
|
|
|
|
- // 3) 若后端以左下为原点,需要翻转 Y(以后端子图高度为参考)
|
|
|
|
|
- if (yAxisFlip) {
|
|
|
|
|
- worldY = backendH - worldY
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 4) 直接作为最终坐标(不要乘 ratioX/ratioY)
|
|
|
|
|
- val fX = localX
|
|
|
|
|
- val fY = localY
|
|
|
|
|
-
|
|
|
|
|
- val switchStatus =
|
|
|
|
|
- if (pt.switchStatus == "1") CustomSwitchStationLayer.STATUS_ON
|
|
|
|
|
- else CustomSwitchStationLayer.STATUS_OFF
|
|
|
|
|
-
|
|
|
|
|
- val p = CustomSwitchStationLayer.IsolationPoint(
|
|
|
|
|
- pos = android.graphics.PointF(worldX, worldY),
|
|
|
|
|
- motorCode = pt.motorCode,
|
|
|
|
|
- pointName = pt.pointName,
|
|
|
|
|
- motorName = pt.motorName,
|
|
|
|
|
- motorType = pt.motorType,
|
|
|
|
|
- pointId = pt.pointId,
|
|
|
|
|
- icon = null,
|
|
|
|
|
- entityId = pt.motorId!!,
|
|
|
|
|
- pointSerialNumber = pt.pointSerialNumber,
|
|
|
|
|
- isSelected = false,
|
|
|
|
|
- pointNfc = pt.pointNfc ?: "",
|
|
|
|
|
- status = switchStatus
|
|
|
|
|
- )
|
|
|
|
|
- points += p
|
|
|
|
|
- byId[p.entityId] = p
|
|
|
|
|
-
|
|
|
|
|
- // 5) 异步加载小图标(有则回填,并做局部刷新)
|
|
|
|
|
- val url = pt.pointIcon
|
|
|
|
|
- if (!url.isNullOrBlank()) {
|
|
|
|
|
- BitmapUtil.loadBitmapSmall(
|
|
|
|
|
- ctx = context,
|
|
|
|
|
- url = url,
|
|
|
|
|
- reqW = 64,
|
|
|
|
|
- reqH = 64
|
|
|
|
|
- ) { bmp ->
|
|
|
|
|
- val target = byId[p.entityId] ?: return@loadBitmapSmall
|
|
|
|
|
- target.icon = bmp
|
|
|
|
|
- // pos 为中心锚点,绘制时以中心绘制;只需局部刷新
|
|
|
|
|
- stationLayer?.refreshIfVisible(target.pos)
|
|
|
|
|
|
|
+ val switchStatus =
|
|
|
|
|
+ if (pt.switchStatus == "1") CustomSwitchStationLayer.STATUS_ON
|
|
|
|
|
+ else CustomSwitchStationLayer.STATUS_OFF
|
|
|
|
|
+
|
|
|
|
|
+ val p = CustomSwitchStationLayer.IsolationPoint(
|
|
|
|
|
+ pos = android.graphics.PointF(worldX, worldY),
|
|
|
|
|
+ motorCode = pt.motorCode,
|
|
|
|
|
+ pointName = pt.pointName,
|
|
|
|
|
+ motorName = pt.motorName,
|
|
|
|
|
+ motorType = pt.motorType,
|
|
|
|
|
+ pointId = pt.pointId,
|
|
|
|
|
+ icon = null,
|
|
|
|
|
+ entityId = pt.motorId!!,
|
|
|
|
|
+ pointSerialNumber = pt.pointSerialNumber,
|
|
|
|
|
+ isSelected = false,
|
|
|
|
|
+ pointNfc = pt.pointNfc ?: "",
|
|
|
|
|
+ status = switchStatus
|
|
|
|
|
+ )
|
|
|
|
|
+ points += p
|
|
|
|
|
+ byId[p.entityId] = p
|
|
|
|
|
+
|
|
|
|
|
+ // 5) 异步加载小图标(有则回填,并做局部刷新)
|
|
|
|
|
+ val url = pt.pointIcon
|
|
|
|
|
+ if (!url.isNullOrBlank()) {
|
|
|
|
|
+ BitmapUtil.loadBitmapSmall(
|
|
|
|
|
+ ctx = context, url = url, reqW = 64, reqH = 64
|
|
|
|
|
+ ) { bmp ->
|
|
|
|
|
+ val target = byId[p.entityId] ?: return@loadBitmapSmall
|
|
|
|
|
+ target.icon = bmp
|
|
|
|
|
+ // pos 为中心锚点,绘制时以中心绘制;只需局部刷新
|
|
|
|
|
+ stationLayer?.refreshIfVisible(target.pos)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 6) 提交点位(保持选中可选)
|
|
|
|
|
- stationLayer?.submitPoints(points)
|
|
|
|
|
|
|
|
|
|
- /* --- 6) 用 RegionTileLayer 替换旧底图(内部自带 LruCache / 512 tile) --- */
|
|
|
|
|
- if (needReloadMap) {
|
|
|
|
|
- mapViewRef()?.let { mv ->
|
|
|
|
|
- imgFile?.let {
|
|
|
|
|
- val tileLayer = RegionTileLayer(mv, it)
|
|
|
|
|
- mv.replaceLayer("bigMap", tileLayer)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 6) 提交点位(保持选中可选)
|
|
|
|
|
+ stationLayer?.submitPoints(points)
|
|
|
}
|
|
}
|
|
|
- needReloadMap = false
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * calculate init zoom
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param viewWidth
|
|
|
|
|
+ * @param viewHeight
|
|
|
|
|
+ * @param imageWidth
|
|
|
|
|
+ * @param imageHeight
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ // 等比塞入视图(不裁剪)
|
|
|
|
|
+ private fun getInitZoom(vw: Float, vh: Float, iw: Float, ih: Float): Float {
|
|
|
|
|
+ if (vw <= 0f || vh <= 0f || iw <= 0f || ih <= 0f) return 1f
|
|
|
|
|
+ return minOf(vw / iw, vh / ih)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|