MySQL 如何在数据库中保存谷歌地图叠加形状?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19614805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 19:15:21  来源:igfitidea点击:

How to save a Google maps overlay shape in the database?

mysqldatabasegoogle-maps-api-3shapesoverlays

提问by Sponge Bob

I want to save a Google maps overlay shape in the database. This is my code. It works perfectly but I just need to save all_shapesarray in the database.

我想在数据库中保存一个谷歌地图覆盖形状。这是我的代码。它工作得很好,但我只需要all_shapes在数据库中保存数组。

<html>
<head>

<style type="text/css">
  #map, html, body
  {
      padding: 0;
      margin: 0;
      height: 100%;
  }
</style>

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true&libraries=drawing,geometry"></script>

<script>
var coordinates = [];
var all_shapes = [];

var selectedShape;
</script>

<script>
function draw_shape()
{
    for(var i = 0; i < all_shapes.length; i++)
    {
        all_shapes[i].setMap(null);
    }

    for(var i = 0; i < all_shapes.length; i++)
    {
        all_shapes[i].setMap(map);
    }
}
</script>

<script>
function clearSelection()
{
    if(selectedShape)
    {
        selectedShape.setEditable(false);
        selectedShape = null;
    }
}

function setSelection(shape)
{
    clearSelection();
    selectedShape = shape;
    shape.setEditable(true);
}

function deleteSelectedShape()
{
    if (selectedShape)
    {
        selectedShape.setMap(null);
    }
}
</script>

<script>
function save_coordinates_to_array(newShapeArg)
{
    if(newShapeArg.type == google.maps.drawing.OverlayType.POLYGON)
    {
        var polygonBounds = newShapeArg.getPath();

        for(var i = 0 ; i < polygonBounds.length ; i++)
        {
            coordinates.push(polygonBounds.getAt(i).lat(), polygonBounds.getAt(i).lng());
        }
    }
    else
    {
        //alert("Not polygon");/////////////
    }   
}
</script>

<script>
var map;

function initialize()
{
    map = new google.maps.Map(document.getElementById('map'), {zoom: 12, center: new google.maps.LatLng(32.344, 51.048)});

    var drawingManager = new google.maps.drawing.DrawingManager();
    drawingManager.setMap(map);

    google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
        var newShape = e.overlay;
        newShape.type = e.type;

        all_shapes.push(newShape);

        setSelection(newShape);

        save_coordinates_to_array(newShape);

        google.maps.event.addListener(newShape, 'click', function() {setSelection(newShape)});
      });

    google.maps.event.addListener(map, 'click', function(e) {clearSelection();});
}

google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>

<body>
<table border="1">
  <tr>
    <td>Name</td>
    <td><input name="name" id="name" type="text"></td>
  </tr>
  <tr>
    <td>Color</td>
    <td>
      <table border="1" width="100%">
        <tr>
          <td bgcolor="#FF0000">&nbsp;</td>
          <td bgcolor="#00FF00">&nbsp;</td>
          <td bgcolor="#0000FF">&nbsp;</td>
        </tr>
      </table>
    </td>
  </tr>
  <tr>
    <td colspan="2"><input name="save" type="button" value="Save" onClick="draw_shape()"></td>
  </tr>
  <tr>
    <td colspan="2"><input name="delete" type="button" value="Delete" onClick="deleteSelectedShape()"></td>
  </tr>  
</table>

<div id="map"></div>
</body>

</html>

Where and how can I save the created overlay shapes in the database. All shapes are saved in the var all_shapes = [];array. What kind of type I have to choose for the field in database? I mean for example int, char, etc. I'm going to use MySQL and PHP.

我在哪里以及如何将创建的叠加形状保存在数据库中。所有形状都保存在var all_shapes = [];数组中。我必须为数据库中的字段选择什么样的类型?我的意思是例如 int、char 等。我将使用 MySQL 和 PHP。

回答by Dr.Molle

When you simply want to store the shapes somehow, you may use a JSON-string, store it in e.g. a Text-column(charwould be to small to store detailed polygons/polylines )

当您只是想以某种方式存储形状时,您可以使用 JSON 字符串,将其存储在例如Text-column(char对于存储详细的多边形/折线来说太小了)

Note: when you create the JSON-string, you must convert the properties(e.g. to native arrays or objects), you cannot store for example LatLng's directly, because the prototype will be lost when saving it. Pathes of polylines/polygons may be stored encoded

注意:创建 JSON 字符串时,必须转换属性(例如转换为原生数组或对象),不能直接存储例如 LatLng,因为保存时原型会丢失。折线/多边形的路径可以存储编码

Another approach: use multiple columns, e.g.

另一种方法:使用多列,例如

  1. a column(varchar) where you store the type(LatLng, Circle,Polyline,etc.)
  2. a column(geometry) where you store the geometric features(LatLng,Polygon or Polyline)
  3. a column(int) where you store a radius(used when you insert a circle)
  4. optionally column(text) where you store the style-options(when needed)
  1. 用于varchar存储类型(LatLng、Circle、Polyline 等)的 column( )
  2. geometry存储几何特征的列()(LatLng、Polygon 或 Polyline)
  3. int存储半径的列()(插入圆时使用)
  4. 可选的 column( text) 存储样式选项的位置(需要时)

The first suggestion would be sufficient when you simply want to store it.

当您只想存储它时,第一个建议就足够了。

When you must be able to select particular shapes, e.g for a given area, use the 2nd suggestion. See http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.htmlfor details of the spatial extensions

当您必须能够选择特定形状时,例如对于给定区域,请使用第二个建议。有关空间扩展的详细信息,请参阅http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html



2 functions that either remove the circular references and create storable objects, or restore the overlays from these stored objects.

2 个函数可以删除循环引用并创建可存储对象,或者从这些存储对象中恢复覆盖。

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

}

The array returned by IO.INmay be sended to a serverside script. The serverside script should iterate over this array and INSERT a JSON-string into the table:

返回的数组IO.IN可能会发送到服务器端脚本。服务器端脚本应该遍历这个数组并将一个 JSON 字符串插入到表中:

<?php
$mysqli = new mysqli(/*args*/);
$stmt = $mysqli->prepare('INSERT INTO `tableName`(`columnName`) VALUES (?)');
$stmt->bind_param('s', $json);

foreach($_POST['shapes'] as $value){
  $json = json_encode($value);
  $stmt->execute();
}
?>

to restore the shapes fetch them:

恢复形状获取它们:

<?php
$json=array();
$res=$mysqli->query('SELECT `columnName` from `tableName`');
while ($row = $res->fetch_assoc()) {
        $json[]=json_decode($row['columnName']);
    }
$res->close();
$json=json_encode($json);
?>

and pass the result to IO.OUT():

并将结果传递给IO.OUT()

IO.OUT(<?php echo $json;?>, someGoogleMapsInstance);

Demo: http://jsfiddle.net/doktormolle/EdZk4/show/

演示:http: //jsfiddle.net/doktormolle/EdZk4/show/

回答by intotecho

Simple GeoJson Editoris an example of drawing, editing, dropping and saving shapes as geoJson on google maps. The author ( a Google intern) described the project in this post.

简单的 GeoJson 编辑器是在谷歌地图上绘制、编辑、删除和保存形状为 geoJson 的示例。作者(谷歌实习生)在这篇文章中描述了这个项目。

The Javascriptand HTMLare not minified.

使用JavascriptHTML不精缩。

An even better opensource tool can be found at Geojson.io

一个更好的开源工具可以在Geojson.io找到

回答by trainmaster

If you need to store the path just to restore it later on a map, you can also use Google Maps Encoding Utility. It is not as powerful as Dr.Molle's answer but can be useful for storing polygons and polylines.

如果您需要存储路径只是为了稍后在地图上恢复它,您还可以使用Google Maps Encoding Utility。它不如 Dr.Molle 的答案强大,但可用于存储多边形和折线。