Can't save polygon in google maps - javascript

I have a google maps polygon object:
var poly = new google.maps.Polygon({
paths: [
new google.maps.LatLng(25.774252, -80.190262),
new google.maps.LatLng(18.466465, -66.118292),
new google.maps.LatLng(32.321384, -64.75737)
]
});
I'm trying to send it to MySQL db via jquery's AJAX:
$.post("savePolygon.php", {polygon: poly});
I get this error in console:
TypeError: Cannot call method 'lat' of undefined
I've seen some other posts about saving polygons, and they all say to extract the latLng's from the poly's and save them in a db. When I do this though:
var latLngs = poly.getPath().getArray();
$.post("savePolygon.php", {polygon: latLngs});
I get the same error. It seems there is a function in array's prototype called 'lat'. I'd like to know how exactly can I extract those values and send them via AJAX, and also why do I get this error?

Use google.maps.geometry.encoding.encodePath() to encode the path. This method returns a string, perfect for storing into a DB. For reuse decode the string by using google.maps.geometry.encoding.decodePath()
Please note: the geometry-library isn't loaded by default, you must load it by appending &libraries=geometry to the src of the maps-API-script.
To explain why you can't store the path directly(e.g. as JSON):
when you store the path(array), which contains the LatLng's, you will lose the prototype of the LatLng's, which is essential because it defines the methods for retrieving the properties(lat() and lng() )

Related

Creating a dynamic JSON from C# to JavaScript

I am new at C# programming and I am developing an application based on geolocation for my Graduate.
I have a Javascript which is responsible for creating the map and inserting the markers. But the markers are inserted from a JSON file, like this:
{
"Id": 1,
"Latitude": -19.212355602107472,
"Longitude": -44.20234468749999,
"Descricao": "Conteúdo do InfoBox 1"
},
And after that. they call this file by this:
function carregarPontos() {
$.getJSON('js/pontos.json', function(pontos) {
$.each(pontos, function(index, ponto) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(ponto.Latitude, ponto.Longitude),
title: "Meu ponto personalizado! :-D",
map: map
});
});
});
}
carregarPontos();
My problem is I need to have those points from MySql DB.
I created a DataTable where I have the information I need to pass to this JSON, but I don't have any clues regarding how to make it.
Any help? Please keep in mind I am a noob at C# and JSON programming.
While the standard C# library offers some JSON support, you're better off using the free JSON.Net library from Newtonsoft. You can add it to your project in Visual Studio through the NuGet package manager (Project > Manage NuGet packages).
Then make sure your file has:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
To parse a JSON, just write dynamic json = JObject.Parse(str);
Then you can access its properties just like you would in JavaScript, the only difference being that undefined properties will return null.
dynamic json = JObject.Parse("{example: \"Hello world\"}");
Console.Write(json.example); // prints "Hello world"
To write a JSON, just create a JObject and then append strings, numbers, JArrays and JObjects to it.
dynamic json = new JObject();
json.example = "Hello world";
json.myArray = new JArray(1, 2, 3, 4);
Console.Write(json);
// {
// "example": "Hello world",
// "myArray": [
// 1,
// 2,
// 3,
// 4
// ]
// }
as far as I understand you have some data stored in your sql database from where you will fetch the data and pass to a javascript function.
If that is the case then you can refer to this link.
Pass json/javascript data/objects to c# function using ajax
The example given is using aspx approach and not the MVC but it will be similar.

How to pass LatlngBounds object to nodejs server using javascript

I want to pass a LatlngBounds object from a client to nodejs server.
var bounds = map.getBounds();
socket.emit('sendbounds', bounds);
In the server:
socket.on('sendbounds',function(data){
console.log(data);
data.getNorthEast();// undefined method getNorthEast()
}
The server can get the data sent from the client. However I am unable to use method getNorthEast().
My solution is to create an object LatlngBounds:
bounds = new google.maps.LatLng(data.Ea.k, data.va.j),
new google.maps.LatLng(data.Ea.j, data.va.k));
However this is not recommended because we cannot sure the key names are always 'Ea' and 'va'.
I notice that sometimes the key names are "Fa" and wa". They are "undocumented properties". They change with API releases.
Any solution to solve this problem?
I tried it that way, too, but had the same problem: Can't rely on the variable names.
Instead, I passed it to the server as a string instead of an object:
corners = map.getBounds();
var c = corners.toString();`
Then use whatever AJAX library to send the string to the server.
It looks something like this:
((33.94310833405608, -118.44952616442868), (33.985820303992334, -118.34120783557125))
You will have to pick it apart using a regexp, but at least it's reliably formatted.

Reload points on a Map in using the Google Maps API v3

I'm trying to reload points on a map based on when someone clicks a button.
I have a couple json objects saved in memory, "data" and "data2". The following code takes the "data2" JSON file and sets it equal to the "data" JSON file and then triggers a map reload event.
dataholder = data
function myFunction() {
data = dataholder
window.data = data2;
google.maps.event.trigger(map, 'resize');
}
Currently, the map won't reload with the new set of data. However, I am not getting any error messages.
There's no map reload event. The resize event, when it comes from a window resize, will at most recalculate the map bounds and reproject the existing features (markers, polylines, polygons). For this case in particular, I don't think that manually triggering the resize event will have any effect.
In second place, you say you have two json files, but your code suggest you instead have two json objects already in memory (meaning you don't need to perform aditional requests to retrieve the value of data2). The rest of the answer will assume that.
If your original collection of markers came from "data", which is a collection of LatLng pairs, and you want to replace the markers for the contents of "data2" the process would be:
1.- Push the markers into an object where you can find them later on
var markers=[];
for(onemarker in data) {
var newmarker=new google.maps.Marker({map: map, position: new google.maps.LatLng({onemarker.lat, onemarker.lng}) });
markers.push(newmarker);
}
2.- When you want to replace the markers, first purge the markers array
while(markers.length) {
var oldmarker=markers.pop();
oldmarker.setMap(null);
};
3.- Fill the markers array with the data from the data2 object
for(onemarker in data2) {
var newmarker=new google.maps.Marker({map: map, position: new google.maps.LatLng({onemarker.lat, onemarker.lng}) });
markers.push(newmarker);
}
For this kind of markers, as for the regular features, there's no instantaneous binding between the object and the underlying data. This is slightly different for the new google.maps.Data() layer for which you can skip the iteration and just feed it a geoJSON array. You still need to have an object to store the current markers, or else you won't have a way to access them when you want to remove them.

SAPUI5 Create OData entity with dates - generates incorrect request payload that ends in CX_SXML_PARSE_ERROR

We are trying to create an entity that has date attributes via an odata service. Backend is an sap system. This entity has only 3 key attributes plus a bunch of other attributes. We have identified that dates in the keys are the root cause of the problem.
Keys:
Pernr type string,
begda type datetime
endda type datetime.
The code below, (which does not work), has been severely simplified when trying to troubleshoot the issue. At the moment, it reads an entity from an entity set and immediately tries to create one with exactly the same data.
Code:
var oODataModel = new sap.ui.model.odata.ODataModel("/sap/opu/odata/sap/Z_PERSONAL_DATA_SRV/");
//Test entity to be saved
var entity = null;
//Handler for read error
var handleReadE = function (oEvent){
alert("error");
};
//Handler for read success
var handleRead = function (oEvent){
//Get the data read from backend
entity = oEvent.results[0];
//Try to create a new entity with same data
oODataModel.create('/PersDataSet', entity, null, function(){
alert("Create successful");
},function(oError){
alert("Create failed", oError);
});
};
oODataModel.read("/PersDataSet", null, [], true, handleRead, handleReadE);
In the gateway error log, an xml parsing error appears. In this log, we can see the request data and it can be seen that the dates are transported with String types. These dates are defined in the service as DateTimes so the request is rejected.
Example:
<m:properties>
<d:Pernr m:type="Edm.String">00000001</d:Pernr>
<d:Endda m:type="Edm.String">9999-12-31T00:00:00</d:Endda>
<d:Begda m:type="Edm.String">1979-05-23T00:00:00</d:Begda>
When the entity is read, the backend does not send any type information. It sends like the following example:
<m:properties>
<d:Pernr>72010459</d:Pernr>
<d:Endda>9999-12-31T00:00:00</d:Endda>
<d:Begda>1876-07-21T00:00:00</d:Begda>
And, indeed, if we try to save the same info without the type=".." it works. So the problem are the incorrect types ODataModel.create adds to the xml.
My question is:
Can I tell ODataModel.create to not add this type info? It is not doing a good job inferring the types.
Can anyone share an example reading and writing dates through odata?
Thank you very much in advance.
the data returned from oODataModel.read is raw, before you post you need to parse it
var handleRead = function (oEvent){
//Get the data read from backend
entity = oEvent.results[0];
var newEntity = jQuery.extend({},entity);
delete newEntity.__metadata;
newEntity.Begda = new Date(entity.Begda);
newEntity.Endda = new Date(entity.Endda);
//Try to create a new entity with same data
oODataModel.create('/PersDataSet', newEntity, null, function(){
why not use json instead of xml?
Thanks all for the help.
We got this working accounting for the following:
The problem of the wrong types appended to the attributes comes from the read itself. The object returned by read has a __metadata attribute which describes the values. In this object the dates are set with type=edm.string, even when the service says they are DateTime. To me this is a bug of the .read function.
When trying to use the same object to save, create sees the __metatada on the entry and uses those values, producing type edm.string type for the dates. This caused the request to be rejected. Manually changing these __metadata.properties...type to Edm.DateTime makes it work.
In the end, we did the following:
Dates are parsed manually from the Odata response, creating a js Date
object from the strings in format "yyyy-mm-ddT00:00:00", to make it work with control bindings. When we want to save, the reverse is done.
The object to be created is a new object with
only the attributes we care (no __metadata)

Passing googlemapsv3 through web sockets?

Is it possible to pass a googlemap through a web socket like this? (from client)
var mapOptions = {
center: pathCoordinates[0],
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var gmap = new google.maps.Map(document.getElementById("mapCanvas"), mapOptions);
$(function(){
socket.emit('smap', pathCoordinates, data, gmap);
});
I am trying to pass my map to the server side code where it can use it to plot new markers on it. I'm getting this error with the way it's currently set up:
Uncaught TypeError: Converting circular structure to JSON
When passing objects via web-sockets, the object gets converted into a JSON string. The particular error Converting circular structure to JSON is due to the object gmap containing circular references, which JSON.stringify does not support.
Furthermore, JSON does not support functions, so even if you could pass the gmap object to the server, calling gmap.doSomething wont work, as the functions are not preserved.
A better solution would be to pass marker data to the client, and have the client plot it on the map:
socket.on('data', function(markerData){
map.doSomething(markerData);
});

Categories

Resources