The Google Maps Places Autocomplete does not work as expected anymore.
https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete
When inserting a search string in the map (for example "ZKM"), it will give some recommendations in the drop down list. In this case it will be "ZKM | Zentrum für Kunst und Medientechnologie Karlsruhe, Lorenzstraße, Karlsruhe, Deutschland". When clicking this item, no marker will be placed on the map!
But when searching for "Karlsruhe" and clicking the first search result "Karlsruhe, Deutschland" the marker is placed correctly.
In the code a function called getPlace() ist called.
var place = autocomplete.getPlace();
The place should contain an object "geometry", but it does not.
Is there any workaround for this problem?
Please be sure you set 'geometry' field in autocomplete like this:
autocomplete.setFields(['address_component', 'geometry']);
Take a look at the beginning of the function:
if (!place.geometry) {
return;
}
A PlaceResult may, but must not have a geometry-property.
To clarify how the autocomplete works:
when you type something, the API will request the predictions(to populate the dropdown). Only when you select a place from the dropdown it requests the data(including the geometry) for the particular place.
Obviously there are inconsistencies of the used data(the API shouldn't suggest a place where no informations are accessible), but that's how it is, it may happen that you get a prediction without a place.
Workaround: AFAIK no
Looks like it has been fixed by Google :)
Yes, the place contains an object "geometry".
To find this, you should use this :
autocomplete.getPlace().geometry.location.lat() //for the latitude
autocomplete.getPlace().geometry.location.lng() //for the longitude
Related
I have added new dataset to carto Builder using .csv file. But there is null the_geom column. So when i create map using reactjs and carto.js via:
this.cartoClient = new carto.Client({ apiKey: 'key', username: 'user' });
<Map center={center} zoom={zoom} ref={node => { this.nativeMap = node && node.leafletElement }}>
<Basemap attribution="" url={CARTO_BASEMAP} />
<Layer
source={airbnb.source}
style={this.state.layerStyle}
client={this.cartoClient}
hidden={this.state.hidelayers}
/>
</Map>
and using airbnb.source
SELECT
cartodb_id, field_1,field_8, field_7, field_6, field_2, field_4, field_3, field_5,
ST_SetSRID( ST_MakePoint(
field_4,
field_3
),
4326
) AS the_geom,
ST_Transform(ST_Buffer(the_geom,0.001), 3857) as the_geom_webmercator
FROM (SELECT * FROM allreports) AS _camshaft_georeference_long_lat_analysis
Carto.js does not mark points on my map, so i get it clear. How should i workaround the_geom,the_geom_webmercator to get the map with points or the problem is somewhere else?
Does same SQL work in Builder? From where did you get it? Without seeing actual data one can only speculate what can be done, also your field names are not very helpful here. Or is it auto-generated SQL from Builder? I'm not sure if it is good idea to hack around that one, even if it works now, then these internal structures can change anytime. In general there are following scenarios how you get data to map:
Importer tries some heuristics from table structure to add it to map. For example if you have column names latitude and longitude, then the table will automatically geocoded, i.e. geom fields are filled and the table just works. Or if there is column city with English city names, then there is good chance also that it will be on map. So the easiest way is to use these field names, if you already have it in your data.
You can persistently geocode table using Carto SQL API, with something like UPDATE {tablename} SET the_geom = cdb_geocode_namedplace_point({city_column}, {province_column}, {country_column}) in the case of named places, or if you have wgs lat/lon fields then UPDATE {tablename} SET the_geom = st_setsrid(st_point({lon_column}, {lat_column}),4326). This way the the_geom will be filled. To make it sure I would also do UPDATE {tablename} SET the_geom_webercator = st_transform(the_geom, 3857). Of course you can use here st_buffer etc.
you can do also live geocoding query as you seem to try now, just be sure that there is unique cartodb_id, proper the_geom (in wgs84) and the_geom_webmercator (in epsg3857 projection, just as you have). This makes more sense if your data is somehow dynamically updated, otherwise I would do one-time UPDATE to the table.
use Builder geocoding analysis. This creates another 'virtual' live dataset with geocoded data, and this can be used in map view or further analyses. I'm afraid this cannot be done/shown in carto.js maps, this is within Builder only.
p.s. you can find more carto-related posts in https://gis.stackexchange.com/questions/tagged/carto
I've become the editor of a website that i didn't create. There is a map feature on one of the webpages and i've been asked to alter how the map initially loads on the webpage.
I don't know if the javascript that i'm looking at is original or whether it's some stock code provided by someone like Google. Anyhow, some of the code that i'm looking at looks like this....
var gridChoice = "";
if (osbounds) gridChoice = osbounds.gridStyle;
var gridUse = QueryString("g");
if (gridUse) gridChoice = gridUse;
switch (gridChoice)
....
....
....
In the comments, it states that using g in the QueryString should override what ever the code does.
It selects the type of grid displayed on the map. There is another selection that is identical to this that selects the type of map shown (Eg. Google road, Terrain, Hybrid, etc). The code used to select the type of map uses m in the QueryString. With the same comment - that m should override.
I have no idea how QueryString works or or what it does. I've tried to Google it but i can only find people asking for advice on places like this. I can't seem to find any documentation that describes the function, and how it works. I know there will be something out there but my Google-foo is weak on this one.
May someone describe to me what it does? Or link a source that exlains it well please?
Thanks.
It uses location.search (w3schools.com/jsref/prop_loc_search.asp) So it turns out that querystring is the name for the part of the URL that represents the parameters of a webpage. In this application, the parameters would be...GPS coordinates, type of map, type of grid, etc. The input in to the function QueryString selects the parameter to be looked at. It then parses the URL for that parameter and then returns the appropriate response.
I am using the Google Place service to obtain the place details for a result coming out from an auto complete. The problem is that executing getPlace() request on my autocomplete object returns undefined for the variable (var place). Have been around this issue for days now, can't get on it.
My page is : here, and
the example I am following is here.
error:
TypeError: place is undefined [testdebug.php:232]
main pieces of code:
window['auto_'+inputFieldID+'_autocomplete'] = new google.maps.places.Autocomplete(document.getElementById(inputFieldID));
window['auto_'+inputFieldID+'_autocomplete'].bindTo('bounds', map);
var place = window['auto_'+GoogleMapItems[LoopIndex]+'_autocomplete'].getPlace();
if (!place.geometry)
{
console.log('cannot resolve rendering.');
}
Thanks for your help.
Closure issue: loop index is used as 1 (value when loop finishes) instead of 0.
You can fix it using closure for loop index around event listener:
(function(LoopIndex) {
google.maps.event.addListener(window['auto_'+GoogleMapItems[LoopIndex]+'_autocomplete'], 'place_changed', function()
... {
});
})(LoopIndex);
This is one fix. Now another issue occurs: points is not defined
You are using variable points which seems has to contain information about markers. It is not defined in your code.
Update: Code as it is written now sets event listener to departure autocomplete only. See for loop. The only valid index is 0. If I load the page and write for example s into departure input I can select for example Sydney, New South Wales, Australia. After selection I get in console index 1 (which is wrong), GoogleMapItems[LoopIndex] returns arrival (which is wrong) and places are undefined which is correct because there is nothing in arrival autocomplete input. This is typical closure issue.
With my code change and selection from departure autocomplete I get loop index 0, GoogleMapItems[LoopIndex] returns departure, I get complete information for place, map is zoomed to Sydney and code fails because variable points is undefined.
So, variable points has to be defined somewhere and for loop has to be expanded to handle also other autocomplete parts of page.
I'm attempting to create a dynamic map using the latest Google Map API. Everything is going smooth so far. I do have a question of course:
How would I/you go about saving my current map?
Let's say you build a map with dynamic markers: Since everything is done via JavaScript, I need to get/set those values from a file/database.
I was thinking about outputting the entire google.map.Markers as a JSON and send it to a database as a string, but then if I have around 100 places, I'm not sure how well it would go and I'm worried about efficiency.
Is this the only way to do it and am I thinking properly? Basically your website users are allowed to place a marker on the map, which then are subject to confirmation of course. Once it's confirmed, that marker must be in the latest "version" of the map, so I must get that info from/into a database/file.
Thanks in advance!
I'm creating similar application and I implemented it this way:
I have a Marker table which has columns for each attribute that I'm using in markers (e.g. latitude, longitude, name, description, type, etc.) When someone adds a marker I'm just saving the attributes of the marker to the database. Next time I want to show the marker I'm just getting the attributes from database, encode them to JSON and attach to the page. Inside page I have the JS that grabs those attributes and creates the markers inside the map. Pseudocode:
//this is generated dynamically from DB.
var markers = [
{lat:115416,lng:26411},
{lat:115416,lng:26411}
];
//this is static, just grabs the dynamic bit and puts it on the map:
for (var i = 0; i < markers.length; i++){
//creates a marker object
var marker = new Marker({lat:markers[i].lat, lng:markers[i].lng })
//displays it on the map
map.addMarker(marker);
}
the benefit of this is that your data in the database is independent from map implementation, e.g. if in the future you decide to move to apple maps and it has different implementation you can just write different JS to handle the data. Also you can query over it, e.g. you can query for places that are close by looking at lat and lang, etc..
So I'm rewriting my first google maps app and I'm looking at how I create info windows on click of a marker and it seems very inefficent to be adding a listener for each. Previously I've used GInfoWindow and EBubble (http://econym.org.uk/gmap/ebubble.htm).
I was thinking that I could use jQuery to show a div with dynamic data if I had a hook for each marker to show the window and relevant marker info (pulled from JSON). I can see each marker has a unique id (e.g. mtgt_unnamed_2822) but I'm not sure how to predicte this.
Has anyone tried this before or know how to go about it?
Thanks
Denis
I don't know jQuery, but Javascript allows you to add your own custom Properties to any Object. So you can write stuff like this:
var marker = new GMarker(...);
marker.ID = "mtgt_unnamed_2822";
or
function createMarker(point,newid) {
var marker = new GMarker(point);
marker.ID = newid;
...
}
Be careful not to use "marker.id" because the API could use "id" as the obfuscated internal name for an existing property in some future release. In fact avoid Property names that start with a lower case letter.
Once you've attached the .ID Property to a marker, you can read the info from the marker.ID of any marker reference whenever you need it to make the jQuery call.