Google Map 测距标尺
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package mylib.controls
{
import com.google.maps.*;
import com.google.maps.controls.*;
import com.google.maps.interfaces.*;
import com.google.maps.overlays.*;
import com.google.maps.services.*;
import com.google.maps.styles.*;
import flash.display.Loader;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.text.TextField;
import mx.controls.*;
import mx.events.*;
public class Ruler extends ControlBase {
private var RESET_BUTTON_TITLE:String = "清除所有测距标记";
private var ENABLE_BUTTON_TITLE:String = "添加测距标记已启用,单击这里禁用";
private var DISABLE_BUTTON_TITLE:String = "添加测距标记已禁用,单击这里启用";
private var DELETE_BUTTON_TITLE:String = "删除当前选中的标记";
private var RESET_BUTTON_IMAGE:String = "images/ruler_clear.png";
private var ENABLE_BUTTON_IMAGE:String = "images/ruler_enabled.png";
private var DISABLE_BUTTON_IMAGE:String = "images/ruler_disabled.png";
private var DELETE_BUTTON_IMAGE:String = "images/ruler_delete.png";
private var enabled_:Boolean=true;
private var map_:com.google.maps.Map;
///////////////
private var btnEnable:Button;
private var btnDisable:Button;
private var btnReset:Button;
private var btnDelete:Button;
private var lblLatLng:TextField;
private var lblInfo:TextField;
///////////
//节点列表。包含Marker和Polyline。总是指向最后一个Marker!
private var lstNode:DoubleNode=null;
public function Ruler(map:com.google.maps.Map)
{
map_=map;
super(new ControlPosition(ControlPosition.ANCHOR_TOP_RIGHT, 200, 50));
}
public override function initControlWithMap(map:IMap):void
{
CreateButton();
//map_.addEventListener(MapMouseEvent.MOUSE_MOVE, onMapMouseMove);
//map_.addEventListener(MapMouseEvent.CLICK, onMapClick);
}
//创建操作界面
private function CreateButton():void
{
//this.blendMode=BlendMode.DARKEN;
//启用按钮
btnEnable=new Button();
var Background:Loader = new Loader();
var url:URLRequest = new URLRequest(ENABLE_BUTTON_IMAGE);
Background.load(url);
btnEnable.addChild(Background);
btnEnable.x=0;
btnEnable.visible=false;
btnEnable.addEventListener(MouseEvent.CLICK, btnEnableClick);
btnEnable.toolTip=ENABLE_BUTTON_TITLE;
addChild(btnEnable);
//禁用按钮
btnDisable=new Button();
Background = new Loader();
url = new URLRequest(DISABLE_BUTTON_IMAGE);
Background.load(url);
btnDisable.addChild(Background);
btnDisable.addEventListener(MouseEvent.CLICK, btnDisableClick);
btnDisable.x=0;
btnDisable.visible=true;
btnDisable.toolTip=DISABLE_BUTTON_TITLE;
addChild(btnDisable);
//重置按钮
btnReset=new Button();
Background = new Loader();
url = new URLRequest(RESET_BUTTON_IMAGE);
Background.load(url);
btnReset.addChild(Background);
btnReset.addEventListener(MouseEvent.CLICK, btnResetClick);
btnReset.x=20;
btnReset.toolTip=RESET_BUTTON_TITLE;
addChild(btnReset);
//删除按钮
btnDelete=new Button();
Background = new Loader();
url = new URLRequest(DELETE_BUTTON_IMAGE);
Background.load(url);
btnDelete.addChild(Background);
btnDelete.addEventListener(MouseEvent.CLICK, btnDeleteClick);
btnDelete.x=40;
btnDelete.toolTip=DELETE_BUTTON_TITLE;
addChild(btnDelete);
//坐标信息
lblLatLng=new TextField();
lblLatLng.height=50;
lblLatLng.width=200;
lblLatLng.htmlText="<font face='宋体' size='14' color='#FF0000'>纬度:<b>"+0+" </b>经度:<b>"+0+" </b></font>";
lblLatLng.x=0;
lblLatLng.y=20;
addChild(lblLatLng);
//距离信息
lblInfo=new TextField();
lblInfo.height=50;
lblInfo.width=200;
lblInfo.htmlText="<font face='宋体' size='14' color='#FF0000'>距离:<b>"+0+"</b> 公里</font>";
lblInfo.x=0;
lblInfo.y=40;
addChild(lblInfo);
}
private function btnEnableClick(evt:MouseEvent):void {
setEnabled(true);
}
private function btnDisableClick(evt:MouseEvent):void {
setEnabled(false);
}
public function setEnabled(value:Boolean):void
{
if (value == enabled_)
return;
if(false==value)
{
btnEnable.visible=true;
btnDisable.visible=false;
map_.removeEventListener(MapMouseEvent.MOUSE_MOVE, onMapMouseMove);
map_.removeEventListener(MapMouseEvent.CLICK, onMapClick);
lblLatLng.text="";
lblInfo.text="";
}
else if(true==value)
{
btnEnable.visible=false;
btnDisable.visible=true;
map_.addEventListener(MapMouseEvent.MOUSE_MOVE, onMapMouseMove);
map_.addEventListener(MapMouseEvent.CLICK, onMapClick);
}
enabled_ = value;
}
private function isEnabled():Boolean
{
return enabled_;
}
public function getList():DoubleNode
{
return lstNode;
}
//地图上鼠标单击
private function onMapClick(event:MapMouseEvent):void
{
if(!isEnabled()) return;
var _marker:Marker=CreateMarker(event);
if(lstNode==null)
{
lstNode=new DoubleNode(_marker,"marker");
}
else
{
var _nodeMarker:DoubleNode=new DoubleNode(_marker,"marker");
lstNode.addAfter(_nodeMarker);
lstNode=_nodeMarker;
var _line:Polyline=CreateLine();
var _nodeLine:DoubleNode=new DoubleNode(_line,"polyline");
lstNode.addBefore(_nodeLine);
UpdateDistance();
}
}
private function CreateMarker(event:MapMouseEvent):Marker
{
//创建标记
var markerOptions:MarkerOptions = new MarkerOptions({draggable:true});
var imgs:Image=new Image();
imgs.source=DISABLE_BUTTON_IMAGE; //图片换成本地有的图片
imgs.alpha=0.90;//透明度
markerOptions.icon =imgs;
markerOptions.iconAlignment =MarkerOptions.ALIGN_LEFT|MarkerOptions.ALIGN_TOP;
var marker:Marker = new Marker( event.latLng, markerOptions);
//打开信息窗口
marker.addEventListener(MapMouseEvent.CLICK, function():void{markerShowInfo(marker);});
//拖曳标记
marker.addEventListener(MapMouseEvent.DRAG_END,function():void{
marker.closeInfoWindow();
DragNode(marker);
UpdateDistance();
});
map_.addOverlay(marker);
return marker;
}
private function CreateLine():Polyline
{
if(lstNode==null) return null;
var point_line:Array = new Array();
var prev_marker:Marker=lstNode.get_prev().get_nodeData();
point_line.push(prev_marker.getLatLng());
var marker:Marker=lstNode.get_nodeData();
point_line.push(marker.getLatLng());
var polyline:Polyline = new Polyline(
point_line,
new PolylineOptions({ strokeStyle: new StrokeStyle({
color: 0xFF0000,
thickness: 4,
alpha: 0.7})
}));
map_.addOverlay(polyline);
return polyline;
}
//打开信息窗口事件
private function markerShowInfo(marker:Marker):void
{
//切换标记
var markerOptions:MarkerOptions = new MarkerOptions({draggable:true});
var imgs:Image=new Image();
imgs.source=ENABLE_BUTTON_IMAGE; //图片换成本地有的图片
imgs.alpha=0.90;//透明度
markerOptions.icon =imgs;
markerOptions.iconAlignment =MarkerOptions.ALIGN_LEFT|MarkerOptions.ALIGN_TOP;
marker.setOptions(markerOptions);
UpdateSelectedStatus(marker);
//显示信息
////////////////先解析地址
var geocoder:ClientGeocoder = new ClientGeocoder();
geocoder.addEventListener( GeocodingEvent.GEOCODING_SUCCESS,function(event:GeocodingEvent):void
{
var placemarks:Array = event.response.placemarks;
if (placemarks.length > 0)
{
markerShowInfoWithAddress(marker,placemarks[0].address);
}
});
geocoder.addEventListener( GeocodingEvent.GEOCODING_FAILURE, function(event:GeocodingEvent):void {});
geocoder.reverseGeocode(marker.getLatLng());
}
private function markerShowInfoWithAddress(marker:Marker,location:String):void
{
//var htmlTitle:String= "<p align=\"left\"><b><font color=\"#00FFFF\" size=\"14\" face=\"Verdana, Arial, Helvetica, sans-serif\"><br> 车载监控系统<br></font></b></p>";
var htmlContent:String= "<font size=\"12\" face=\"Verdana, Arial, Helvetica, sans-serif\">"
// + "<hr color=\"#ff8000\" width=\"240\">"
+ "<br><font color=\"#0000FF\"><b> 纬度:</b></font><font color=\"#FF0000\">" + marker.getLatLng().lat().toFixed(2)
+ "</font><font color=\"#0000FF\"><b> 经度:</b></font><font color=\"#FF0000\">" + marker.getLatLng().lng().toFixed(2)
+ "</font><br><font color=\"#0000FF\"><b> 位置:</b></font><font color=\"#FF0000\">" + location
+ "</font>";
marker.openInfoWindow(new InfoWindowOptions(
{
width:300,
strokeStyle:
{
color: 0x000000
},
//customOffset :new Point(0,-50),
fillStyle:
{
color: 0xFFFFFF,
alpha: 0.7
},
hasCloseButton: true,
//titleFormat: titleFormat,
//titleStyleSheet: titleStyleSheet,
//contentFormat: textFormat,
//contentStyleSheet: contentStyleSheet,
//titleHTML: htmlTitle,
contentHTML: htmlContent
//customContent:mybutton;只显示一个按钮
}));
}
private function onMapMouseMove(event:MapMouseEvent):void
{
if(!isEnabled()) return;
lblLatLng.htmlText="<font face='宋体' size='14' color='#FF0000'>纬度:<b>"+event.latLng.lat().toFixed(2)+" </b>经度:<b>"+event.latLng.lng().toFixed(2)+" </b></font>";
}
private function UpdateDistance():void
{
var len:Number=0;
var _prevNode:DoubleNode=null;
//默认lstNode是最后一个节点
for(var _node:DoubleNode=lstNode;_node!=null;_node=_node.get_prev())
{
if(_node.get_nodeType()=="marker" )
{
if(_prevNode==null)
{
_prevNode=_node;
continue;
}
var _data:Marker=_node.get_nodeData();
var _prev_data:Marker=_prevNode.get_nodeData();
len+=_data.getLatLng().distanceFrom(_prev_data.getLatLng());
_prevNode=_node;
}
}
lblInfo.htmlText="<font face='宋体' size='14' color='#FF0000'>距离:<b>"+(len/1000).toFixed(2)+"</b> 公里</font>";
}
private function btnResetClick(event:MouseEvent):void
{
onReset();
}
public function onReset():void
{
for(var _node:DoubleNode=lstNode;_node!=null;_node=_node.get_prev())
{
map_.removeOverlay(_node.get_nodeData());
}
lstNode=null;
lblInfo.text="";
}
private function DragNode(marker:Marker):void
{
for(var _node:DoubleNode=lstNode;_node!=null;_node=_node.get_prev())
{
if(_node.get_nodeType()=="marker")
{
var m:Marker=_node.get_nodeData();
if(m==marker)
{
//Alert.show("find!");
var prev_node:DoubleNode=_node.get_prev();//polyline
var next_node:DoubleNode=_node.get_next();//polyline
if(prev_node!=null)
{
var prev_prev_node:DoubleNode=prev_node.get_prev();//marker
var prev_marker:Marker=prev_prev_node.get_nodeData();
//添加前驱polyline
var point_line1:Array = new Array();
point_line1.push(prev_marker.getLatLng());
point_line1.push(m.getLatLng());
var polyline1:Polyline = new Polyline(
point_line1,
new PolylineOptions({ strokeStyle: new StrokeStyle({
color: 0xFF0000,
thickness: 4,
alpha: 0.7})
}));
map_.addOverlay(polyline1);
//删除前驱polyline
map_.removeOverlay(prev_node.get_nodeData());
//添加前驱节点
var new_prev_node:DoubleNode=new DoubleNode(polyline1,"polyline");
//删除前驱节点
prev_node.unlink();
_node.addBefore(new_prev_node);
}
//更新后驱节点
if(next_node!=null)
{
var next_next_node:DoubleNode=next_node.get_next();//marker
var next_marker:Marker=next_next_node.get_nodeData();
//添加后驱节点:Polyline
var point_line2:Array = new Array();
point_line2.push(m.getLatLng());
point_line2.push(next_marker.getLatLng());
var polyline2:Polyline = new Polyline(
point_line2,
new PolylineOptions({ strokeStyle: new StrokeStyle({
color: 0xFF0000,
thickness: 4,
alpha: 0.7})
}));
map_.addOverlay(polyline2);
//删除后驱节点:Polyline
map_.removeOverlay(next_node.get_nodeData());
//添加后驱节点
var new_next_node:DoubleNode=new DoubleNode(polyline2,"polyline");
//删除后驱节点
next_node.unlink();
_node.addAfter(new_next_node);
}
return;
}
}
}
}
private function UpdateSelectedStatus(markerSelected:Marker):void
{
for(var _node:DoubleNode=lstNode;_node!=null;_node=_node.get_prev())
{
if(_node.get_nodeType()=="marker")
{
var _marker:Marker=_node.get_nodeData();
if(_marker==markerSelected)
{
_node.set_nodeStatus(true);
}
else if(_node.get_nodeStatus()==true)
{
_node.set_nodeStatus(false);
//切换图片
var markerOptions:MarkerOptions = new MarkerOptions({draggable:true});
var imgs:Image=new Image();
imgs.source=DISABLE_BUTTON_IMAGE; //图片换成本地有的图片
imgs.alpha=0.90;//透明度
markerOptions.icon =imgs;
markerOptions.iconAlignment =MarkerOptions.ALIGN_LEFT|MarkerOptions.ALIGN_TOP;
_marker.setOptions(markerOptions);
}
}
}
}
private function GetSelectedNode():DoubleNode
{
for(var _node:DoubleNode=lstNode;_node!=null;_node=_node.get_prev())
{
if(_node.get_nodeType()=="marker" && _node.get_nodeStatus()==true)
{
return _node;
}
}
return null;
}
private function btnDeleteClick(event:MouseEvent):void
{
var nodeSelected:DoubleNode=GetSelectedNode();
if(nodeSelected!=null)
{
map_.closeInfoWindow();
DeleteNode(nodeSelected);
UpdateDistance();
}
}
private function DeleteNode(nodeDel:DoubleNode):void
{
var markerDel:Marker=nodeDel.get_nodeData();
map_.removeOverlay(markerDel);
/////
var prev_node:DoubleNode=nodeDel.get_prev();//polyline
var next_node:DoubleNode=nodeDel.get_next();//polyline
//删除的是头节点
if(prev_node==null && next_node!=null)
{
map_.removeOverlay(next_node.get_nodeData());
nodeDel.unlink();
next_node.unlink();
return;
}
//删除的是尾节点
else if(prev_node!=null && next_node==null)
{
lstNode=prev_node.get_prev();//marker
map_.removeOverlay(prev_node.get_nodeData());
nodeDel.unlink();
prev_node.unlink();
return;
}
//删除的是中间节点
else if(prev_node!=null && next_node!=null)
{
var prev_prev_node:DoubleNode=prev_node.get_prev();//marker
var prev_marker:Marker=prev_prev_node.get_nodeData();
var next_next_node:DoubleNode=next_node.get_next();//marker
var next_marker:Marker=next_next_node.get_nodeData();
map_.removeOverlay(prev_node.get_nodeData());
map_.removeOverlay(next_node.get_nodeData());
prev_prev_node.set_next(next_next_node);
next_next_node.set_prev(prev_prev_node);
//添加前驱polyline
var point_line:Array = new Array();
point_line.push(prev_marker.getLatLng());
point_line.push(next_marker.getLatLng());
var polyline:Polyline = new Polyline(
point_line,
new PolylineOptions({ strokeStyle: new StrokeStyle({
color: 0xFF0000,
thickness: 4,
alpha: 0.7})
}));
map_.addOverlay(polyline);
//添加前驱节点
var new_prev_node:DoubleNode=new DoubleNode(polyline,"polyline");
next_next_node.addBefore(new_prev_node);
}
else if(prev_node==null && next_node==null)
{
lstNode=null;
}
}
}
}
使用方法:
import mylib.controls.*;
private var m_ruler:Ruler=new Ruler(map);
m_ruler.setEnabled(true);
m_ruler.visible=true;