[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

@@ -1,195 +0,0 @@
package com.mogo.map.overlay;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.map.utils.ObjectUtils;
import com.zhidaoauto.map.sdk.open.poyline.Polyline;
import com.zhidaoauto.map.sdk.open.poyline.PolylineOptions;
import com.zhidaoauto.map.sdk.open.query.LonLatPoint;
import java.util.ArrayList;
import java.util.List;
/**
* @author congtaowang
* @since 2020-03-10
* <p>
* 描述
*/
public class AMapPolylineWrapper implements IMogoPolyline {
private Polyline mPolyline;
private MogoPolylineOptions mOptions;
private boolean mIsDestroyed = false;
public AMapPolylineWrapper( Polyline mPolyline,
MogoPolylineOptions mOptions ) {
this.mPolyline = mPolyline;
this.mOptions = mOptions;
}
@Override
public void destroy() {
remove();
}
@Override
public void remove() {
if ( mPolyline != null ) {
mPolyline.remove();
}
mIsDestroyed = true;
}
@Override
public String getId() {
if ( mPolyline != null ) {
return mPolyline.getId();
}
return null;
}
@Override
public void setPoints( List< MogoLatLng > lonLats ) {
if ( lonLats == null || lonLats.isEmpty() ) {
mPolyline.setPoints( new ArrayList<LonLatPoint>() );
return;
}
ArrayList< LonLatPoint > points = new ArrayList<>();
for ( MogoLatLng lonLat : lonLats ) {
LonLatPoint latLng = ObjectUtils.fromMogo( lonLat );
if ( latLng == null ) {
continue;
}
points.add( latLng );
}
mPolyline.setPoints( points );
}
@Override
public List< MogoLatLng > getPoints() {
if ( mPolyline == null ) {
return null;
}
ArrayList< MogoLatLng > lonLats = new ArrayList<>();
List<LonLatPoint> points = mPolyline.getPoints();
if ( points != null ) {
for ( LonLatPoint latLng : points ) {
MogoLatLng lonLat = ObjectUtils.fromAMap( latLng );
if ( lonLat == null ) {
continue;
}
lonLats.add( lonLat );
}
}
return lonLats;
}
@Override
public void setGeodesic( boolean draw ) {
if ( mPolyline != null ) {
mPolyline.setGeodesic( draw );
}
}
@Override
public boolean isGeodesic() {
return mPolyline == null ? false : mPolyline.isGeodesic();
}
@Override
public void setDottedLine( boolean dottedLine ) {
if ( mPolyline != null ) {
mPolyline.setDottedLine( dottedLine );
}
}
@Override
public boolean isDottedLine() {
return mPolyline == null ? false : mPolyline.isDottedLine();
}
@Override
public void setWidth( float width ) {
if ( mPolyline != null ) {
mPolyline.setWidth( width );
}
}
@Override
public float getWidth() {
if ( mPolyline != null ) {
return mPolyline.getWidth();
}
return 0;
}
@Override
public void setColor( int color ) {
if ( mPolyline != null ) {
mPolyline.setColor( color );
}
}
@Override
public int getColor() {
if ( mPolyline != null ) {
return mPolyline.getColor();
}
return 0;
}
@Override
public void setZIndex( float zIndex ) {
if ( mPolyline != null ) {
mPolyline.setZIndex( zIndex );
}
}
@Override
public float getZIndex() {
if ( mPolyline != null ) {
return mPolyline.getZIndex();
}
return 0;
}
@Override
public void setVisible( boolean visible ) {
if ( mPolyline != null ) {
mPolyline.setVisible( visible );
}
}
@Override
public boolean isVisible() {
if ( mPolyline != null ) {
return mPolyline.isVisible();
}
return false;
}
@Override
public void setTransparency( float transparency ) {
if ( mPolyline != null ) {
mPolyline.setTransparency( transparency );
}
}
@Override
public void setOption( MogoPolylineOptions option ) {
PolylineOptions target = ObjectUtils.fromMogo( option );
if ( target == null ) {
return;
}
mOptions = option;
if ( mPolyline != null ) {
mPolyline.setOption( target );
}
}
@Override
public boolean isDestroyed() {
return false;
}
}

View File

@@ -0,0 +1,448 @@
package com.mogo.map.overlay
import android.graphics.*
import com.mogo.eagle.core.data.map.*
import com.mogo.eagle.core.function.call.autopilot.*
import com.mogo.eagle.core.function.call.map.*
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.map.overlay.point.Point.Options
import com.mogo.map.*
import com.mogo.map.overlay.core.*
import com.mogo.map.overlay.line.*
import com.mogo.map.overlay.point.Point
import com.mogo.map.overlay.proxy.line.*
import com.mogo.map.overlay.proxy.point.*
import java.util.concurrent.ConcurrentHashMap
internal class MoGoOverlayManagerImpl: IMoGoOverlayManager {
private val points by lazy { ConcurrentHashMap<Point, IMapPointOverlay>() }
private val lines by lazy { ConcurrentHashMap<Polyline, IMapPolylineOverlay>() }
override fun showOrUpdatePoint(options: Options): Point? {
synchronized(points) {
val key = Point(options.id, options.owner, options.level, options)
var point = points[key]
try {
if (point != null) {
point.setOptions(options)
return key
} else {
val p = MogoMap.getInstance().mogoMap.addPoint(options)
if (p != null) {
p.onRemove { removed ->
val keys = points.filterKeys { it.id == removed }
if (keys.isNotEmpty()) {
keys.forEach {
points.remove(it.key)
}
}
}
points[key] = p
point = p
return key
}
}
} finally {
point?.also {
key.delegate = point
it.setToTop()
if (options.moveToCenter) {
moveToCenter(
options.id,
options.longitude,
options.latitude,
if (options.isGps) CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().longitude else CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02().longitude,
if (options.isGps) CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().latitude else CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02().latitude
)
}
}
}
return null
}
}
override fun hidePoint(id: String) {
points.filter { it.key.id == id && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun hidePoint(p: Point) {
points.filter { it.key == p && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun hideAllPointsInOwner(owner: String) {
points.filter { it.key.owner == owner && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun hideAllPointsInLevel(level: Level) {
points.filter { it.key.level == level && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun hideAllPoints() {
points.filter { it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun removePoint(id: String) {
synchronized(points) {
val keys = ArrayList<Point>()
points.filter { it.key.id == id }.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
keys += it.key
}
keys.forEach {
points.remove(it)
}
}
}
override fun removePoint(p: Point) {
synchronized(points) {
val keys = ArrayList<Point>()
points.filter { it.key == p }.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
keys += it.key
}
keys.forEach {
points.remove(it)
}
}
}
override fun removeAllPointsInOwner(owner: String) {
synchronized(points) {
val keys = ArrayList<Point>()
points.filter { it.key.owner == owner }.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
keys += it.key
}
keys.forEach {
points.remove(it)
}
}
}
override fun removeAllPointsInLevel(level: Level) {
synchronized(points) {
val keys = ArrayList<Point>()
points.filter { it.key.level == level && it.value.isVisible() }.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
keys += it.key
}
keys.forEach {
points.remove(it)
}
}
}
override fun removeAllPoints() {
synchronized(points){
points.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
}
points.clear()
}
}
override fun showAllPoints() {
points.filter { !it.value.isVisible() }.onEach {
it.value.setVisible(true)
}
}
override fun showAllPointsInOwner(owner: String) {
points.filter { it.key.owner == owner && !it.value.isVisible() }.onEach {
it.value.setVisible(true)
}
}
override fun showAllPointsInLevel(level: Level) {
points.filter { it.key.level == level && !it.value.isVisible() }.onEach {
it.value.setVisible(true)
}
}
override fun showPoint(id: String) {
points.filter { it.key.id == id && !it.value.isVisible() }.onEach {
it.value.setVisible(true)
}
}
override fun showOrUpdateLine(options: Polyline.Options): Polyline? {
synchronized(lines) {
val key = Polyline(options.id, options.owner, options.level, options)
var line = lines[key]
try {
if (line != null) {
line.setOptions(options)
return key
} else {
val newLine = MogoMap.getInstance().mogoMap.addLine(options)
if (newLine != null) {
newLine.onRemove { removed ->
val keys = lines.filterKeys { it.id == removed }
if (keys.isNotEmpty()) {
keys.forEach {
lines.remove(it.key)
}
}
}
lines[key] = newLine
line = newLine
return key
}
}
} finally {
line?.also {
it.setToTop()
key.delegate = it
}
}
return null
}
}
private fun moveToCenter(id: String, eventLon: Double, eventLat: Double, carLon: Double, carLat: Double) {
try {
CallerMapUIServiceManager.getMapUIController()?.showBounds(
id,
MogoLatLng(carLat, carLon),
listOf(MogoLatLng(eventLat, eventLon)),
Rect(
WindowUtils.dip2px(Utils.getApp(), 100f),
WindowUtils.dip2px(Utils.getApp(), 370f),
WindowUtils.dip2px(Utils.getApp(), 575f),
WindowUtils.dip2px(Utils.getApp(), 100f)
), true)
} catch (t: Throwable) {
t.printStackTrace()
}
}
override fun hideLine(id: String) {
lines.filter { it.key.id == id && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun hideLine(p: Polyline) {
lines.filter { it.key == p && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun hideAllLinesInOwner(owner: String) {
lines.filter { it.key.owner == owner && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun hideAllLinesInLevel(level: Level) {
lines.filter { it.key.level == level && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun hideAllLines() {
lines.filter { it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun removeLine(id: String) {
synchronized(lines) {
val keys = ArrayList<Polyline>()
lines.filter { it.key.id == id }.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
keys += it.key
}
keys.forEach {
lines.remove(it)
}
}
}
override fun removeLine(p: Polyline) {
synchronized(lines) {
val keys = ArrayList<Polyline>()
lines.filter { it.key == p }.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
keys += it.key
}
keys.forEach {
lines.remove(it)
}
}
}
override fun removeAllLinesInOwner(owner: String) {
synchronized(lines) {
val keys = ArrayList<Polyline>()
lines.filter { it.key.owner == owner }.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
keys += it.key
}
keys.forEach {
lines.remove(it)
}
}
}
override fun removeAllLinesInLevel(level: Level) {
synchronized(lines) {
val keys = ArrayList<Polyline>()
lines.filter { it.key.level == level }.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
keys += it.key
}
keys.forEach {
lines.remove(it)
}
}
}
override fun removeAllLines() {
synchronized(lines) {
lines.onEach {
try {
it.value.remove()
} catch (t: Throwable) {
t.printStackTrace()
}
try {
it.value.destroy()
} catch (t: Throwable) {
t.printStackTrace()
}
}
lines.clear()
}
}
override fun showAllLines() {
lines.filter { !it.value.isVisible() }.onEach {
it.value.setVisible(true)
}
}
override fun showAllLinesInOwner(owner: String) {
lines.filter { !it.value.isVisible() && it.key.owner == owner }.onEach {
it.value.setVisible(true)
}
}
override fun showAllLinesInLevel(level: Level) {
lines.filter { !it.value.isVisible() && it.key.level == level }.onEach {
it.value.setVisible(true)
}
}
override fun showLine(id: String) {
lines.filter { it.key.id == id && !it.value.isVisible() }.onEach {
it.value.setVisible(true)
}
}
override fun hideAllPointsExceptIds(vararg ids: String) {
points.filter { !ids.contains(it.key.id) && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
override fun hideAllPointsExceptOwners(vararg owners: String) {
points.filter { !owners.contains(it.key.owner) && it.value.isVisible() }.onEach {
it.value.setVisible(false)
}
}
}

View File

@@ -0,0 +1,76 @@
package com.mogo.map.overlay.wrapper.line
import com.mogo.map.overlay.line.Polyline.Options
import com.mogo.map.overlay.proxy.line.*
import com.mogo.map.utils.ObjectUtils
import com.zhidaoauto.map.sdk.open.poyline.*
import java.util.concurrent.atomic.*
class AMapPolylineWrapper(private val id: String, private val delegate: Polyline): IMapPolylineOverlay {
private val isDestroyed by lazy { AtomicBoolean(false) }
private val isRemoved by lazy { AtomicBoolean(false) }
@Volatile
private var onRemoveAction: ((id: String) -> Unit)? = null
override fun destroy() {
if (isDestroyed.compareAndSet(false, true)) {
try {
delegate.destroy()
} finally {
onRemoveAction?.invoke(id)
}
}
}
override fun remove() {
if (isRemoved.compareAndSet(false, true)) {
try {
delegate.remove()
} finally {
onRemoveAction?.invoke(id)
}
}
}
override fun setVisible(visible: Boolean) {
if (isDestroyed.get() || isRemoved.get()) {
return
}
delegate.setVisible(visible)
}
override fun isDestroyed(): Boolean {
return isDestroyed.get()
}
override fun isVisible(): Boolean {
return delegate.isVisible() ?: false
}
override fun setToTop() {
//没有对应的API
}
override fun setUnTop() {
//没有对应的API
}
override fun setOptions(options: Options) {
if (isDestroyed.get() || isRemoved.get()) {
return
}
delegate.also {
val option = ObjectUtils.fromMogo(options)
if (option != null) {
it.setOption(option)
}
}
}
override fun onRemove(action: (id: String) -> Unit) {
onRemoveAction = action
}
}

View File

@@ -0,0 +1,84 @@
package com.mogo.map.overlay.wrapper.point
import com.mogo.eagle.core.data.map.*
import com.mogo.map.overlay.point.Point.Options
import com.mogo.map.overlay.proxy.point.*
import com.mogo.map.utils.ObjectUtils
import com.zhidaoauto.map.sdk.open.marker.*
import com.zhidaoauto.map.sdk.open.query.LonLatPoint
import java.util.concurrent.atomic.AtomicBoolean
class AMapPointWrapper(private val id: String, private val delegate: Marker): IMapPointOverlay {
private val isDestroyed by lazy { AtomicBoolean(false) }
private val isRemoved by lazy { AtomicBoolean(false) }
@Volatile
private var onRemoveAction: ((id: String) -> Unit)? = null
override fun destroy() {
if (isDestroyed.compareAndSet(false, true)) {
try {
delegate.destroy()
} finally {
onRemoveAction?.invoke(id)
}
}
}
override fun remove() {
if (isRemoved.compareAndSet(false, true)) {
try {
delegate.remove()
} finally {
onRemoveAction?.invoke(id)
}
}
}
override fun setVisible(visible: Boolean) {
if (isDestroyed.get() || isRemoved.get()) {
return
}
delegate.setVisible(visible)
}
override fun isDestroyed(): Boolean {
return isDestroyed.get()
}
override fun isVisible(): Boolean {
return delegate.isVisible()
}
override fun setToTop() {
if (isDestroyed.get() || isRemoved.get()) {
return
}
delegate.setToTop()
}
override fun setUnTop() {
if (isDestroyed.get() || isRemoved.get()) {
return
}
delegate.setUnTop()
}
override fun setOptions(opt: Options) {
if (isDestroyed.get() || isRemoved.get()) {
return
}
delegate.setMarkerOptions(ObjectUtils.fromMogo(opt))
}
override fun addDynamicAnchorPosition(point: MogoLatLng, angle: Float, duration: Long) {
delegate.addDynamicAnchorPostion(LonLatPoint(point.lon, point.lat, angle.toDouble()), System.currentTimeMillis(), duration.toInt())
}
override fun onRemove(action: (id: String) -> Unit) {
onRemoveAction = action
}
}