I have a form and I want to add a "select location" option.
How can I do this, and how can I place a pin as the selected location?
You may want to consider using the Google Maps API, as davek already suggested.
The following example may help you getting started. All you would need to do is to change the JavaScript variable userLocation with the location chosen by your users from the drop-down field you mention.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps API Demo</title>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false"
type="text/javascript"></script>
</head>
<body onunload="GUnload()">
<div id="map_canvas" style="width: 400px; height: 300px"></div>
<script type="text/javascript">
var userLocation = 'London, UK';
if (GBrowserIsCompatible()) {
var geocoder = new GClientGeocoder();
geocoder.getLocations(userLocation, function (locations) {
if (locations.Placemark)
{
var north = locations.Placemark[0].ExtendedData.LatLonBox.north;
var south = locations.Placemark[0].ExtendedData.LatLonBox.south;
var east = locations.Placemark[0].ExtendedData.LatLonBox.east;
var west = locations.Placemark[0].ExtendedData.LatLonBox.west;
var bounds = new GLatLngBounds(new GLatLng(south, west),
new GLatLng(north, east));
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
map.addOverlay(new GMarker(bounds.getCenter()));
}
});
}
</script>
</body>
</html>
The above example would render a map like the one below:
The map will not show if the Google Client-side Geocoder cannot retreive the coordinates from the address.
Check out the Google Maps API. There's lots of information there and several examples:without knowing more about your environment/requirements it is difficult to be more specific.
Related
I'm trying to embed a Google Maps web view inside a PyQt5 Window. But the map is rendered correctly in plain HTML but throws an error while rendering in Python. I tried running the code separately in plain HTML and inside a PyQt5 Web view.
My HTML code is following
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Google Maps - gmplot</title>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=visualization&key=MY_KEY"></script>
<script type="text/javascript">
function initialize() {
var map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 18,
center: new google.maps.LatLng(12.980700, 80.188200)
});
var marker_icon_FF0000 = {
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAiCAYAAACwaJKDAAAABmJLR0QA/wD/AP+gvaeTAAACBklEQVRIia3VzUtUURgH4GdG/AiyZZShtWgXUbSIFtGqRYtqWRLhXyBYf0K6MaJQ2gRtayHtijYpleHKSCgIcRHoIiOSKEzLKea0OOeqTfPlzPzg5Qwz9zz3nXPvPTeneo7gNA4gjyI+Ygbva8z9L2cxi9BHOE+4msY+gliz6biayWE0R7GfMEcoEkJJzRH6CbnY+WiaVxEc6yY8KQOVq8eE7tj1WCV4qIswUyeY1QyhK8JDpWAP1m7vEMzqTkTXkrOZkYOEQoNogXAowiPE2wQuDqC9nktZJu0YSE72XRs2phrsMqup2OkG2vLpRB19DXaZJc3vQHv294Um0e3z8yigsNQkmuYXUMie5/npJtE0fz55YLiXsNHELdUbV2B4+4n2Y/Vmg+itCK4m558MdhBe7hCcJnRGdLDS0ox3E17XCb4h7IngeLX1zuFhD2G5BriytY4Tqmx9WXbh3Tnl99KsLkdwAbtrgVmO4/eDCuCkzd3/TL1glru9hF8lYJFwMoKPdgrCXqzfL0GfR7CIo42gcO9YCXopolONgnAC4W0Cv9l8dVxpBoWFGwmdiOC6Glc8X+3HlKeT6cOzOLzAjyaaBBc602ZzOHZ6vVkQ9kl7Qi6ip1qBwpdrEfwjPnFVU8+awuKrOC7hZ6vQlQ9baM3Ui379HsfVVqKf07jcSvRTGhfrOfgvIP3ECS77BDoAAAAASUVORK5CYII=",
labelOrigin: new google.maps.Point(10, 11)
};
new google.maps.Marker({
position: new google.maps.LatLng(12.980700, 80.188200),
icon: marker_icon_FF0000,
map: map
});
}
</script>
</head>
<body style="margin:0px; padding:0px;" onload="initialize()">
<div id="map_canvas" style="width: 100%; height: 100%;" />
</body>
</html>
This works fine but when I try to run this code inside a PyQt5 WebView Widget like following
# app.py
import gmplot
import sys
import os
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
class Browser(QtWebEngineWidgets.QWebEngineView):
def __init__(self):
super().__init__()
html = """
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Google Maps - gmplot</title>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=visualization&key=MY_KEY"></script>
<script type="text/javascript">
function initialize() {
var map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 18,
center: new google.maps.LatLng(12.980700, 80.188200)
});
var marker_icon_FF0000 = {
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAiCAYAAACwaJKDAAAABmJLR0QA/wD/AP+gvaeTAAACBklEQVRIia3VzUtUURgH4GdG/AiyZZShtWgXUbSIFtGqRYtqWRLhXyBYf0K6MaJQ2gRtayHtijYpleHKSCgIcRHoIiOSKEzLKea0OOeqTfPlzPzg5Qwz9zz3nXPvPTeneo7gNA4gjyI+Ygbva8z9L2cxi9BHOE+4msY+gliz6biayWE0R7GfMEcoEkJJzRH6CbnY+WiaVxEc6yY8KQOVq8eE7tj1WCV4qIswUyeY1QyhK8JDpWAP1m7vEMzqTkTXkrOZkYOEQoNogXAowiPE2wQuDqC9nktZJu0YSE72XRs2phrsMqup2OkG2vLpRB19DXaZJc3vQHv294Um0e3z8yigsNQkmuYXUMie5/npJtE0fz55YLiXsNHELdUbV2B4+4n2Y/Vmg+itCK4m558MdhBe7hCcJnRGdLDS0ox3E17XCb4h7IngeLX1zuFhD2G5BriytY4Tqmx9WXbh3Tnl99KsLkdwAbtrgVmO4/eDCuCkzd3/TL1glru9hF8lYJFwMoKPdgrCXqzfL0GfR7CIo42gcO9YCXopolONgnAC4W0Cv9l8dVxpBoWFGwmdiOC6Glc8X+3HlKeT6cOzOLzAjyaaBBc602ZzOHZ6vVkQ9kl7Qi6ip1qBwpdrEfwjPnFVU8+awuKrOC7hZ6vQlQ9baM3Ui379HsfVVqKf07jcSvRTGhfrOfgvIP3ECS77BDoAAAAASUVORK5CYII=",
labelOrigin: new google.maps.Point(10, 11)
};
new google.maps.Marker({
position: new google.maps.LatLng(12.980700, 80.188200),
icon: marker_icon_FF0000,
map: map
});
}
</script>
</head>
<body style="margin:0px; padding:0px;" onload="initialize()">
<div id="map_canvas" style="width: 100%; height: 100%;" />
</body>
</html>
"""
here = os.path.dirname(os.path.abspath(__file__)).replace('\\', '/')
base_path = os.path.join(os.path.dirname(here), 'dummy').replace('\\', '/')
self.url = QtCore.QUrl('file:///' + 'map.html')
self.page().setHtml(html, baseUrl=self.url)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.init_widgets()
self.init_layout()
def init_widgets(self):
self.browser = Browser()
self.browser.loadFinished.connect(self.load_finished)
def init_layout(self):
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.browser)
centralWidget = QtWidgets.QWidget()
centralWidget.setLayout(layout)
self.setCentralWidget(centralWidget)
def load_finished(self, status):
self.msg = QtWidgets.QMessageBox()
self.msg.setIcon(QtWidgets.QMessageBox.Information)
self.msg.setWindowTitle('Load Status')
self.msg.setText(f"It is {str(status)} that the page loaded.")
self.msg.show()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
I get this error on the console saying "js: You must enable Billing on the Google Cloud Project at https://console.cloud.google.com/project/_/billing/enable Learn more at https://developers.google.com/maps/gmp-get-started"
I mean why is it working in plain HTML file and not in the web view.
Screenshots -
(Running inside PyQT Widget)
(Running inside Browser as HTML)
Well first of all - do make sure that you billing account at google maps is enabled and this should solve your problem :)
besides that I must say that I have also played with google maps a little and it is a riddle for me. Sometimes it works without user's credential at all and sometimes not. No idea why the difference.
But really enabling paying is safe, unless you have thousands of API calls you won't get billed. Just do it and move forward.
This is what I would do.
I have a html file on my website domain (devodeliver.co.uk) which calls on my API Key with the code.
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=MY-KEY"></script>
In the Developers Console I have tried adding every combination of my domain URL as you can see below
But when I load my site it shows the map for a millisecond then returns with the error "Google Maps API error: InvalidKeyMapError https://developers.google.com/maps/documentation/javascript/error-messages#invalid-key-map-error_.bb # MY-KEY:32" - basically saying I haven't given my website permission to access that API Key. But even if I don't set any referrers, it come back with the same error message. I've also waited way over 5 minutes for the API to take affect. Please, what am I doing wrong?! I've spent almost 16 hours trying to figure this out & I can't seem to for the life of me. HELPPPP!
Full HTML code:
<html>
<head>
<style type="text/css">
#map
{
height:400px;
width:400px;
display:block;
}
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB7-LTLEupUWBJBWl1GpOWPwkMvxzf8itQ"></script>
<script type="text/javascript">
function getPosition(callback) {
var geocoder = new google.maps.Geocoder();
var postcode = document.getElementById("postcode").value;
geocoder.geocode({'address': postcode}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
callback({
latt: results[0].geometry.location.lat(),
long: results[0].geometry.location.lng()
});
}
});
}
function setup_map(latitude, longitude) {
var _position = { lat: latitude, lng: longitude};
var mapOptions = {
zoom: 16,
center: _position
}
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
var marker = new google.maps.Marker({
position: mapOptions.center,
map: map
});
}
window.onload = function() {
setup_map(51.5073509, -0.12775829999998223);
document.getElementById("form").onsubmit = function() {
getPosition(function(position){
var text = document.getElementById("text")
text.innerHTML = "Marker position: { Longitude: "+position.long+ ", Latitude:"+position.latt+" }";
setup_map(position.latt, position.long);
});
}
}
</script>
</head>
<body>
<form action="javascript:void(0)" id="form">
<input type="text" id="postcode" placeholder="Enter a postcode">
<input type="submit" value="Show me"/>
</form>
<div id="map"></div>
<div id="text"></div>
</body>
</html>
Here, when I tested it, it gives me the error "Google Maps API error: ApiNotActivatedMapError" on the JS console.
Take a look for this issue on: https://developers.google.com/maps/documentation/javascript/error-messages#deverrorcodes
When you use a library or service via the Maps-Javascript-API, and use a key, you need to activate the Google Maps JavaScript API .
Make sure to activate the Google Maps JavaScript API for your project.
Also,
take a look on this other topic about Enable the Google Maps Jvascript API: Google Map error: InvalidKeyOrUnauthorizedURLMapError
I'm trying to use the Google Maps geocoding service. I copied the code and it seems to find addresses fine (for example "13 Marine Terrace Aberystwyth") but not other places like "Rummers Wine Bar, Aberystwyth" even though the actual Google Maps website has no problem with them at all.
This is my code, slightly modified to be for the Aberystwyth area but otherwise copied form https://developers.google.com/maps/documentation/javascript/tutorial
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<script type="text/javascript"
/*you can use https if you want it secure!!! set java scrip sensor to true and read from gps!*/
src="http://maps.googleapis.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXo-tdDimvjIs&sensor=false®ion=GB">
</script>
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(52.4156, -4.0829);
var myOptions = {
zoom: 14,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
function code ()
{document.write(results[0].geometry.location);}
});
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width: 320px; height: 480px;"></div>
<div>
<input id="address" type="textbox" value="aberystwyth">
<input type="button" value="Encode" onclick="codeAddress()">
</div>
</script>
<script type="text/javascript">
code();
</script>
</body>
This is a link to it: http://users.aber.ac.uk/avh9/thesite/geocodeaber.html
Can anyone tell me why and how to fix it? or any alternative for geocoding....
There's a library called Places Library within Google Maps API. You can use its search() nearbySearch() or textSearch() methods to search for POIs and landmarks.
I'm showing a Google Map based on a street address supplied from an outside source.
My JavaScript is very simple, and I build the link like so
var googleMap = 'http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=' + address + '&ie=UTF8';
This is quick and easy, and works. But some of the incoming addresses aren't exactly addresses (they include some stuff which shouldn't be there).
When Google Maps can't make heads or tails of the address, it defaults to showing a map of USA. Unfortunately, I'm in Australia.
Is there any way using this lazy method to know if Google Maps couldn't match the address, or can I show Australia by default?
... or do I need to look at the API?
What about using maps.google.com.au? Note that the parameters might be a bit different.
http://maps.google.com.au/maps?q=Melbourne
http://maps.google.com.au/maps?q=Something-Garbage-That-Does-Not-Exist
You could also use the Maps API, as you suggested. Something like that would be very easy to do:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps Geocoding Default Location</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 400px; height: 300px;"></div>
<script type="text/javascript">
var address = 'Melbourne, Australia';
var map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.TERRAIN,
center: new google.maps.LatLng(-25.50, 135.00),
zoom: 3
});
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
map.setCenter(results[0].geometry.location);
}
});
</script>
</body>
</html>
Screenshot:
And another screenshot if you were to use address = 'Something Garbage That Does Not Exist':
Google Maps API can build a Direction from a source to a destination. In the following Google's example, each step are published into the HTML code: http://code.google.com/apis/maps/documentation/examples/directions-simple.html
I would like to get the Geocoding of each step of this direction, and store them in a array. I believe it's possible, but I don't see how to process.
Many Thanks for any answer.
Regards
Yes, you can get the individual steps from GDirections very easily.
First you have to make sure to pass the getSteps: true option when you call the GDirections.load() method. Then you can simply iterate through GDirections.getRoute(i).getStep(j), as in the following example:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps Simple Directions Demo</title>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false"
type="text/javascript"></script>
</head>
<body onunload="GUnload()">
<div id="map" style="width: 550px; height: 400px"></div>
<script type="text/javascript">
var map = new GMap2(document.getElementById("map"));
var directions = new GDirections(map);
directions.load('from: London, UK to: Glasgow, UK', { getSteps: true });
GEvent.addListener(directions, "load", function() {
if (directions.getNumRoutes() > 0) {
for (var i = 0; i < directions.getRoute(0).getNumSteps(); i++) {
directions.getRoute(0).getStep(i).getLatLng().lat();
directions.getRoute(0).getStep(i).getLatLng().lng();
directions.getRoute(0).getStep(i).getDescriptionHtml();
directions.getRoute(0).getStep(i).getPolylineIndex();
directions.getRoute(0).getStep(i).getDistance().meters;
directions.getRoute(0).getStep(i).getDuration().seconds;
}
}
});
</script>
</body>
</html>
Further reading and reference:
GDirections
GRoute
GStep