gpt4 book ai didi

javascript - 使用几何多边形来围住其他多边形

转载 作者:行者123 更新时间:2023-12-03 08:51:02 25 4
gpt4 key购买 nike

一些背景知识。该 map 在每分钟的四分之一处绘制多边形。它们被贴上这样的标签。这似乎运作良好。我正在添加第二个多边形,该多边形可编辑并可拖动到 map 上,用户可以通过展开 gridSelectBox 上的 handle 来选择四分之一分钟,然后单击所选区域的外部。我将四分之一分钟写入数据库。

这可行,但有问题。

有时,仅每隔一个列或行(经度或纬度)被选中,尽管它显然位于选定​​区域中。我只能假设它是某种舍入区域。我确实注意到,完美的度数 X 度顶点 34.00 X -84.00 显示为 34.00000000000001 X -84.00。这可能是问题所在吗?如果是,我该如何纠正?

fiddle

<html>
<head>
<script type ="text/javascript"
src ="https://maps.googleapis.com/maps/api/js?v=3.exp&amp;libraries=geometry&amp;sensor=false"></script>
<title>Find your Qtr minute locator</title>
</head>
<body style="height:100%;margin:0">
<!-- Declare the div, make it take up the full document body -->
<div id="map-canvas" style="width:100%; height: 100%;"></div>

<script type="text/javascript">

var map;

var qtrArray = [];
var Startlatlng = "";
var llOffset =((1/60)/4);

var drawGridSelectBox = false;
var firstRun = true;
var drawGridBox = false;
var gridOverBox = new google.maps.Polygon();
var gridSelectBox = new google.maps.Polygon();

var gridline;
var polylinesquare;
var latPolylines = [];

var latLabels = [];
var latMapLabel;

var lngPolylines = [];

var lngLabels = [];
var lngMapLabel;
var bounds = new google.maps.LatLngBounds();

function initialize() {
map = new google.maps.Map(document.getElementById("map-canvas"), {
center: new google.maps.LatLng(34.0, -84.0),
zoom: 16,
streetViewControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scaleControl: true
});

google.maps.event.addListener(map, "click", function (event) {
if (!google.maps.geometry.poly.containsLocation(event.latLng, gridSelectBox)) {
map.setZoom(16);
createGridSelectBox(event.latLng);
ClearGrid();
for(var x=0;x<latPolylines.length;++x){
for(var y=0;y<lngPolylines.length-1;++y){
var latLng=new google.maps.LatLng(latPolylines[x].getPath().getAt(0).lat(),
lngPolylines[y].getPath().getAt(0).lng());

if ((google.maps.geometry.poly.containsLocation(latLng, gridSelectBox))&&(!firstRun))
{
drawGridBox = true;
createGridBox(latLng);
}
}
}
firstRun = false;
map.panTo(event.latLng);
drawGridBox = false;

}});
DrawGridOn();
google.maps.event.addListener(map, "idle", function () {
createGridLines(map.getBounds());
});
}
google.maps.event.addDomListener(window, "load", initialize);

function DrawGridOn() {
drawGridSelectBox = true;
}

function DrawGridOff() {
drawGridSelectBox = false;
}



function createGridLines(bounds) {
for (var i = 0; i < latPolylines.length; i++) {
latPolylines[i].setMap(null);
}

latPolylines = [];
for (var j = 0; j < lngPolylines.length; j++) {
lngPolylines[j].setMap(null);
}
lngPolylines = [];

if (map.getZoom() < 14) return;
var north = bounds.getNorthEast().lat();
var east = bounds.getNorthEast().lng();
var south = bounds.getSouthWest().lat();
var west = bounds.getSouthWest().lng();

// define the size of the grid
var topLat = Math.ceil(north / llOffset) * llOffset;
var rightLong = Math.ceil(east / llOffset) * llOffset;

var bottomLat = Math.floor(south / llOffset) * llOffset;
var leftLong = Math.floor(west / llOffset) * llOffset;

for (var latitude = bottomLat; latitude <= topLat; latitude += llOffset) latPolylines.push(new google.maps.Polyline({
path: [
new google.maps.LatLng(latitude, leftLong), new google.maps.LatLng(latitude, rightLong)],
map: map,
geodesic: true,
strokeColor: "#0000FF",
strokeOpacity: 0.5,
strokeWeight: 1
}));
for (var longitude = leftLong; longitude <= rightLong; longitude += llOffset) lngPolylines.push(new google.maps.Polyline({
path: [
new google.maps.LatLng(topLat, longitude), new google.maps.LatLng(bottomLat, longitude)],
map: map,
geodesic: true,
strokeColor: "#0000FF",
strokeOpacity: 0.5,
strokeWeight: 1
}));

if (map.getZoom() < 15) {
for (var i = 0; i < lngLabels.length; i++) {
lngLabels[i].setMap(null);
}
lngLabels = [];
return;
} // set lngLabels to null

for(var x=0;x<latPolylines.length;++x){
for(var y=0;y<lngPolylines.length-1;++y){
var latLng=new google.maps.LatLng(latPolylines[x].getPath().getAt(0).lat(),
lngPolylines[y].getPath().getAt(0).lng());

var qtrLatLng = ddToQM(latLng.lat(), latLng.lng());

lngLabels.push(new google.maps.Marker({
map:map,
position:latLng,
icon:{ url:"https://chart.googleapis.com/chart?"
+"chst=d_bubble_text_small&chld=bb|"
+ latLng
+"|FFFFFF|000000",
anchor:new google.maps.Point(0,42)
}
}));
}
}
} // end createGridLines

function createGridSelectBox(point) {
// Square limits
var smPoint = point;
var babyOffset = (llOffset/2);
var bottomLeftLat = (Math.floor(point.lat() / llOffset) * llOffset)-babyOffset;
var bottomLeftLong = (Math.floor(point.lng() / llOffset) * llOffset) - babyOffset;


var gridLineSquare = [
new google.maps.LatLng(bottomLeftLat, bottomLeftLong), //lwr left
new google.maps.LatLng(bottomLeftLat, bottomLeftLong + llOffset), //lwr right
new google.maps.LatLng(bottomLeftLat + llOffset, bottomLeftLong + llOffset), //upr right
new google.maps.LatLng(bottomLeftLat + llOffset, bottomLeftLong), //upr left
new google.maps.LatLng(bottomLeftLat, bottomLeftLong)]; //lwr left

if (drawGridSelectBox == true) {
gridSelectBox = new google.maps.Polygon({
path: gridLineSquare,
draggable:true,
geodesic:true,
editable :true,
fillColor: "#FF0000",
fillOpacity: 0.35,
strokeColor: "#CC0099",
strokeOpacity: 0.5,
strokeWeight: 2
});

gridSelectBox.setMap(map);
drawGridSelectBox = false;
}
}

function ClearGrid() {
if (qtrArray) {
for (i in qtrArray) {
qtrArray[i].setMap(null);
}
}
qtrArray=[];
}


function createGridBox(point) {
// Square limits

var smPoint = point;

var bottomLeftLat = Math.floor(point.lat() / llOffset) * llOffset;
var bottomLeftLong = Math.floor(point.lng() / llOffset) * llOffset;


var gridLineSquare = [
new google.maps.LatLng(bottomLeftLat, bottomLeftLong), //lwr left
new google.maps.LatLng(bottomLeftLat, bottomLeftLong + llOffset), //lwr right
new google.maps.LatLng(bottomLeftLat + llOffset, bottomLeftLong + llOffset), //upr right
new google.maps.LatLng(bottomLeftLat + llOffset, bottomLeftLong), //upr left
new google.maps.LatLng(bottomLeftLat, bottomLeftLong)]; //lwr left

if (drawGridBox == true) {

gridOverBox = new google.maps.Polygon({
path: gridLineSquare,
draggable:false,
geodesic:true,
editable :false,
fillColor: "#EAED00",
fillOpacity: 0.35,
strokeColor: "#CC0099",
strokeOpacity: 0.5,
strokeWeight: 2
});


gridOverBox.setMap(map);
qtrArray.push(gridOverBox);

}
}

function ddToQM(alat, alng) {
var latResult, lngResult, dmsResult;

alat = parseFloat(alat);
alng = parseFloat(alng);

latResult = (alat >= 0)? "" : "";
latResult += getDms(alat);
lngResult = (alng >= 0)? "" : "";
lngResult += getDms(alng);
dmsResult = latResult + lngResult;

// Return the resultant string.
return dmsResult;
}


function getDms(val) {

// Required variables
var valDeg, valMin, valSec, interimResult;
var qtrMin;

val = Math.abs(val);

// ---- Degrees ----

valDeg = Math.floor(val);
valMin = Math.floor((val - valDeg) * 60);
valSec = Math.round((val - valDeg - valMin / 60) * 3600 * 1000) / 1000;

if (valSec == 60){
valMin +=1;
valSec = 0;
}
if (valMin == 60){
valMin +=1;
valSec = 0;
}
interimResult = valDeg+"";

if (valMin<10){
valMin = "0"+valMin;
}
interimResult += valMin + "";

switch(valSec){
case 0 : qtrMin = "A";
break;
case 15 : qtrMin = "B";
break;
case 30 : qtrMin = "C";
break;
case 45 : qtrMin = "D";
break;

}
interimResult += qtrMin;
return interimResult;
}

</script>
</body>
</html>

最佳答案

经过几周的拆解我的脚本,我终于找到了它。问题在于 LLOffset 常量。网格框为 1/4 分钟 X 1/4 分钟。因此常数为 var llOffset = (1/60)/4);或 1 度/60 分钟/4

我使用了分数计算并让 JavaScript 决定格式。JS 确定 1/60)/4 = 0.004166666666666667 或 18 位有效数字,但在计算 LatLng 时,它仅使用 14 位有效数字。通常情况下,差异并不重要,但每隔一段时间,.000000000000006667 就足以将我的多边形 anchor 插入下一个网格。

只需将 llOffset 更改为 0.00416666666667(与谷歌地图 LatLng 相同,即可纠正问题。

当需要紧密的公差时,这可能是有用的信息。

关于javascript - 使用几何多边形来围住其他多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32670562/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com