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_shapes
array in the database.
<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"> </td>
<td bgcolor="#00FF00"> </td>
<td bgcolor="#0000FF"> </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.
When you simply want to store the shapes somehow, you may use a JSON-string, store it in e.g. a Text
-column(char
would be to small to store detailed polygons/polylines )
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
Another approach: use multiple columns, e.g.
- a column(
varchar
) where you store the type(LatLng, Circle,Polyline,etc.) - a column(
geometry
) where you store the geometric features(LatLng,Polygon or Polyline) - a column(
int
) where you store a radius(used when you insert a circle) - optionally column(
text
) where you store the style-options(when needed)
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.html for details of the spatial extensions
2 functions that either remove the circular references and create storable objects, or restore the overlays from these stored objects.
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.IN
may be sended to a serverside script. The serverside script should iterate over this array and INSERT a JSON-string into the 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();
}
?>
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(<?php echo $json;?>, someGoogleMapsInstance);
Simple GeoJson Editor is 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.
The Javascript and HTML are not minified.
An even better opensource tool can be found at Geojson.io
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.
来源:https://stackoverflow.com/questions/19614805/how-to-save-a-google-maps-overlay-shape-in-the-database