此问题与此SO question有关,并由@geocodezip回答。
我遇到的一个问题是从北到南或从南到北画一条线。曲线现在弯曲为数字8或S.如何控制曲线显示在直线的一侧。有时曲线会扩展到起点以外,并在终点处收缩。感谢。
这是我的代码。我有两条样本折线从北到南。
var map;
function init() {
var Map = google.maps.Map,
LatLng = google.maps.LatLng,
LatLngBounds = google.maps.LatLngBounds,
Marker = google.maps.Marker,
Point = google.maps.Point;
var pos1 = new LatLng(29.703642, -95.152274);
var pos2 = new LatLng(29.702452, -95.152296);
var pos3 = new LatLng(29.703514, -95.151405);
var pos4 = new LatLng(29.702359, -95.152078);
var bounds = new LatLngBounds();
bounds.extend(pos1);
bounds.extend(pos2);
var mapOptions = {
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.SATELLITE,
draggableCursor: 'auto',
panControl: true,
scaleControl: true,
smallMapControl: true,
tilt: 0,
zoom: 19,
zoomControl: true,
rotateControl:true,
zoomControlOptions: { style: google.maps.ZoomControlStyle.SMALL }
};
map = new Map(document.getElementById('map-canvas'), mapOptions);
map.fitBounds(bounds);
var markerP1 = new Marker({
position: pos1,
draggable: true,
map: map
});
var markerP2 = new Marker({
position: pos2,
draggable: true,
map: map
});
var markerP2 = new Marker({
position: pos3,
draggable: true,
map: map
});
var markerP3 = new Marker({
position: pos4,
draggable: true,
map: map
});
var curvedLine = new GmapsCubicBezier(pos1, pos2, 0.01, map);
var curvedLine = new GmapsCubicBezier(pos3, pos4, 0.01, map);
var line = new google.maps.Polyline({
path: [pos1, pos2],
strokeOpacity: 0,
icons: [{
icon: {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
},
offset: '0',
repeat: '20px'
}],
map: map
});
var line = new google.maps.Polyline({
path: [pos3, pos4],
strokeOpacity: 0,
icons: [{
icon: {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
},
offset: '0',
repeat: '20px'
}],
map: map
});
}
google.maps.event.addDomListener(window, 'load', init);
var GmapsCubicBezier = function (latlong1, latlong4, resolution, map) {
var lineLength = google.maps.geometry.spherical.computeDistanceBetween(latlong1, latlong4);
var lineHeading = google.maps.geometry.spherical.computeHeading(latlong1, latlong4);
var positionA = google.maps.geometry.spherical.computeOffset(latlong1, lineLength / 3, lineHeading - 60);
var positionB = google.maps.geometry.spherical.computeOffset(latlong4, lineLength / 3, -lineHeading + 120);
var lat1 = latlong1.lat();
var long1 = latlong1.lng();
var lat2 = positionA.lat();
var long2 = positionA.lng();
var lat3 = positionB.lat();
var long3 = positionB.lng();
var lat4 = latlong4.lat();
var long4 = latlong4.lng();
var points = [];
for (it = 0; it <= 1; it += resolution) {
points.push(this.getBezier({
x: lat1,
y: long1
}, {
x: lat2,
y: long2
}, {
x: lat3,
y: long3
}, {
x: lat4,
y: long4
}, it));
}
var path = [];
for (var i = 0; i < points.length - 1; i++) {
path.push(new google.maps.LatLng(points[i].x, points[i].y));
path.push(new google.maps.LatLng(points[i + 1].x, points[i + 1].y, false));
}
var Line = new google.maps.Polyline({
path: path,
geodesic: true,
strokeOpacity: 0.0,
icons: [{
icon: {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
},
offset: '0',
repeat: '20px'
}],
strokeColor: 'grey'
});
Line.setMap(map);
return Line;
};
GmapsCubicBezier.prototype = {
B1: function (t) {
return t * t * t;
},
B2: function (t) {
return 3 * t * t * (1 - t);
},
B3: function (t) {
return 3 * t * (1 - t) * (1 - t);
},
B4: function (t) {
return (1 - t) * (1 - t) * (1 - t);
},
getBezier: function (C1, C2, C3, C4, percent) {
var pos = {};
pos.x = C1.x * this.B1(percent) + C2.x * this.B2(percent) + C3.x * this.B3(percent) + C4.x * this.B4(percent);
pos.y = C1.y * this.B1(percent) + C2.y * this.B2(percent) + C3.y * this.B3(percent) + C4.y * this.B4(percent);
return pos;
}
};
答案 0 :(得分:2)
绘制您正在寻找的Bezier曲线的一般程序是:
function drawDashedCurve(P1, P2, map) {
var lineLength = google.maps.geometry.spherical.computeDistanceBetween(P1, P2);
var lineHeading = google.maps.geometry.spherical.computeHeading(P1, P2);
if (lineHeading < 0) {
var lineHeading1 = lineHeading + 45;
var lineHeading2 = lineHeading + 135;
} else {
var lineHeading1 = lineHeading + -45;
var lineHeading2 = lineHeading + -135;
}
var pA = google.maps.geometry.spherical.computeOffset(P1, lineLength / 2.2, lineHeading1);
var pB = google.maps.geometry.spherical.computeOffset(P2, lineLength / 2.2, lineHeading2);
var curvedLine = new GmapsCubicBezier(P1, pA, pB, P2, 0.01, map);
}
更改角度和距离以计算控制点(pA
,pB
)将改变曲率。
代码段
// draw a dashed curve anchored at P1, P2
function drawDashedCurve(P1, P2, map) {
var lineLength = google.maps.geometry.spherical.computeDistanceBetween(P1, P2);
var lineHeading = google.maps.geometry.spherical.computeHeading(P1, P2);
if (lineHeading < 0) {
var lineHeading1 = lineHeading + 45;
var lineHeading2 = lineHeading + 135;
} else {
var lineHeading1 = lineHeading + -45;
var lineHeading2 = lineHeading + -135;
}
var pA = google.maps.geometry.spherical.computeOffset(P1, lineLength / 2.2, lineHeading1);
var pB = google.maps.geometry.spherical.computeOffset(P2, lineLength / 2.2, lineHeading2);
var curvedLine = new GmapsCubicBezier(P1, pA, pB, P2, 0.01, map);
}
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// generate test points every 10 degrees
for (var angle = 0; angle < 360; angle += 10) {
var p1 = google.maps.geometry.spherical.computeOffset(map.getCenter(), 1000, angle);
var p2 = google.maps.geometry.spherical.computeOffset(map.getCenter(), 2000, angle);
drawDashedCurve(p1, p2, map);
var straightPoly = new google.maps.Polyline({
map: map,
path: [p1, p2],
strokeOpacity: 0.2,
strokeColor: "blue"
});
var markerP1 = new google.maps.Marker({
position: p1,
map: map,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 4,
fillColor: "black",
fillOpacity: 1.0
}
});
var markerP2 = new google.maps.Marker({
position: p2,
map: map,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 4,
fillColor: "black",
fillOpacity: 1.0
}
});
}
}
google.maps.event.addDomListener(window, "load", initialize);
// original Belzier Curve code from nicoabie's answer to this question on StackOverflow:
// http://stackoverflow.com/questions/5347984/letting-users-draw-curved-lines-on-a-google-map
var GmapsCubicBezier = function(latlong1, latlong2, latlong3, latlong4, resolution, map) {
var lat1 = latlong1.lat();
var long1 = latlong1.lng();
var lat2 = latlong2.lat();
var long2 = latlong2.lng();
var lat3 = latlong3.lat();
var long3 = latlong3.lng();
var lat4 = latlong4.lat();
var long4 = latlong4.lng();
var points = [];
for (it = 0; it <= 1; it += resolution) {
points.push(this.getBezier({
x: lat1,
y: long1
}, {
x: lat2,
y: long2
}, {
x: lat3,
y: long3
}, {
x: lat4,
y: long4
}, it));
}
var path = [];
for (var i = 0; i < points.length - 1; i++) {
path.push(new google.maps.LatLng(points[i].x, points[i].y));
path.push(new google.maps.LatLng(points[i + 1].x, points[i + 1].y, false));
}
var Line = new google.maps.Polyline({
path: path,
geodesic: true,
strokeOpacity: 0.0,
icons: [{
icon: {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
},
offset: '0',
repeat: '20px'
}],
strokeColor: 'grey'
});
Line.setMap(map);
return Line;
};
GmapsCubicBezier.prototype = {
B1: function(t) {
return t * t * t;
},
B2: function(t) {
return 3 * t * t * (1 - t);
},
B3: function(t) {
return 3 * t * (1 - t) * (1 - t);
},
B4: function(t) {
return (1 - t) * (1 - t) * (1 - t);
},
getBezier: function(C1, C2, C3, C4, percent) {
var pos = {};
pos.x = C1.x * this.B1(percent) + C2.x * this.B2(percent) + C3.x * this.B3(percent) + C4.x * this.B4(percent);
pos.y = C1.y * this.B1(percent) + C2.y * this.B2(percent) + C3.y * this.B3(percent) + C4.y * this.B4(percent);
return pos;
}
};
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map_canvas"></div>