0

In my angualr project I have created the map with leaflet and created the circle of 5km radius with the coordinates coming from the backend.something like :


 "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
                }
            ]
        }

from the above object I have created the circle with 5km radius with index-0 and with index 1 created the drone icon and from the index 2 created the points.

from the second index drone has to move from one place to another if the drone comes inside the circle of 5km it(circle) has to turned to red otherwise blue.

I have done with the above object with moving drone and color changing,but now my requirement is I have another JSON object (drone2) something like:

 "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
                }
            ]
        }
    }
}

So for this object also I have to create the circle of 5 km radius and moving from the index the functionality same as above.

but when I am trying the circle color is changing only for one drone for other the color is not changing.

.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'});
  }
}

I want to place the two drones in the map and are moving from index-2(for index-0placed the circle for index-1 placed the drone icon) and if any of the drone comes inside it has to change the color as red otherwise turned to blue.

Can anyone help me regarding this.

Bhargavi gottam
  • 93
  • 1
  • 11

1 Answers1

0

You had the problem, that some variables are used multiple times.

I created a class for you, now you can easy create new drones with 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'>

Also I added the functions drone1.startDroneMoving() and drone1.stopDroneMoving()

Update

To show only the red quadrants:


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

Example: https://jsfiddle.net/falkedesign/fu39n1so/

Falke Design
  • 10,635
  • 3
  • 15
  • 30
  • Thanks @Falke Design,absolutely working for me,and one more requirement is when the drone inside the circle the quadrant of the circle only be highlight no need to show the circle border with the highlighted quadrent. – Bhargavi gottam Sep 14 '20 at 02:07
  • Thanks ,It is working fine.and one more last requirement is to move the marker slowly(i.e smooth moving)if change the time to 3000 it is moving at a time after 3 sec but I want to move the drone slowly with in 3 sec. – Bhargavi gottam Sep 14 '20 at 07:56
  • This is not so easy, use a library for this, look at https://leafletjs.com/plugins.html#overlay-animations – Falke Design Sep 14 '20 at 08:14