web-dev-qa-db-fra.com

Comment enregistrer une forme de superposition Google maps dans la base de données?

Je souhaite enregistrer une forme de superposition Google Maps dans la base de données. Ceci est mon code. Cela fonctionne parfaitement, mais je dois juste enregistrer le tableau all_shapes dans la base de données.

<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>

Où et comment puis-je enregistrer les formes de superposition créées dans la base de données? Toutes les formes sont enregistrées dans le tableau var all_shapes = [];. Quel type de type dois-je choisir pour le champ dans la base de données? Je veux dire par exemple int, char, etc., je vais utiliser MySQL et PHP.

14
Sponge Bob

Lorsque vous souhaitez simplement stocker les formes d’une manière ou d’une autre, vous pouvez utiliser une chaîne JSON, stockez-la dans, par exemple. une colonne Text- (char serait trop petit pour stocker des polygones/polylignes détaillés)

Remarque: lorsque vous créez la chaîne JSON, vous devez convertir les propriétés (par exemple, en tableaux ou objets natifs). Vous ne pouvez pas stocker directement par exemple celui de LatLng, car le prototype sera perdu lors de son enregistrement. Les chemins des polylignes/polygones peuvent être stockés codé

Une autre approche: Utilise plusieurs colonnes, par ex. 

  1. une colonne (varchar) où vous stockez le type (LatLng, Circle, Polyline, etc.)
  2. une colonne (geometry) où vous stockez les entités géométriques (LatLng, Polygon ou Polyligne)
  3. une colonne (int) où vous stockez un rayon (utilisé lorsque vous insérez un cercle)
  4. éventuellement colonne (text) où vous stockez les options de style (si nécessaire)

La première suggestion serait suffisante lorsque vous souhaitez simplement la stocker. 

Lorsque vous devez pouvoir sélectionner des formes particulières, par exemple pour une zone donnée, utilisez la 2ème suggestion .. Voir http://dev.mysql.com/doc/refman/5.0/fr/spatial-extensions.html pour les détails des extensions spatiales


2 fonctions qui suppriment les références circulaires et créent des objets stockables, ou restaurent les superpositions à partir de ces objets stockés.

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

}

Le tableau renvoyé par IO.IN peut être envoyé à un script côté serveur. Le script serverside doit itérer sur ce tableau et INSERER une chaîne JSON dans la table:

<?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();
}
?>

pour restaurer les formes, allez les chercher:

<?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);
?>

et passez le résultat à IO.OUT():

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

Démo: http://jsfiddle.net/doktormolle/EdZk4/show/

30
Dr.Molle

Simple GeoJson Editor est un exemple de dessin, modification, suppression et enregistrement de formes au format geoJson sur Google Maps L'auteur (un stagiaire de Google) a décrit le projet dans ce post .

Les Javascript et HTML ne sont pas minifiés. 

Un outil opensource encore meilleur peut être trouvé à Geojson.io

5
intotecho

Si vous devez stocker le chemin simplement pour le restaurer ultérieurement sur une carte, vous pouvez également utiliser Utilitaire d'encodage Google Maps . Ce n'est pas aussi puissant que la réponse de Dr.Molle mais peut être utile pour stocker des polygones et des polylignes.

0
trainmaster