问题描述
在我的angualr项目中,我用传单创建了地图,并创建了5km半径的圆,其坐标来自后端。
"drone1": {
"Drone": {
"Droneid": 1001,"latlong": [
{
"lat": 12.979377,"lon": 80.195147
},{
"lat": 12.957052,"lon": 80.241433
},{
"lat": 12.95379,"lon": 80.230627
},{
"lat": 12.956634,"lon": 80.18737
},{
"lat": 12.952619,"lon": 80.17072
},{
"lat": 12.950946,"lon": 80.150122
},{
"lat": 12.949356,"lon": 80.134757
}
]
}
从上述对象中,我创建了一个半径为5 km的圆,索引号为0,索引号为1的无人机图标,索引号为2的点。
如果无人机进入5公里以内,它必须从第二个索引位置移动到另一个地方,圆圈必须变成红色,否则变成蓝色。
我已经完成了上述对象的移动无人机和颜色更改,但是现在我的要求是我还有另一个JSON对象(drone2),如下所示:
"drone2": {
"Drone": {
"Droneid": 1002,{
"lat": 13.021618,"lon": 80.140019
},{
"lat": 13.000376,"lon": 80.164602
},{
"lat": 12.991009,"lon": 80.174901
},{
"lat": 12.980304,"lon": 80.184514
},{
"lat": 12.965416,"lon": 80.20838
},{
"lat": 12.936976,"lon": 80.24117
}
]
}
}
}
因此,对于该对象,我还必须创建半径为5 km的圆,并从索引中移出与上面相同的功能。
但是当我尝试使用圆形颜色时,只有一架无人机改变了颜色,而另一种则没有改变。
.component.ts
var latlngs = this.drones.drone1.Drone.latlong;
var latlngs02 = this.drones.drone2.Drone.latlong;
var START_IDX = 2;
var latlngIdx = START_IDX; // 0 = Circle,1 = First position
var marker;
var circlemark;
var circle;
latlngs.forEach((latlong,idx)=>{
var latlng = L.latLng(latlong.lat,latlong.lon)
if(idx === 0){
var jammer = {"name":"Jammer 1","lat":latlong.lat,"lon":latlong.lon,"isCollapsed":false};
var sensor = {"name":"Sensor 1","lon":latlong.lon};
circlemark = L.circle(latlng,{radius:5000}).addTo(map);
marker = L.marker(latlng,{icon:sensoricon}).addTo(map);
marker = L.marker(latlng,{icon:jammericon}).addTo(map);
}else if(idx===1){
marker = L.marker(latlng,{icon:myIcon}).addTo(map);
}else if(idx>=2){
var circleMarker = L.circle(latlng,{color: 'red'},{radius:100}).addTo(map)
}
});
var Quadrant1 = createQuadrant(circlemark,0).addTo(map);
var Quadrant2 = createQuadrant(circlemark,90).addTo(map);
var Quadrant3 = createQuadrant(circlemark,180).addTo(map);
var Quadrant4 = createQuadrant(circlemark,270).addTo(map);
function nextLatLng(){
if(marker){
if(latlngIdx === latlngs.length){
latlngIdx = START_IDX;
}
marker.setLatLng(latlngs[latlngIdx]);
inQuadrant(Quadrant1,marker);
inQuadrant(Quadrant2,marker);
inQuadrant(Quadrant3,marker);
inQuadrant(Quadrant4,marker);
latlngIdx++;
setTimeout(nextLatLng,TIME);
}
}
nextLatLng();
function getdistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
var d = R * c; // distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
function createQuadrant(circle,degree){
var degree
var p1 = L.GeometryUtil.destination(circle.getLatLng(),degree,circle.geTradius());
var p2 = L.GeometryUtil.destination(circle.getLatLng(),degree+22.5,circle.geTradius());
var p3 = L.GeometryUtil.destination(circle.getLatLng(),degree+45,circle.geTradius());
var p4 = L.GeometryUtil.destination(circle.getLatLng(),degree+67.5,circle.geTradius());
var p5 = L.GeometryUtil.destination(circle.getLatLng(),degree+90,circle.geTradius());
return L.polygon([circle.getLatLng(),p1,p2,p3,p4,p5]);
}
function isMarkerInsidepolygon(marker,poly) {
var inside = false;
var x = marker.getLatLng().lat,y = marker.getLatLng().lng;
for (var ii=0;ii<poly.getLatLngs().length;ii++){
var polyPoints = poly.getLatLngs()[ii];
for (var i = 0,j = polyPoints.length - 1; i < polyPoints.length; j = i++) {
var xi = polyPoints[i].lat,yi = polyPoints[i].lng;
var xj = polyPoints[j].lat,yj = polyPoints[j].lng;
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
}
return inside;
};
function inQuadrant(quadrant,marker){
var inpolygon = isMarkerInsidepolygon(marker,quadrant);
if(inpolygon){
quadrant.setStyle({color: 'red'});
}else{
quadrant.setStyle({color: '#3388ff'});
}
}
我要将两架无人机放置在地图上,并从索引2移动(对于索引0放置了圆圈,索引1放置了无人机图标的圆圈),如果有任何无人机进入内部,则必须更改颜色变成红色,否则变成蓝色。
有人可以帮我吗?
解决方法
您遇到了问题,某些变量被多次使用。
我为您创建了一个类,现在您可以使用drone1 = new L.Drone(map,latlngs)
var map = L.map('map').setView([12.979377,80.195147],12);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw',{
maxZoom: 180,attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors,' +
'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>,' +
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',id: 'mapbox.streets'
}).addTo(map);
var D1 = {
"drone1":{
"Drone":{
"Droneid":
1001,"latlong":
[
{
"lat": 12.979377,"lon": 80.195147
},{
"lat": 12.957052,"lon": 80.241433
},{
"lat": 12.95379,"lon": 80.230627
},{
"lat": 12.956634,"lon": 80.18737
},{
"lat": 12.952619,"lon": 80.17072
},{
"lat": 12.950946,"lon": 80.150122
},{
"lat": 12.949356,"lon": 80.134757
}
]
}
}
};
var D2 = {
"drone2": {
"Drone": {
"Droneid": 1002,"latlong": [
{
"lat": 12.979877,"lon": 80.195147
},{
"lat": 13.021618,"lon": 80.140019
},{
"lat": 13.000376,"lon": 80.164602
},{
"lat": 12.991009,"lon": 80.174901
},{
"lat": 12.980304,"lon": 80.184514
},{
"lat": 12.965416,"lon": 80.20838
},{
"lat": 12.936976,"lon": 80.24117
}
]
}
}
}
var latlngs = D1.drone1.Drone.latlong;
var latlngs02 = D2.drone2.Drone.latlong;
L.Drone = L.Class.extend({
START_IDX: 2,latlngIdx: this.START_IDX,// 0 : Circle,1 : First position
marker: null,circle: null,TIME: 500,latlngs: null,droneMarker: null,timeout: null,initialize(map,data) {
this.map = map;
this.addDroneData(data);
this.showDroneData();
this.startDroneMoving();
},addDroneData(data) {
this.latlngs = data;
},showDroneData() {
this.latlngs.forEach((latlong,idx) => {
var latlng = L.latLng(latlong.lat,latlong.lon);
if (idx === 0) {
var jammer = {"name": "Jammer 1","lat": latlong.lat,"lon": latlong.lon,"isCollapsed": false};
var sensor = {"name": "Sensor 1","lon": latlong.lon};
this.circle = L.circle(latlng,{radius: 5000}).addTo(map);
L.marker(latlng).addTo(map);
L.marker(latlng).addTo(map);
} else if (idx === 1) {
this.droneMarker = L.marker(latlng).addTo(map);
L.circle(latlng,{color: 'red'},{radius: 100}).addTo(map)
} else if (idx >= 2) {
L.circle(latlng,{radius: 100}).addTo(map)
}
});
this.Quadrant1 = this.createQuadrant(this.circle,0).addTo(map);
this.Quadrant2 = this.createQuadrant(this.circle,90).addTo(map);
this.Quadrant3 = this.createQuadrant(this.circle,180).addTo(map);
this.Quadrant4 = this.createQuadrant(this.circle,270).addTo(map);
},startDroneMoving(){
this.nextLatLng();
},stopDroneMoving(){
clearTimeout(this.timeout);
},createQuadrant(circle,degree) {
var p1 = L.GeometryUtil.destination(circle.getLatLng(),degree,circle.getRadius());
var p2 = L.GeometryUtil.destination(circle.getLatLng(),degree + 22.5,circle.getRadius());
var p3 = L.GeometryUtil.destination(circle.getLatLng(),degree + 45,circle.getRadius());
var p4 = L.GeometryUtil.destination(circle.getLatLng(),degree + 67.5,circle.getRadius());
var p5 = L.GeometryUtil.destination(circle.getLatLng(),degree + 90,circle.getRadius());
return L.polygon([circle.getLatLng(),p1,p2,p3,p4,p5]);
},nextLatLng() {
if (this.droneMarker) {
if (!this.latlngIdx || this.latlngIdx === this.latlngs.length) {
this.latlngIdx = this.START_IDX;
}
this.droneMarker.setLatLng(this.latlngs[this.latlngIdx]);
this.inQuadrant(this.Quadrant1); //this.droneMarker
this.inQuadrant(this.Quadrant2);
this.inQuadrant(this.Quadrant3);
this.inQuadrant(this.Quadrant4);
this.latlngIdx++;
this.timeout = setTimeout(()=>{this.nextLatLng()},this.TIME);
}
},isMarkerInsidePolygon(marker,poly) {
var inside = false;
var x = marker.getLatLng().lat,y = marker.getLatLng().lng;
for (var ii = 0; ii < poly.getLatLngs().length; ii++) {
var polyPoints = poly.getLatLngs()[ii];
for (var i = 0,j = polyPoints.length - 1; i < polyPoints.length; j = i++) {
var xi = polyPoints[i].lat,yi = polyPoints[i].lng;
var xj = polyPoints[j].lat,yj = polyPoints[j].lng;
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
}
return inside;
},inQuadrant(quadrant) {
var inPolygon = this.isMarkerInsidePolygon(this.droneMarker,quadrant);
if (inPolygon) {
quadrant.setStyle({color: 'red'});
quadrant.addTo(this.map);
} else {
quadrant.removeFrom(this.map);
quadrant.setStyle({color: '#3388ff'});
}
}
});
var drone1 = new L.Drone(map,latlngs);
var drone2 = new L.Drone(map,latlngs02);
#map {
width: 600px;
height: 400px;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet-geometryutil@0.9.3/src/leaflet.geometryutil.min.js"></script>
<div id='map'>
我还添加了功能drone1.startDroneMoving()
和drone1.stopDroneMoving()
更新
仅显示红色象限:
inQuadrant(quadrant) {
var inPolygon = this.isMarkerInsidePolygon(this.droneMarker,quadrant);
if (inPolygon) {
quadrant.setStyle({color: 'red'});
quadrant.addTo(this.map);
} else {
quadrant.removeFrom(this.map);
quadrant.setStyle({color: '#3388ff'});
}
}