可能按自已在googlemap上的起始点进行在线修改,可以用于公交线路的展示,客运线路的显示
代码如下
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Edit</title>
<style type="text/css">
body{font-family: Arial; font-size: small; background-color: #ccf;}
#outline {margin:20px; border:solid 10px #9FB6CD; -moz-border-radius:20px; width:512px; height:440px;}
#map{width:512px; height:440px;float:left;}
#forehead{text-align:left;font-size:150%;}
#novel{width:400px; margin:20px;float:right;}
#AdSense{margin:20px;}
A:hover {color: red;text-decoration: underline overline;}
td{vertical-align:top;}
.draggable-popup input{background-color:#ccf}
.draggable-popup{background-color:white; border:1px solid black}
</style>
<script
src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAYxpy0HiKBWXiyhVrpVqkshTzRM_GTxWOqTaXXRScn8KwUCiJWhT96ZS2MOLTq-SEmmJL1_cNrib9tA" type="text/javascript">
</script>
</head>
<body οnunlοad="GUnload()">
<table><tr><td>
<div id="forehead"><h3 id="head">
Esa's Google Maps API experiments.</h3>
</div></td>
<td rowspan="2">
<div id="novel">
<h4>Polyline editor with CSV output</h4>
<p>Api v2.111 gave us a nifty option to edit GPolylines MyMaps way.</p>
Search your start location:
<div class="inputsection">
<form action="#" οnsubmit="showAddress(this.haku.value,this.haku.id); return false">
<input type="text" size="30" id="haku" name="haku" title="Placename or address"/>
<input type="submit" id="hae" value=" >> " title="Set zoom first"/>
</form>
<form action="#" οnsubmit="getDirections(); return false">
<input type="text" size="30" id="dest" name="dest" title="Destination address"/>
<input type="submit" id="directions" value=" >> " title="Driving directions"/>
</form>
</div>
<h4>Draggable Context Menu</h4>
<p>'singlerightclick' opens a popup menu that is a GDraggableObject</p>
<h4>CSV vertex list </h4>
<p><abbr title="Comma Separated Values">CSV</abbr> formatted text files have been used for placing markers but why not for polylines too.</p>
<p>The format <code>lng,lat</code> (longitude first) comes from GPS equipment csv 'standards'.</p>
<p><span id="vertices"></span>The text field updates by map 'dblclick'.
<p><input type="checkbox" checked="true" id="update" title="Uncheck to keep text field as a backup"> update by 'lineupdated' too.
<p><a href="javascript:$('memo').select()">select all</a> and copy/paste where it belongs.
</p>
<textarea id="memo" cols="40" rows="15" title="Memo"></textarea>
<input type="button" value="Draw from text field" οnclick="drawFromText()" />
<p>When you came back later to edit a file you created earlier:</p>
<p>Paste your file to the text field and click [Draw from text field]</p>
<p>Rightclick on map and select [Go on editing]</p>
<p>A comment to be dragged on text field:
<input type="text" size="3" value=" <!-- -->" οnmοuseοver="this.select()"
οnmοuseοut="this.value=' <!-- -->'"/></p>
<p><a href="http://koti.mbnet.fi/ojalesa/exam/index.html" target="_blank">Experiment index</a></p>
</div>
</td>
</tr>
<tr>
<td>
<div id="outline">
<div id="map">Map coming...
<noscript>You should turn on JavaScript</noscript>
</div>
</div>
<div id="AdSense">
<script type="text/javascript"><!--
google_ad_client = "pub-3649938975494252";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text_image";
google_ad_channel ="2676021345";
google_color_border = "CCCCFF";
google_color_bg = "CCCCFF";
google_color_link = "0000CC";
google_color_url = "008000";
google_color_text = "000000";
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</td>
</tr>
</table>
<script type="text/javascript">
//<![CDATA[
///Esa May 2008, updated Oct 2008
if (!GBrowserIsCompatible()) {
alert('Sorry. Your browser is not Google Maps compatible.');
}
/**
* A general helper function
* $() replaces document.getElementById()
*/
if(typeof($)=='undefined'){
function $(elementId){
var element = document.getElementById(elementId);
return element;
}
}
/**
* map with GDirections
* pointer marker
*/
_mPreferMetric=true;
var map = new GMap2($("map"));
var start = new GLatLng(65,26);
map.setCenter(start, 5);
map.addControl(new GLargeMapControl());
map.addControl(new GScaleControl(250));
map.addControl(new GMapTypeControl(1));
map.disableDoubleClickZoom();
map.openInfoWindowHtml(map.getCenter(),"Nice to see you.");
map.closeInfoWindow; //preload module;
gdir = new GDirections();
GEvent.addListener(gdir, "load", drawRoute);
GEvent.addListener(gdir, "error", errorReport);
/**
* A general helper function for creating html elements. <div> as default element type
* @author Esa 2008
*/
function createElem(opt_className, opt_html, opt_tagName) {
var tag = opt_tagName||"div";
var elem = document.createElement(tag);
if (opt_html) elem.innerHTML = opt_html;
if (opt_className) elem.className = opt_className;
return elem;
}
/**
* draggable popup
* @author Esa 2008
*/
function draggablePopup(contents, opt_options){
var opts = opt_options||{};
var popup = createElem("draggable-popup");
popup.style.width = opts.width||"240px";
popup.style.top = opts.top||"240px";
popup.style.left = opts.left||"240px";
popup.style.padding = opts.padding||"10px";
popup.style.paddingTop = "0px";
popup.style.visibility = "hidden";
var me = this;
popup.onmouseover = function(){GEvent.trigger(me,'mouseover')};
popup.onmouseout = function(){GEvent.trigger(me,'mouseout')};
var header = createElem("draggable-popup-header");
header.style.textAlign = "right";
var closetext = opts.closeText||"Close[x]";
var close = createElem("draggable-popup-close",closetext,"a");
close.onclick = function(){popup.style.visibility = "hidden"};
header.appendChild(close);
var popupContents = createElem("draggable-popup-contents",contents);
popup.appendChild(header);
popup.appendChild(popupContents);
document.getElementsByTagName("body")[0].appendChild(popup);
this.dragObject = new GDraggableObject(popup);
this.popup = popup;
this.show = function(){popup.style.visibility = "visible"};
this.hide = function(){popup.style.visibility = "hidden"};
}
var html = '<p><input type="button" value="End editing"'
+ 'οnclick="poly.disableEditing(); map.closeInfoWindow();" />'
+ '<input type="button" value="Go on editing"'
+ 'οnclick="poly.enableEditing();map.closeInfoWindow();" /></p>'
+ '<p><input type="button" value="Delete first" οnclick="poly.deleteVertex(0)" />'
+ '<input type="button" value="Delete last"'
+ 'οnclick="try{poly.deleteVertex(poly.getVertexCount()-1)}catch(e){}" />'
+ '<input type="button" value="Delete node:" οnclick="deleteNode()" />'
+ '<select id="vertex-select" οnchange="showNode(this.selectedIndex)"></select></p>'
+ '<p><input type="button" value="New rectangle" οnclick="rectPoly()" />'
+ '<br/><input type="button" value="New polyline from scratch" οnclick="drawPoly()" /></p>'
+ '<p><input type="text" id="km" size="1" value="1" οnmοuseοver="this.focus()"/>km'
+ '<input type="button" value="New circle" οnclick="drawCircle()"/></p>';
var context = new draggablePopup(html);
GEvent.addListener(map, "singlerightclick", function(){
context.show();
}); //these are needed to keep draggable popup stable when using selector
GEvent.addDomListener($('vertex-select'), "mouseover", function(){
context.dragObject.disable();
});
GEvent.addDomListener($('vertex-select'), "mouseout", function(){
context.dragObject.enable();
});
/**
* Selector options handling
*/
var selector = $('vertex-select');
function addOption(value){
var len = selector.options.length;
selector.options[len] = new Option(value);
}
function clearSelector(){
while(selector.options[0]){
selector.options[0] = null;
}
}
function deleteNode(){
poly.deleteVertex(selector.selectedIndex);
}
function showBlowup(){
var sel_ = selector.selectedIndex||0;
try{map.showMapBlowup(poly.getVertex(sel_))}catch(e){};
}
function showNode(index_){
map.setCenter(poly.getVertex(index_));
showBlowup();
}
/**
* GLatLngBounds.drawBox() method
* Returns a GPolyline or GPolygon rectangle representing the bounds
* optional parameter is an object with style properties {liColor, liWidth, liOpa, fillColor, fillOpa, polygon}
* {polygon:true} switches the return object from GPolyline to GPolygon
* @author Esa 2007
*/
GLatLngBounds.prototype.drawBox = function(opt_options){
var opts = opt_options||{};
var northEast = this.getNorthEast();
var southWest = this.getSouthWest();
var topLat = northEast.lat();
var rightLng = northEast.lng();
var botLat = southWest.lat();
var leftLng = southWest.lng();
var pnts = [];
pnts.push(southWest);
pnts.push(new GLatLng(topLat,leftLng));
pnts.push(northEast);
pnts.push(new GLatLng(botLat,rightLng));
pnts.push(southWest);
var fillColor = opts.fillColor||opts.liColor||"#0055ff";
var liWidth = opts.liWidth||2;
if(opts.polygon){
var boxPoly = new GPolygon(pnts,opts.liColor,liWidth,opts.liOpa,fillColor,opts.fillOpa);
}else{
var boxPoly = new GPolyline(pnts,opts.liColor,liWidth,opts.liOpa);
}
return boxPoly;
}
/**
* GLatLng.drawKmCircle() method
* Returns a GPolyline or GPolygon rectangle representing
* optional parameter is an object with radius, quality and style properties {radius, nodes, liColor, liWidth, liOpa, fillColor, fillOpa, polygon}
* {polygon:true} switches the return object from GPolyline to GPolygon
* @author Esa 2006, 2008
*/
GLatLng.prototype.drawKmCircle =function (opt_options){
var pnts = [];
var opts = opt_options||{};
var radius = 1*opts.radius||1;
var step = parseInt(360/opts.nodes)||18;
var latConv = this.distanceFrom(new GLatLng(this.lat()+0.1, this.lng()))/100;
var lngConv = this.distanceFrom(new GLatLng(this.lat(), this.lng()+0.1))/100;
for(var i=0; i<=360; i+=step)
{ // @author Esa 2006, 2008
var pint = new GLatLng(this.lat() + (radius/latConv * Math.cos(i * Math.PI/180)),
this.lng() + (radius/lngConv * Math.sin(i * Math.PI/180)));
pnts.push(pint);
}
var fillColor = opts.fillColor||opts.liColor||"#0055ff";
var liWidth = opts.liWidth||2;
if(opts.polygon){
var poly = new GPolygon(pnts,opts.liColor,liWidth,opts.liOpa,fillColor,opts.fillOpa);
}else{
var poly = new GPolyline(pnts,opts.liColor,liWidth,opts.liOpa);
}
return poly;
}
/**
* Context menu button functions
*/
var poly = null;
var updateListener;
function rectPoly(){
map.clearOverlays();
updateListener = null;
map.zoomIn();
poly = map.getBounds().drawBox();
map.addOverlay(poly);
map.zoomOut();
poly.enableEditing();
setListener(poly);
listPoly();
}
function drawPoly(){
map.clearOverlays();
updateListener = null;
poly = new GPolyline([],"blue",2);
map.addOverlay(poly);
poly.enableDrawing();
setListener(poly);
}
function drawCircle(){
var km = $("km").value;
map.clearOverlays();
updateListener = null;
poly = map.getCenter().drawKmCircle({radius:km, polygon: true});
map.addOverlay(poly);
poly.enableEditing();
setListener(poly);
map.fit(poly.getBounds(), true);
listPoly();
}
function getDirections(){
var saddr = $("haku").value;
var daddr = $("dest").value;
gdir.load("from: " + saddr + " to: " + daddr,{getPolyline:true});
}
function drawRoute(){
map.clearOverlays();
updateListener = null;
poly = gdir.getPolyline();
var vert = poly.getVertexCount();
var permission = true;
if(vert>100) permission = confirm(vert + " points are not editable but I can draw it.");
if(!permission)return;
if(vert>1000) permission = confirm(vert + " points is much. Are you really serious?");
if(!permission)return;
if(vert>10000) permission = confirm(vert + " points. This is your last change. Proceed?");
if(permission){
map.addOverlay(poly);
setListener(poly);
map.fit(poly.getBounds(), true);
listPoly();
}
}
/**
* Draw a polyline from textarea data
*/
function drawFromText(){
map.clearOverlays();
updateListener = null;
var polyPoints = $("memo").value.parseCsv();
poly = new GPolyline(polyPoints,"red",2);
map.addOverlay(poly);
var bounds = poly.getBounds();
if(bounds)map.fit(bounds, true);
setListener(poly);
}
/**
* Update textarea by polyline 'lineupdated' and map 'dblclick'
*/
function setListener(obj){
updateListener = GEvent.addListener(obj, "lineupdated", function(){
if($("update").checked) listPoly();
});
GEvent.addListener(map, "dblclick", function(){
listPoly();
});
}
function listPoly(){
clearSelector();
var rows = [];
$("memo").value = "";
if(poly){
var len = poly.getVertexCount()||0;
for(var i=0; i<len; i++){
var point = poly.getVertex(i);
rows.push(point.lng().toFixed(6)+", "+point.lat().toFixed(6));
addOption(i);
}
$("memo").value = rows.join('/n');
}
$("vertices").innerHTML = len + " vertices . ";
}
/**
* Geocoder
*/
var geocoder = new GClientGeocoder();
function showAddress(address,id){
geocoder.getLatLng(address,function(point){
if(!point){
$(id).style.color = "#ff0000";
}else{
map.setCenter(point);
rectPoly();
$(id).style.color = "#000000";
$("memo").value = "";
}
})
}
/**
* zoom and pan to fit in view
*/
GMap2.prototype.fit = function(bounds,save){
if(!save){
this.setZoom(map.getBoundsZoomLevel(bounds));
this.panTo(bounds.getCenter());
}else{
this.setCenter(bounds.getCenter(), this.getBoundsZoomLevel(bounds));
this.savePosition();
}
}
/**
* parseCsv()
* @return an array of GLatLng() objects
* @author Esa 2008
*/
String.prototype.parseCsv = function(opt_options){
var results = [];
var opts = opt_options||{};
var iLat = opts.lat||1;
var iLng = opts.lng||0;
var lines = this.split("/n");
for (var i=0; i<lines.length; i++) {
var blocks = lines[i].split('"');
//finding commas inside quotes. Replace them with '::::'
for(var j=0;j<blocks.length;j++){
if(j%2){
blocks[j]=blocks[j].replace(/,/g,'::::');
}
} //@author Esa 2008, keep this note.
lines[i] = blocks.join("");
var lineArray = lines[i].split(",");
var lat = lineArray[iLat]*1;
var lng = lineArray[iLng]*1;
var point = new GLatLng(lat,lng);
//after splitting by commas, we put hidden ones back
for(var cell in lineArray){
lineArray[cell] = lineArray[cell].replace(/::::/g,',');
} //corrupted line step-over
if(!isNaN(lat+lng)){
point.textArray = lineArray;
results.push(point);
}
}
return results;
}
/**
* directions error
*/
function errorReport(){
alert("D'oh");
}
/**
* Draw rectangle on page load
*/
rectPoly();
window.onload = function(){
listPoly();
}
//]]>
</script>
</body>
</html>