[MAP] 高精地图Marker绘制逻辑重构

This commit is contained in:
renwj
2023-05-08 14:46:29 +08:00
parent eecea49493
commit 22cf999031
97 changed files with 3615 additions and 6757 deletions

View File

@@ -0,0 +1,74 @@
package com.mogo.map.overlay
import com.mogo.map.overlay.core.*
import com.mogo.map.overlay.line.*
import com.mogo.map.overlay.point.*
import com.mogo.map.overlay.point.Point.Options as PointOptions
import com.mogo.map.overlay.line.Polyline.Options as LineOptions
interface IMoGoOverlayManager {
fun showOrUpdatePoint(options: PointOptions): Point?
fun hidePoint(id: String)
fun hidePoint(p: Point)
fun hideAllPointsInOwner(owner: String)
fun hideAllPointsInLevel(level: Level)
fun hideAllPoints()
fun removePoint(id: String)
fun removePoint(p: Point)
fun removeAllPointsInOwner(owner: String)
fun removeAllPointsInLevel(level: Level)
fun removeAllPoints()
fun showAllPoints()
fun showAllPointsInOwner(owner: String)
fun showAllPointsInLevel(level: Level)
fun showPoint(id: String)
fun showOrUpdateLine(options: LineOptions): Polyline?
fun hideLine(id: String)
fun hideLine(p: Polyline)
fun hideAllLinesInOwner(owner: String)
fun hideAllLinesInLevel(level: Level)
fun hideAllLines()
fun removeLine(id: String)
fun removeLine(p: Polyline)
fun removeAllLinesInOwner(owner: String)
fun removeAllLinesInLevel(level: Level)
fun removeAllLines()
fun showAllLines()
fun showAllLinesInOwner(owner: String)
fun showAllLinesInLevel(level: Level)
fun showLine(id: String)
fun hideAllPointsExceptIds(vararg ids: String)
fun hideAllPointsExceptOwners(vararg owners: String)
}

View File

@@ -1,18 +0,0 @@
package com.mogo.map.overlay;
/**
* @author congtaowang
* @since 2020-03-10
* <p>
* 覆盖物
*/
public interface IMogoOverlayManager {
/**
* 绘制线段
*
* @param options
* @return
*/
IMogoPolyline addPolyline( MogoPolylineOptions options );
}

View File

@@ -1,144 +0,0 @@
package com.mogo.map.overlay;
import androidx.annotation.ColorInt;
import com.mogo.map.IDestroyable;
import com.mogo.eagle.core.data.map.MogoLatLng;
import java.util.List;
/**
* @author congtaowang
* @since 2020-03-10
* <p>
* 线段
*/
public interface IMogoPolyline extends IDestroyable {
/**
* 是否已经销毁
*
* @return
*/
boolean isDestroyed();
/**
* 移除
*/
void remove();
/**
* 获取ID
*
* @return
*/
String getId();
/**
* 设置绘制点数据
*
* @param lonLats
*/
void setPoints( List< MogoLatLng > lonLats );
/**
* 获取点
*
* @return
*/
List< MogoLatLng > getPoints();
/**
* 测地线
*
* @param draw
*/
void setGeodesic( boolean draw );
/**
* 是否设置了测地线
*
* @return
*/
boolean isGeodesic();
/**
* 虚线
*
* @param dottedLine
*/
void setDottedLine( boolean dottedLine );
/**
* 是否是虚线
*
* @return
*/
boolean isDottedLine();
/**
* 设置线宽
*
* @param width
*/
void setWidth( float width );
/**
* 获取线宽
*
* @return
*/
float getWidth();
/**
* 设置线条颜色
*
* @param color
*/
void setColor( @ColorInt int color );
/**
* 获取线条颜色
*
* @return
*/
@ColorInt
int getColor();
/**
* 设置Z轴
*/
void setZIndex( float zIndex );
/**
* 获取Z轴
*
* @return
*/
float getZIndex();
/**
* 设置显示/隐藏
*/
void setVisible( boolean visible );
/**
* 是否可见
*
* @return
*/
boolean isVisible();
/**
* 设置透明度
*
* @param transparency
*/
void setTransparency( float transparency );
/**
* 设置配置项
*/
void setOption( MogoPolylineOptions option );
}

View File

@@ -1,288 +0,0 @@
package com.mogo.map.overlay;
import android.graphics.Color;
import androidx.annotation.ColorInt;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.data.map.MogoLocation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author congtaowang
* @since 2020-03-10
* <p>
* 线段属性
*/
public class MogoPolylineOptions {
public boolean useFacade = false;
public float maxIndex = Float.MIN_VALUE;
private List<MogoLatLng> mPoints;
private float mWidth = 10.0F;
private int mColor = Color.BLACK;
private float mZIndex = 0.0F;
private boolean mIsVisible = true;
private boolean mIsGeodesic = false;
private boolean mIsDottedLine = false;
private boolean mIsGradient = false;
private float mTransparency = 1.0F;
private boolean mIsAboveMaskLayer = false;
private boolean mIsPointsUpdated = false;
private boolean mGps = false;
private List<Integer> mColorValues;
private float brightSpeed = Float.MIN_VALUE;
private int brightColor = -1;
private boolean isBrightOn = false;
public MogoPolylineOptions() {
this.mPoints = new ArrayList<>();
}
/**
* 设置顶点
*
* @param points
* @return
*/
public MogoPolylineOptions points(List<MogoLatLng> points) {
this.mPoints.clear();
this.mPoints.addAll(points);
this.mIsPointsUpdated = true;
return this;
}
/**
* 添加顶点到集合最后
*
* @param points
* @return
*/
public MogoPolylineOptions add(MogoLatLng... points) {
if (points != null) {
this.mPoints.addAll(Arrays.asList(points));
this.mIsPointsUpdated = true;
}
return this;
}
public MogoPolylineOptions add(double lon, double lat) {
this.mPoints.add(new MogoLatLng(lat, lon));
return this;
}
public MogoPolylineOptions add(MogoLocation location) {
if (location != null) {
this.mPoints.add(new MogoLatLng(location.getLatitude(), location.getLongitude()));
}
return this;
}
/**
* 设置线宽
*/
public MogoPolylineOptions width(float width) {
this.mWidth = width;
return this;
}
/**
* 设置线的颜色
*
* @param color
* @return
*/
public MogoPolylineOptions color(@ColorInt int color) {
this.mColor = color;
return this;
}
/**
* 设置Z轴的值
*
* @param zIndex
* @return
*/
public MogoPolylineOptions zIndex(float zIndex) {
this.mZIndex = zIndex;
return this;
}
/**
* 设置是否可见
*
* @param isVisible
* @return
*/
public MogoPolylineOptions visible(boolean isVisible) {
this.mIsVisible = isVisible;
return this;
}
/**
* 设置是否绘制测地线
*
* @param isGeodesic
* @return
*/
public MogoPolylineOptions geodesic(boolean isGeodesic) {
this.mIsGeodesic = isGeodesic;
return this;
}
/**
* 是否是虚线
*
* @param isDottedLine
* @return
*/
public MogoPolylineOptions dottedLine(boolean isDottedLine) {
this.mIsDottedLine = isDottedLine;
return this;
}
/**
* 是否使用渐变色
*
* @param isGradient
* @return
*/
public MogoPolylineOptions useGradient(boolean isGradient) {
this.mIsGradient = isGradient;
return this;
}
public MogoPolylineOptions maxIndex(float maxIndex) {
this.maxIndex = maxIndex;
return this;
}
/**
* 设置透明度
*
* @param transparency
* @return
*/
public MogoPolylineOptions transparency(float transparency) {
this.mTransparency = transparency;
return this;
}
public MogoPolylineOptions brightSpeed(float speed) {
this.brightSpeed = speed;
return this;
}
public MogoPolylineOptions openBright(boolean on) {
this.isBrightOn = on;
return this;
}
public MogoPolylineOptions brightColor(int color) {
this.brightColor = color;
return this;
}
public MogoPolylineOptions useFacade(boolean useFacade) {
this.useFacade = useFacade;
return this;
}
/**
* @param isAboveMaskLayer
* @return
*/
public MogoPolylineOptions aboveMaskLayer(boolean isAboveMaskLayer) {
this.mIsAboveMaskLayer = isAboveMaskLayer;
return this;
}
/**
* @param colors
* @return
*/
public MogoPolylineOptions colorValues(List<Integer> colors) {
mColorValues = colors;
return this;
}
public boolean gps() {
return mGps;
}
public MogoPolylineOptions setGps(boolean gps) {
mGps = gps;
return this;
}
public List<MogoLatLng> getPoints() {
return mPoints;
}
public float getWidth() {
return mWidth;
}
public int getColor() {
return mColor;
}
public float getZIndex() {
return mZIndex;
}
public boolean isVisible() {
return mIsVisible;
}
public boolean isGeodesic() {
return mIsGeodesic;
}
public boolean isDottedLine() {
return mIsDottedLine;
}
public boolean isGradient() {
return mIsGradient;
}
public boolean useFacade() {
return useFacade;
}
public float getTransparency() {
return mTransparency;
}
public boolean isAboveMaskLayer() {
return mIsAboveMaskLayer;
}
public boolean isPointsUpdated() {
return mIsPointsUpdated;
}
public float getBrightSpeed() {
return brightSpeed;
}
public boolean isBrightOn() {
return isBrightOn;
}
public int getBrightColor() {
return brightColor;
}
public List<Integer> getColorValues() {
return mColorValues;
}
}

View File

@@ -0,0 +1,28 @@
package com.mogo.map.overlay.core
enum class Level(val zIndex: Int) {
DEFAULT(10),
/**
* 地图上Marker覆盖物
*/
MAP_MARKER(100),
/**
* 车道中心线
*/
ROAD_CENTER_LINE(40000),
/**
* 前车引导线
*/
GUIDE_ROUTE_LINE(75000),
/**
* 道路围栏区域绘制
*/
MAP_POLYGON(76000)
}

View File

@@ -0,0 +1,194 @@
package com.mogo.map.overlay.line
import android.graphics.*
import android.text.TextUtils
import com.mogo.eagle.core.data.map.MogoLatLng
import com.mogo.map.overlay.core.*
import com.mogo.map.overlay.proxy.line.*
import java.util.UUID
data class Polyline(val id: String, val owner: String, val level: Level, val options: Options) {
@Volatile
var delegate: IMapPolylineOverlay? = null
class Options private constructor(private val builder: Builder) {
val id: String = builder.id ?: throw AssertionError("id must not be null.")
val owner: String = builder.owner
val level: Level = builder.level
val useFacade: Boolean = builder.useFacade
val maxIndex: Float = builder.maxIndex
val points: List<MogoLatLng>? = builder.points
val width = builder.width
val color: Int = builder.color
val isVisible = builder.isVisible
val isGeodesic = builder.isGeodesic
val isDottedLine = builder.isDottedLine
val dottedLineType = builder.dottedLineType
val isGradient = builder.isGradient
val alpha = builder.alpha
val isUseGps = builder.isUseGps
val colors: List<Int>? = builder.colors
val isLightOn: Boolean = builder.isLightOn
val lightColor: Int = builder.lightColor
val lightSpeed: Float = builder.lightSpeed
fun builder(): Builder {
return builder
}
class Builder(val owner: String, val level: Level) {
internal var id: String? = null
internal var useFacade: Boolean = false
internal var maxIndex: Float = Float.MIN_VALUE
internal var points: List<MogoLatLng>? = null
internal var width = 10.0f
internal var color: Int = Color.BLACK
internal var isVisible = true
internal var isGeodesic = false
internal var isDottedLine = false
internal var dottedLineType = -1
internal var isGradient = false
internal var alpha = 1.0f
internal var isUseGps = false
internal var colors: List<Int>? = null
internal var isLightOn: Boolean = false
internal var lightColor: Int = Color.WHITE
internal var lightSpeed: Float = 0f
fun setId(id: String) = apply {
this.id = id
}
fun points(points: List<MogoLatLng>) = apply {
this.points = points
}
fun colors(colors: List<Int>) = apply {
this.colors = colors
}
fun color(color: Int) = apply {
this.color = color
}
fun setVisible(visible: Boolean) = apply {
this.isVisible = visible
}
fun setWidth(width: Float) = apply {
this.width = width
}
fun setMaxIndex(maxIndex: Float) = apply {
this.maxIndex = maxIndex
}
fun useFacade(facade: Boolean) = apply {
this.useFacade = facade
}
fun setGeodesic(isGeodesic: Boolean) = apply {
this.isGeodesic = isGeodesic
}
fun setIsDottedLine(isDottedLine: Boolean) = apply {
this.isDottedLine = isDottedLine
}
fun setDottedLineType(type: Int) = apply {
this.dottedLineType = type
}
fun setIsGradient(isGradient: Boolean) = apply {
this.isGradient = isGradient
}
fun setAlpha(alpha: Float) = apply {
this.alpha = alpha
}
fun setUseGps(isUseGps: Boolean) = apply {
this.isUseGps = isUseGps
}
fun setLightOn(isLightOn: Boolean) = apply {
this.isLightOn = isLightOn
}
fun setLightColor(color: Int) = apply {
this.lightColor = color
}
fun setLightSpeed(speed: Float) = apply {
this.lightSpeed = speed
}
fun build(): Options {
if (TextUtils.isEmpty(id)) {
id = UUID.randomUUID().toString()
}
if (TextUtils.isEmpty(id)) {
throw AssertionError("id must not be null.")
}
return Options(this)
}
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Polyline
if (id != other.id) return false
if (owner != other.owner) return false
if (level != other.level) return false
return true
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + owner.hashCode()
result = 31 * result + level.hashCode()
return result
}
}

View File

@@ -0,0 +1,448 @@
package com.mogo.map.overlay.point
import android.graphics.*
import android.text.TextUtils
import android.view.*
import androidx.annotation.*
import com.mogo.map.overlay.core.*
import com.mogo.map.overlay.proxy.point.*
import java.util.*
data class Point(val id: String, val owner: String, val level: Level, val option: Options) {
@Volatile
var delegate: IMapPointOverlay? = null
/**
*
* 地图上绘制点相关的参数
*/
class Options private constructor(private val builder: Builder){
/**
* 唯一标识,可以通过此标识,操作对点的显示和隐藏
*/
val id: String = builder.id ?: throw AssertionError("id must not be null")
/**
* 当前地图覆盖物所在level(zIndex值在此存储)
*/
val level: Level = builder.level
/**
* 当前地图覆盖物所属的业务类型
*/
val owner: String = builder.owner
/**
* 绘制点的纬度
*/
val latitude: Double = builder.latitude ?: 0.0
/**
* 绘制点的经度
*/
val longitude: Double = builder.longitude ?: 0.0
/**
* 3D模型
*/
@RawRes
val icon3DRes: Int = builder.icon3DRes
/**
* 自定义样式
*/
val iconView: View? = builder.iconView
/**
* 指定覆盖物的颜色
*/
val anchorColor: String? = builder.anchorColor
/**
* 文字标题
*/
val title: String? = builder.title
/**
* 文字描述
*/
val snippet: String? = builder.snippet
/**
* 图标对应的Bitmap对象
*/
val icon: Bitmap? = builder.icon
/**
* 设置Marker覆盖物的动画帧图标列表多张图片模拟gif的效果
*/
val icons: ArrayList<Bitmap>? = builder.icons
/**
* 设置多少帧刷新一次图片资源Marker动画的间隔时间值越小动画越快
*/
val period = builder.period
/**
* 设置Marker覆盖物的图片旋转角度从正北开始逆时针计算
*/
val rotate = builder.rotate
/**
* 设置Marker覆盖物是否平贴地图
*/
val isFlat = builder.isFlat
/**
* 设置Marker覆盖物是否可见
*/
val isVisible = builder.isVisible
/**
* 设置Marker覆盖物的InfoWindow是否允许显示
*/
val isInfoWindowEnable = builder.isInfoWindowEnable
/**
* 设置Marker覆盖物的透明度
*/
val alpha = builder.alpha
/**
* 设置Marker覆盖物的透明度
*/
val scale = builder.scale
/**
* Marker覆盖物的坐标是否是Gps
*/
val isGps = builder.isGps
/**
* Marker覆盖物锚点在水平范围的比例
*/
val u = builder.u
/**
* Marker覆盖物锚点垂直范围的比例
*/
val v = builder.v
/**
* 是否是3D模型
*/
val is3DMode: Boolean = builder.is3DMode
/**
* 是否控制角度
*/
val isControlAngle = builder.isControlAngle
/**
* 资源名称便于缓存重复使用和mIcon3DRes、mIconView、icon等冲突需要县设置
*/
val resName: String? = builder.resName
/**
* 是否切换到当前marker所在的视角
*/
val moveToCenter: Boolean = builder.moveToCenter
fun builder(): Builder {
return builder
}
class Builder(val owner: String,val level: Level){
/**
* 唯一标识,可以通过此标识,操作对点的显示和隐藏
*/
internal var id: String? = null
/**
* 绘制点的纬度
*/
internal var latitude: Double? = null
/**
* 绘制点的经度
*/
internal var longitude: Double? = null
/**
* 3D模型
*/
@RawRes
internal var icon3DRes = 0
/**
* 自定义样式
*/
internal var iconView: View? = null
/**
* 指定覆盖物的颜色
*/
internal var anchorColor: String? = null
/**
* 文字标题
*/
internal var title: String? = null
/**
* 文字描述
*/
internal var snippet: String? = null
/**
* 图标对应的Bitmap对象
*/
internal var icon: Bitmap? = null
/**
* 设置Marker覆盖物的动画帧图标列表多张图片模拟gif的效果
*/
internal var icons: ArrayList<Bitmap>? = null
/**
* 设置多少帧刷新一次图片资源Marker动画的间隔时间值越小动画越快
*/
internal var period = 0
/**
* 设置Marker覆盖物的图片旋转角度从正北开始逆时针计算
*/
internal var rotate = 0f
/**
* 设置Marker覆盖物是否平贴地图
*/
internal var isFlat = false
/**
* 设置Marker覆盖物是否可见
*/
internal var isVisible = true
/**
* 设置Marker覆盖物的InfoWindow是否允许显示
*/
internal var isInfoWindowEnable = true
/**
* 设置Marker覆盖物的透明度
*/
internal var alpha = 1.0f
/**
* 设置Marker覆盖物的透明度
*/
internal var scale = 1.0f
/**
* Marker覆盖物的坐标是否是Gps
*/
internal var isGps = false
/**
* Marker覆盖物锚点在水平范围的比例
*/
internal var u = 0.5f
/**
* Marker覆盖物锚点垂直范围的比例
*/
internal var v = 0.5f
/**
* 是否是3D模型
*/
internal var is3DMode: Boolean = false
/**
* 是否控制角度
*/
internal var isControlAngle = false
/**
* 资源名称便于缓存重复使用和mIcon3DRes、mIconView、icon等冲突需要县设置
*/
internal var resName: String? = null
/**
* 是否切换到当前marker所在的视角
*/
internal var moveToCenter: Boolean = true
fun setId(id: String) = apply {
this.id = id
}
fun resName(resName: String?) = apply {
this.resName = resName
}
fun controlAngle(controlAngle: Boolean) = apply {
isControlAngle = controlAngle
}
fun set3DMode(is3DMode: Boolean) = apply {
this.is3DMode = is3DMode
}
fun latitude(latitude: Double) = apply {
this.latitude = latitude
}
fun longitude(longitude: Double) = apply {
this.longitude = longitude
}
/**
* 优先使用icon作为marker资源
* @param icon
* @return
*/
fun icon(icon: Bitmap?) = apply {
this.icon = icon
}
/**
* 帧动画对应的图片序列
*/
fun icons(icons: ArrayList<Bitmap>?) = apply {
this.icons = icons
}
/**
* 帧动画执行完成一次需要的时长,时间越短,帧动画越快
*/
fun period(period: Int) = apply {
this.period = period
if (this.period < 1) {
this.period = 1
}
}
/**
* marker对应的资源的旋转角度正北方为0度逆时针计算
*/
fun rotate(rotate: Float) = apply {
this.rotate = rotate
}
/**
* 是否平铺在地图上
*/
fun flat(flat: Boolean) = apply {
isFlat = flat
}
/**
* 是否可见
*/
fun visible(visible: Boolean) = apply {
isVisible = visible
}
/**
* 设置地图覆盖物的透明度
*/
fun alpha(alpha: Float) = apply {
this.alpha = alpha
}
/**
* 设置地图覆盖物的缩放比例
*/
fun scale(scale: Float) = apply {
this.scale = scale
}
/**
* 设置是否使用GPS坐标
*/
fun isUseGps(gps: Boolean) = apply {
this.isGps = gps
}
/**
* 设置地图覆盖物锚点在水平和垂直方向的比例
*/
fun anchor(u: Float, v: Float) = apply {
this.u = u
this.v = v
}
/**
* 自定义marker图层样式优先使用 icon [.icon]作为marker资源
*
* @param iconView
* @return
*/
fun icon(iconView: View?) = apply {
this.iconView = iconView
}
/**
* 3D模型对应的资源
*/
fun icon3DRes(@RawRes icon3DRes: Int) = apply {
this.icon3DRes = icon3DRes
}
/**
* 设置地图覆盖物的颜色
*/
fun anchorColor(anchorColor: String?) = apply {
this.anchorColor = anchorColor
}
/**
* 是否切换到当前marker所在的视角
*/
fun moveToCenter(flag: Boolean) = apply {
this.moveToCenter = flag
}
/**
* 构建Options对象
*/
fun build(): Options {
if (TextUtils.isEmpty(id)) {
id = UUID.randomUUID().toString()
}
if (TextUtils.isEmpty(id)) {
throw AssertionError("id must not be null.")
}
return Options(this)
}
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Point
if (id != other.id) return false
if (owner != other.owner) return false
if (level != other.level) return false
return true
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + owner.hashCode()
result = 31 * result + level.hashCode()
return result
}
}

View File

@@ -0,0 +1,46 @@
package com.mogo.map.overlay.proxy
interface IMapOverlay {
/**
* 删除当前marker并销毁Marker的图片等资源
*/
fun destroy()
/**
* 删除当前marker。
*/
fun remove()
/**
* 设置 Marker 覆盖物的可见属性。
*
* @param visible
*/
fun setVisible(visible: Boolean)
/**
* 是否已销毁
*/
fun isDestroyed(): Boolean
/**
* 是否可见
*/
fun isVisible(): Boolean
/**
* 设置当前marker在最上面。
*/
fun setToTop()
/**
* 取消当前marker在最上面
*/
fun setUnTop()
fun onRemove(action: (id: String) -> Unit)
}

View File

@@ -0,0 +1,9 @@
package com.mogo.map.overlay.proxy.line
import com.mogo.map.overlay.line.*
import com.mogo.map.overlay.proxy.*
interface IMapPolylineOverlay: IMapOverlay {
fun setOptions(options: Polyline.Options)
}

View File

@@ -0,0 +1,18 @@
package com.mogo.map.overlay.proxy.point
import com.mogo.eagle.core.data.map.MogoLatLng
import com.mogo.map.overlay.point.Point.Options
import com.mogo.map.overlay.proxy.*
interface IMapPointOverlay: IMapOverlay {
/**
* 设置Marker覆盖物的属性选项类 通过markerOption 给marker设置属性
*
* @param opt
*/
fun setOptions(opt: Options)
fun addDynamicAnchorPosition(point: MogoLatLng, angle: Float, duration: Long)
}