Почему координаты многоугольника в Google Map возвращают ложные значения Lat, Lng? - PullRequest
0 голосов
/ 25 января 2020

Вот мой код, который я использую для извлечения данных из Google Maps, а также для получения координат многоугольника и полилиний из Drawer.

**

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
  <meta charset="UTF-8" />
  <title>Muhammad</title>
  <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&libraries=drawing"></script>
  <style type="text/css">
    #map,
    html,
    body {
      padding: 0;
      margin: 0;
      width: 95%;
      height: 700px;
      float: right;
    }
    #panel {
      width: 200px;
      font-family: Arial, sans-serif;
      font-size: 13px;
      float: right;
      margin: 10px;
    }
    #color-palette {
      clear: both;
    }
    .color-button {
      width: 14px;
      height: 14px;
      font-size: 0;
      margin: 2px;
      float: left;
      cursor: pointer;
    }
    #delete-button {
      margin-top: 5px;
    }
  </style>
  <script type="text/javascript">
    var drawingManager;
    var selectedShape;
    var colors = ["#1E90FF", "#FF1493", "#32CD32", "#FF8C00", "#4B0082"];
    var selectedColor;
    var colorButtons = {};
    function clearSelection() {
      if (selectedShape) {
        selectedShape.setEditable(false);
        selectedShape = null;
      }
    }
    function setSelection(shape) {
      clearSelection();
      // getting shape coordinates
      var v = shape.getPath();
      var coords = [];
      for (var i = 0; i < v.getLength(); i++) {
        var xy = v.getAt(i);
        console.log(`Cordinate lat ${i}: ` + xy.lat() + `and long  ${i}: ` + xy.lng());
        var x = document.createElement('INPUT');
        x.setAttribute('type', 'text');
        x.setAttribute('value', xy);
        document.body.appendChild(x);
        coords.push([xy.lat()], [xy.lng()]);
      }
      console.log(coords + 'Muhammad');
      document.getElementById('coords_value').value = coords;
      selectedShape = shape;
      shape.setEditable(true);
      selectColor(shape.get("fillColor") || shape.get("strokeColor"));
    }
    function saveButton(shape) {
    }
    function deleteSelectedShape() {
      if (selectedShape) {
        selectedShape.setMap(null);
      }
    }
    function selectColor(color) {
      selectedColor = color;
      for (var i = 0; i < colors.length; ++i) {
        var currColor = colors[i];
        colorButtons[currColor].style.border = currColor == color ? "2px solid #789" : "2px solid #fff";
      }
      // Retrieves the current options from the drawing manager and replaces the
      // stroke or fill color as appropriate.
      var polylineOptions = drawingManager.get("polylineOptions");
      polylineOptions.strokeColor = color;
      drawingManager.set("polylineOptions", polylineOptions);
      var rectangleOptions = drawingManager.get("rectangleOptions");
      rectangleOptions.fillColor = color;
      drawingManager.set("rectangleOptions", rectangleOptions);
      var circleOptions = drawingManager.get("circleOptions");
      circleOptions.fillColor = color;
      drawingManager.set("circleOptions", circleOptions);
      var polygonOptions = drawingManager.get("polygonOptions");
      polygonOptions.fillColor = color;
      drawingManager.set("polygonOptions", polygonOptions);
    }
    function setSelectedShapeColor(color) {
      console.log("fn setSelectedShapeColor()");
      console.log(selectedShape);
      if (selectedShape) {
        if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
          selectedShape.set("strokeColor", color);
        } else {
          selectedShape.set("fillColor", color);
        }
      }
    }
    function makeColorButton(color) {
      var button = document.createElement("span");
      button.className = "color-button";
      button.style.backgroundColor = color;
      google.maps.event.addDomListener(button, "click", function() {
        selectColor(color);
        setSelectedShapeColor(color);
      });
      return button;
    }
    function buildColorPalette() {
      var colorPalette = document.getElementById("color-palette");
      for (var i = 0; i < colors.length; ++i) {
        var currColor = colors[i];
        var colorButton = makeColorButton(currColor);
        colorPalette.appendChild(colorButton);
        colorButtons[currColor] = colorButton;
      }
      selectColor(colors[0]);
    }
    function initialize() {
      var pakistan = new google.maps.LatLng(30.3753, 69.3451);
      var map = new google.maps.Map(document.getElementById("map"), {
        zoom: 3,
        center: pakistan,
        disableDefaultUI: true,
        zoomControl: true
      });
      var marker = new google.maps.Marker({
        position: pakistan,
        map: map
      });
      var polyOptions = {
        strokeWeight: 0,
        fillOpacity: 0.45,
        editable: true,
        draggable: true
      };
      // Creates a drawing manager attached to the map that allows the user to draw
      // markers, lines, and shapes.
      drawingManager = new google.maps.drawing.DrawingManager({
        drawingMode: google.maps.drawing.OverlayType.POLYGON,
        markerOptions: {
          draggable: true
        },
        polylineOptions: {
          editable: true,
          draggable: true
        },
        rectangleOptions: polyOptions,
        circleOptions: polyOptions,
        polygonOptions: polyOptions,
        map: map
      });
      google.maps.event.addListener(drawingManager, "overlaycomplete", function(e) {
        if (e.type !== google.maps.drawing.OverlayType.MARKER) {
          // Switch back to non-drawing mode after drawing a shape.
          drawingManager.setDrawingMode(null);
          // Add an event listener that selects the newly-drawn shape when the user
          // mouses down on it.
          var newShape = e.overlay;
          newShape.type = e.type;
          google.maps.event.addListener(newShape, "click", function(e) {
            if (e.vertex !== undefined) {
              if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
                var path = newShape.getPaths().getAt(e.path);
                path.removeAt(e.vertex);
                if (path.length < 3) {
                  newShape.setMap(null);
                }
              }
              if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
                var path = newShape.getPath();
                path.removeAt(e.vertex);
                if (path.length < 2) {
                  newShape.setMap(null);
                }
              }
            }
            setSelection(newShape);
            saveButton(newShape);
          });
          setSelection(newShape);
          saveButton(newShape);
        }
      });
      // Clear the current selection when the drawing mode is changed, or when the
      // map is clicked.
      google.maps.event.addListener(drawingManager, "drawingmode_changed", clearSelection);
      google.maps.event.addListener(map, "click", clearSelection);
      google.maps.event.addDomListener(document.getElementById("delete-button"), "click", deleteSelectedShape);
      buildColorPalette();
    }
    google.maps.event.addDomListener(window, "load", initialize);
    var IO = {
      //returns array with storable google.maps.Overlay-definitions
      IN: function(
        arr, //array with google.maps.Overlays
        encoded //boolean indicating if pathes should be stored encoded
      ) {
        var shapes = [],
          goo = google.maps,
          shape,
          tmp;
        for (var i = 0; i < arr.length; i++) {
          shape = arr[i];
          tmp = {
            type: this.t_(shape.type),
            id: shape.id || null
          };
          switch (tmp.type) {
            case "CIRCLE":
              tmp.radius = shape.getRadius();
              tmp.geometry = this.p_(shape.getCenter());
              break;
            case "MARKER":
              tmp.geometry = this.p_(shape.getPosition());
              break;
            case "RECTANGLE":
              tmp.geometry = this.b_(shape.getBounds());
              break;
            case "POLYLINE":
              tmp.geometry = this.l_(shape.getPath(), encoded);
              break;
            case "POLYGON":
              tmp.geometry = this.m_(shape.getPaths(), encoded);
              break;
          }
          shapes.push(tmp);
        }
        return shapes;
      },
      //returns array with google.maps.Overlays
      OUT: function(
        arr, //array containg the stored shape-definitions
        map //map where to draw the shapes
      ) {
        var shapes = [],
          goo = google.maps,
          map = map || null,
          shape,
          tmp;
        for (var i = 0; i < arr.length; i++) {
          shape = arr[i];
          switch (shape.type) {
            case "CIRCLE":
              tmp = new goo.Circle({
                radius: Number(shape.radius),
                center: this.pp_.apply(this, shape.geometry)
              });
              break;
            case "MARKER":
              tmp = new goo.Marker({
                position: this.pp_.apply(this, shape.geometry)
              });
              break;
            case "RECTANGLE":
              tmp = new goo.Rectangle({
                bounds: this.bb_.apply(this, shape.geometry)
              });
              break;
            case "POLYLINE":
              tmp = new goo.Polyline({
                path: this.ll_(shape.geometry)
              });
              break;
            case "POLYGON":
              tmp = new goo.Polygon({
                paths: this.mm_(shape.geometry)
              });
              break;
          }
          tmp.setValues({
            map: map,
            id: shape.id
          });
          shapes.push(tmp);
        }
        return shapes;
      },
      l_: function(path, e) {
        path = path.getArray ? path.getArray() : path;
        if (e) {
          return google.maps.geometry.encoding.encodePath(path);
        } else {
          var r = [];
          for (var i = 0; i < path.length; ++i) {
            r.push(this.p_(path[i]));
          }
          return r;
        }
      },
      ll_: function(path) {
        if (typeof path === "string") {
          return google.maps.geometry.encoding.decodePath(path);
        } else {
          var r = [];
          for (var i = 0; i < path.length; ++i) {
            r.push(this.pp_.apply(this, path[i]));
          }
          return r;
        }
      },
      m_: function(paths, e) {
        var r = [];
        paths = paths.getArray ? paths.getArray() : paths;
        for (var i = 0; i < paths.length; ++i) {
          r.push(this.l_(paths[i], e));
        }
        return r;
      },
      mm_: function(paths) {
        var r = [];
        for (var i = 0; i < paths.length; ++i) {
          r.push(this.ll_.call(this, paths[i]));
        }
        return r;
      },
      p_: function(latLng) {
        return [latLng.lat(), latLng.lng()];
      },
      pp_: function(lat, lng) {
        return new google.maps.LatLng(lat, lng);
      },
      b_: function(bounds) {
        return [this.p_(bounds.getSouthWest()), this.p_(bounds.getNorthEast())];
      },
      bb_: function(sw, ne) {
        return new google.maps.LatLngBounds(this.pp_.apply(this, sw), this.pp_.apply(this, ne));
      },
      t_: function(s) {
        var t = ["CIRCLE", "MARKER", "RECTANGLE", "POLYLINE", "POLYGON"];
        for (var i = 0; i < t.length; ++i) {
          if (s === google.maps.drawing.OverlayType[t[i]]) {
            return t[i];
          }
        }
      }
    };
  </script>
</head>
<body>
  <div id="panel">
    <div id="color-palette"></div>
    <form method="POST" action="submit.php">
      <input type="text" id="coords_value" name="coords" value="Muhammad">
      <button onclick="saveButton()">Muhammad</button>
    </form>
    <div><button id="delete-button">Delete Selected Shape</button></div>
  </div>
  <div id="map"></div>
</body>
</html>

** и мой способ отправки. php file **

<?php $servername = "localhost";
$username = "root";
$password = "";
$db = "users";
$mysqli = new mysqli($servername, $username, $password, $db);
//    SET @g = 'POLYGON($_POST[coords])';
$coords = $_POST['coords'];
//$stmt = "INSERT INTO polygon_data (polygon_values) VALUES (GeomFromText('POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))'))";
$stmt = "INSERT INTO polygon_data (polygon_values) VALUES (PolygonFromText('POLYGON((40.95269385429521, -74.14416921914062,40.959175907354734, -74.11670339882812,40.9419322410085, -74.13009298623047))'))";
if ($mysqli->query($stmt) === TRUE) {
    echo "feedback sucessfully submitted";
} else {
    echo "Error: " . $stmt  . "<br>" . $mysqli->error;
}
$mysqli->close();
?>

**

Например, если я рисую поллигон, а затем получаю следующие неправильные точки, это потому, что в многоугольнике первый и координаты последней точки были бы такими же, но в моем случае это выглядит как-то иначе, как показано ниже. (61.81599137659937,102.17362172851564,62.956500953314375,117.64237172851564,56.80241721826492,111.84159047851564) и эта разница огромная. И я не получил ожидаемого результата? Спасибо

...