首页 > 解决方案 > 如何使用角度的传单地图将角度90的圆弧放置在半径5公里的圆内以及如何更改圆的颜色

问题描述

在我的 angualr 项目中,我使用传单创建了地图,并创建了半径为 5 公里的圆圈,其坐标来自后端。类似于:


 "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 公里的圆,索引为 0,索引 1 创建了无人机图标,并从索引 2 创建了点。

从第二个索引无人机必须从一个地方移动到另一个地方,如果无人机进入 5 公里的圆圈内,它(圆圈)必须变成红色,否则为蓝色。

我已经通过移动无人机和颜色更改完成了上述对象,但现在我的要求是我有另一个 JSON 对象(drone2),例如:

 "drone2": {
        "Drone": {
            "Droneid": 1002,
            
            "latlong": [
                {
                    "lat": 12.979377,
                    "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
                }
            ]
        }
    }
}

所以对于这个对象,我还必须创建半径为 5 公里的圆,并从索引移动与上面相同的功能。

但是当我尝试时,圆圈颜色只改变了一架无人机,而另一架无人机的颜色没有改变。

.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","lat":latlong.lat,"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'});
  }
}

我想将两架无人机放在地图中并从 index-2 移动(对于 index-0 放置了 index-1 的圆圈放置了无人机图标),如果有任何无人机进入它必须将颜色更改为红色,否则变成了蓝色。

任何人都可以帮助我解决这个问题。

标签: leafletreact-leafletangular-leaflet-directiveleaflet.markercluster

解决方案


您遇到了问题,即某些变量被多次使用。

我为你创建了一个类,现在你可以轻松地创建新的无人机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 &copy; <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", "lat": latlong.lat, "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, {color: 'red'}, {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'});
      }
    }

示例:https ://jsfiddle.net/falkedesign/fu39n1so/


推荐阅读