【问题标题】:How to place the arc of angle 90 inside the circle of 5km radius using leaflet map in angular and how to change the color of circle如何使用角度的传单地图将角度90的圆弧放置在半径5公里的圆内以及如何更改圆的颜色
【发布时间】:2020-12-31 12:20:38
【问题描述】:

在我的 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'});
  }
}

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

谁能帮我解决这个问题。

【问题讨论】:

    标签: leaflet react-leaflet angular-leaflet-directive leaflet.markercluster


    【解决方案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 &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/

    【讨论】:

    • 感谢@Falke Design,绝对为我工作,还有一个要求是当圆圈内的无人机只突出显示圆圈的象限时,不需要显示带有突出显示的象限的圆圈边界。
    • 谢谢,它工作正常。最后一个要求是缓慢移动标记(即平滑移动)如果将时间更改为 3000,它会在 3 秒后一次移动,但我想在 3 秒内缓慢移动无人机。
    • 这不是那么容易,为此使用一个库,看看leafletjs.com/plugins.html#overlay-animations
    猜你喜欢
    • 2020-12-15
    • 2014-06-12
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 2013-11-23
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    相关资源
    最近更新 更多