My intention is to utilize the coordinates that are returned by geolocation in order to generate directions to a given destination, without the visitor having to manually input their address. However, since these coordinates seem to vary from browser to browser, whereby some sets are accurate and other sets are not accurate at all, I am beginning to think this will be impossible.
The code below apparently has very little impact on the accuracy of the returned values.
var options = {
enableHighAccuracy: true,
timeout: Infinity,
maximumAge: 0
};
Is there another way to improve the accuracy of the coordinates, so that the coordinates actually become usable?
Based on the Official Google Documentation, the Google Maps Geolocation API returns a location and accuracy radius based on information about cell towers and WiFi nodes that the mobile client can detect. The protocol used to send this data to the server and to return a response to the client.
In Geolocation request, you must specify a key in your request. The request body must be formatted as JSON.
You may include 'radioType' in the API call. The mobile radio type supports 'lte, gsm, cdma, and wcdma'. While this field is optional, it should be included if a value is available, for more accurate results.
For more details regarding Maps Geocoding API, please follow this link: https://developers.google.com/maps/documentation/geocoding/intro
Related
I have the following description of an API. How do I call this API in my react app or through postman? I don't understand the endpoints in it.
Deployed a CORS-enabled API for IP geolocation and weather lookup at
https://weathersync.herokuapp.com.
There are two endpoints:
/ip
Get the geographic location of the requestor’s IP
/weather/$lat,$lng
Get weather for a given latitude & longitude
I tried https://weathersync.herokuapp.com/weather/28.704059,77.102490 in postman but it doesn't work. Also, https://weathersync.herokuapp.com/?ip=192.168.0.106 doesn't work. Any help is appreciated aI i am new to APIs
Through simple trial and error I managed to determine that this API expects you to call it like this for the /ip route:
https://weathersync.herokuapp.com/ip?73.119.54.218
Note that this is pretty unusual and would be considered incorrect by most API designers. I would expect it to be /ip/73.119.54.218 instead, but the server is not set up correctly to handle that.
Also, as TKoL mentioned in the comments, an IP like 192... will never work, because it is a local IP address that is not visible to the outside world beyond your network. If the server attempts to lookup anything based on that IP address, it will likely not find anything, or even worse it might find something about a computer inside of its datacenter, in which case it could return data that is subtly incorrect from your point of view. You can find your external IP with services like iplocation.net.
Your weather example works fine for me as-is (try clicking below in a browser):
https://weathersync.herokuapp.com/weather/28.704059,77.102490
I did not try Postman, but it may not be working for you because it does not send the same HTTP headers as a browser does. Some servers expect certain headers to be sent. You can manually configure the headers in Postman to mimic a browser, which should work if that is the case.
While taking screenshot of the current map using arcgis JavaScript, I could see that we have two ways to take the screenshots.
I could see same question asked here
using /export of url
using print task api
var printTask = new esriLoader.PrintTask(PrintTaskServiceUrl);
esriLoader.Config.defaults.io.proxyUrl = proxyUrl;
esriLoader.Config.defaults.io.alwaysUseProxy = true;
var template = new esriLoader.PrintTemplate();
template.exportOptions = {
width: 1015,
height: 633,
dpi: 96 // if 200 ,map image will get good quality
};
template.format = "JPG";
template.layout = "MAP_ONLY",
template.preserveScale = false;
template.showLabels = true;
template.showAttribution = false;
template.layoutOptions = {
"legendLayers": [], // empty array means no legend
"scalebarUnit": "Miles",
"copyrightText": "<div>xxx</div>",
}
var params = new esriLoader.PrintParameters();
params.map = map;
params.template = template;
printTask.execute(params, success, error);
So, what is the difference between these 2 methods?
Is the REST API provided by ArcGIS Server to generated map images.
Is the Javascript object with in ArcGIS JavaScript SDK.
The PrintTask will use the Export Web Map Task from REST api to generate the map image. PrintTask provides a simple way of creating images. On the other hand, if you want to use the REST API directly you can do so, by using esri\request object, but you would have to generate all the required parameters as described by the API.
Disclaimer: I just joined and don't have reputation to comment; hence I have to post it as an answer to original question, which following is not.
Is there any advantage when using REST API directly or vice versa?
As T Kambi stated, using PrintTask, if available, is easier. Accessing Export Web Map Task REST end point directly may be beneficial in some cases, for example:
Web_Map_as_JSON parameter needs to be modified before request is
sent to the Export Web Map Task Geoprocessing service. For example, resources not present in the map need to be added, layers' visibility needs to be changed, tokens for secured services need to be supplied, etc.
The request for map image is sent from outside of ArcGIS API for JavaScript environment. There may be no actual map and one only wants to use ArcGIS Server capabilities to fuse services' images and utilize a Layout Template.
The Export Web Map task may be accessed either from client or server side. In the latter case, a kind of "Print Task proxy" may help with printing secured services; for example, eliminate need for custom printing service in applications utilizing Long-lived Tokens.
Answering the original question now.
The Export Map REST end point is specific to a MapServer service and allows for producing a service image for given extent, specified layers, spatial reference, etc.
Ultimately, PrintTask sends request to Export Web Map Task REST end point. Export Web Map Task is an interface for producing a map image, possibly with multiple services present and graphics, per provided Web_Map_as_JSON parameter. It also provides an option to surround the map image with a layout, predefined as an ArcGIS template (stored on the server). For example:
https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task/execute
After executed, the value of url in provided results is reference to the map image.
Export Web Map Task interface results
Note: Web Map as JSON parameter can be observed in browser's developer tools after PrintTask request is sent by the API. In this case, it is taken from ESRI's Print Dijit example:
(cannot post another link)
I am looking to display many routes on one instance of map, each route with different color. For it I created an array of DirectionsRenderer objects and assigning separate DirectionsRenderer for each route.
The problem is GoogleMap component displays only first 10 DirectionsRenderer, I was not able to find any info on this limitation in google developers website. Is there any way to use more than 10 DirectionsRenderers at same time?
Thanks for help in advance.
Just to add to what #geocodezip said:
"I was not able to find any info on this limitation in google developers website."
Here you go:
Usage limits and
policies
-Up to 8 waypoints per request, plus the origin and destination. // 10 overall
-50 requests per second, calculated as the sum of client-side and server-side queries.
-2,500 free requests per day, calculated as the sum of client-side and server-side queries; enable billing to access higher daily quotas,
billed at $0.50 USD / 1000 additional requests, up to 100,000 requests
daily.
When Google returns a NOT_FOUND response to a direction request with waypoints, the documentation says
NOT_FOUND indicates at least one of the locations specified in the requests
origin, destination, or waypoints could not be geocoded.
But it doesn't tell me which one is invalid...
I realise I could then attempt to geocode each address individually to find the bad address, but that is wasting a lot of geocoding requests, given I have about 20 waypoints, and given Google could just tell me which one failed...
Is there a way to do this?
My fallback is to geocode the addresses before I save them, however I'd prefer not to do this, if I can get google to tell me which waypoint failed.
Normally, the response comes back with warnings, and I thought the bad address may come back in that, however I think that only happens if a route can be built in the first place.
Warning items are intended to display information when a route has been found, you are right. For example, it is telling that the walking directions mode results are in beta.
Sample: http://maps.googleapis.com/maps/api/directions/json?origin=Boston,MA&destination=Concord,MA&waypoints=Charle,MA&mode=walking
For the problem you depicted (waypoint is not found), the response of the webservice is really short. Sample call with a non-working waypoint:
http://maps.googleapis.com/maps/api/directions/json?origin=Boston,MA&destination=Concord,MA&waypoints=Chle,MA
Result:
{
"routes" : [],
"status" : "ZERO_RESULTS"
}
The google maps Directions API is not currently helping for your case, and you also cannot try to geocode all your waypoint at once. Furthermore, the geocode api will throw an error if you exceed 5 simultaneous requests, so you initial workaround idea may be limited.
As a workaround (but not perfect, as the results between this service and gmaps service can be different), you could try to use other geocoding services, such as the one provided by OpenStreetMap: http://wiki.openstreetmap.org/wiki/Nominatim#Search
You still have to do it one-by-one, but you won't be getting a "query limit exceeded" error.
I'm using the following to successfully capture user's location (mobile browser):
<script>
if ( navigator.geolocation ) {
navigator.geolocation.getCurrentPosition(handlePosition);
}
function handlePosition(pos) {
//this passes lat/long to additional code
}
</script>
This works, but often times the browser will seemingly cache the location data. The page that calls this geolocation code shows information relative to the user's location, so what happens is the user can move (change location), the page is reloaded, but the previous location data is used (showing incorrect data). Sometimes the page will have to be refreshed once or even twice for the page to use new location data.
Does anyone know of any means to force the code to get and use "up to date" location data each time script is executed?
FWIW, I'm experiencing problem in iOS Safari (6.1). Have not been able to test in Android yet.
Thanks for reading and for any help.
Edit: As Oleksiy has written in his answer, the Geolocation API now supports this. You can add {maximumAge: 0} as the third option parameter of getCurrentPosition. There is also a timeout and a high accuracy option available in the PositionOptions as noted in the specification.
Your navigator call would change to the following:
navigator.geolocation.getCurrentPosition(
handlePosition,
(error)=>{},
{maximumAge:0}
);
No can't be done. You don't have any control over the browser geolocation other than the code in your example. The html5 geo location api is very, very limited and that is a pain. I also had a question whether I could ask it if permission for the domain had already been granted and the answer was also no.
The problem is that the api is implemented in the browser itself and that are just no endpoints for these kind of functions.
What you could do is make an array in js to store previous locations and before you update your view test against that array to see if you got a stale location.
You do have this ability now.
getCurrentPosition takes three parameters: success, failure and options
Try this:
<script>
if ( navigator.geolocation ) {
navigator.geolocation.getCurrentPosition(handlePosition, (error)=>{}, {maximumAge:0});
}
function handlePosition(pos) {
//this passes lat/long to additional code
}
</script>