Raster: How to get elevation at lat/long using python? - python

I also posted this question in the GIS section of SO. As I'm not sure if this rather a 'pure' python question I also ask it here again.
I was wondering if anyone has some experience in getting elevation data from a raster without using ArcGIS, but rather get the information as a python list or dict?
I get my XY data as a list of tuples.
I'd like to loop through the list or pass it to a function or class-method to get the corresponding elevation for the xy-pairs.
I did some research on the topic and the gdal API sounds promising. Can anyone advice me how to go about things, pitfalls, sample code? Other options?
Thanks for your efforts, LarsVegas

I recommend checking out the Google Elevation API
It's very straightforward to use:
http://maps.googleapis.com/maps/api/elevation/json?locations=39.7391536,-104.9847034&sensor=true_or_false
{
"results" : [
{
"elevation" : 1608.637939453125,
"location" : {
"lat" : 39.73915360,
"lng" : -104.98470340
},
"resolution" : 4.771975994110107
}
],
"status" : "OK"
}
note that the free version is limited to 2500 requests per day.

We used this code to get elevation for a given latitude/longitude (NOTE: we only asked to print the elevation, and the rounded lat and long values).
import urllib.request
import json
lati = input("Enter the latitude:")
lngi = input("Enter the longitude:")
# url_params completes the base url with the given latitude and longitude values
ELEVATION_BASE_URL = 'http://maps.googleapis.com/maps/api/elevation/json?'
URL_PARAMS = "locations=%s,%s&sensor=%s" % (lati, lngi, "false")
url=ELEVATION_BASE_URL + URL_PARAMS
with urllib.request.urlopen(url) as f:
response = json.loads(f.read().decode())
status = response["status"]
result = response["results"][0]
print(float(result["elevation"]))
print(float(result["location"]["lat"]))
print(float(result["location"]["lng"]))

Have a look at altimeter a wrapper for the Google Elevation API

Here is the another one nice API that I`v built: https://algorithmia.com/algorithms/Gaploid/Elevation
import Algorithmia
input = {
"lat": "50.2111",
"lon": "18.1233"
}
client = Algorithmia.client('YOUR_API_KEY')
algo = client.algo('Gaploid/Elevation/0.3.0')
print algo.pipe(input)

Related

How to reorder Data from yahoo finance(Python)?

I'm trying to write down a python script that allow me to get some items of financial statement from Yahoo.I've tried with yahoofinancials library, but I can get only an entire page of data:
For istance,with this code:
from yahoofinancials import YahooFinancials
yahoo_financials = YahooFinancials('AAPL')
print(yahoo_financials.get_financial_stmts('annual', 'balance'))
I will get this:
{
"balanceSheetHistory": {
"AAPL": [
{
"2016-09-24": {
"otherCurrentLiab": 8080000000,
"otherCurrentAssets": 8283000000,
"goodWill": 5414000000,
"shortTermInvestments": 46671000000,
"longTermInvestments": 170430000000,
"cash": 20484000000,
"netTangibleAssets": 119629000000,
"totalAssets": 321686000000,
"otherLiab": 36074000000,
"totalStockholderEquity": 128249000000,
"inventory": 2132000000,
"retainedEarnings": 96364000000,
"intangibleAssets": 3206000000,
"totalCurrentAssets": 106869000000,
"otherStockholderEquity": 634000000,
"shortLongTermDebt": 11605000000,
"propertyPlantEquipment": 27010000000,
"deferredLongTermLiab": 2930000000,
"netReceivables": 29299000000,
"otherAssets": 8757000000,
"longTermDebt": 75427000000,
"totalLiab": 193437000000,
"commonStock": 31251000000,
"accountsPayable": 59321000000,
"totalCurrentLiabilities": 79006000000
}
}
]
}
}
I want to get every single element, such as "cash" and put it in a variable or an array with all these data,in order to get the single number.
So,for example, if I would get "cash",I would have a variable or an array/list that allow me to get the number(in this case 20484000000,for cash).
I hope I’ve made myself clear.
Someone knows how to do it?Thank you.
Since the output is in json format we must work with json.
from yahoofinancials import YahooFinancials
import json
yahoo_financials = YahooFinancials('AAPL')
w = yahoo_financials.get_financial_stmts('annual', 'balance')
print(w["balanceSheetHistory"]["AAPL"][2]['2019-09-28']['totalLiab'])
change 'totalLiab' to get desired data and to change '2019-09-28' you must also change [2].

Extracting values from json containing list as values to key

i am currently doing a data science project (beginner) and have the following scenario :
I have a dataframe with Pincode , address and city (approx 57000 rows)
I need the geo coordinates of the same
i am trying to use the Bing Map API to get the coordinates in python. But i am stuck at parsing the Json response.
pincodelist=[]
import json
i=0
for i in range(5): #just trying with first 5 rows
countryRegion = "IN"
locality = df_all.iloc[13,6] #references the location column
postalCode =df_all.iloc[13,12] #references the pincode column
addressLine = df_all.iloc[13,0] #references the address
BingMapsKey = 'my api key'
url="http://dev.virtualearth.net/REST/v1/Locations?countryRegion="+str(countryRegion)+"&locality="+str(locality)+"&postalCode=" + str(postalCode)+"&addressLine="+str(addressLine)+"&key="+str(BingMapsKey)
# make the GET request
results = requests.get(url).json()
pincodelist.append([
addressLine,
postalCode,
results(['resourceSets']['resources']['bbox'])])
print(pincodelist)
I get the following error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-198-396207c04bc6> in <module>
20 addressLine,
21 postalCode,
---> 22 results(['resourceSets']['resources']['bbox'])])
23 print(pincodelist)
24
TypeError: list indices must be integers or slices, not str
can somebody please help me how to parse this json response? the info i need is "bbox" which contains the coordinates.
{
"authenticationResultCode":"ValidCredentials",
"brandLogoUri":"http://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright":"Copyright © 2020 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
"resourceSets":[
{
"estimatedTotal":1,
"resources":[
{
"__type":"Location:http://schemas.microsoft.com/search/local/ws/rest/v1",
"bbox":[
12.91842713075696,
77.56459359208381,
12.926152565898313,
77.57516165693963
],
"name":"Banashankari, India",
"point":{
"type":"Point",
"coordinates":[
12.922289848327637,
77.56987762451172
]
},
"address":{
"adminDistrict":"KA",
"adminDistrict2":"Bengaluru",
"countryRegion":"India",
"formattedAddress":"Banashankari, India",
"locality":"Bengaluru"
},
"confidence":"High",
"entityType":"Neighborhood",
"geocodePoints":[
{
"type":"Point",
"coordinates":[
12.922289848327637,
77.56987762451172
],
"calculationMethod":"Rooftop",
"usageTypes":[
"Display"
]
}
],
"matchCodes":[
"Good"
]
}
]
}
],
"statusCode":200,
"statusDescription":"OK",
"traceId":"4e23d3d9bef84411846539f3113cc06b|DU00000D7F|0.0.0.1|Ref A: F8AB7E576A9B47B1A86B3DE04F1058A9 Ref B: DB3EDGE1616 Ref C: 2020-05-24T11:30:41Z"
}
Also would be helpful if you can refer any other location data service considering the numbers of rows to query. As a student a paid service is not feasible for me.
resourceSets is a list of objects, as can be seen by the square brackets that follow the key, so you need to specify a numeric index to get an element out of it. The same goes for the resources key.
{'resourceSets': [{'estimatedTotal': 1, 'resources': [{'__type': ...
In you example, there is only one resourceSet, so we can just get the first element:
# resource sets - a list
resource_sets = results['resourceSets']
# resource set object
resource_set = resource_sets[0]
# resources - a list
resources = resource_set['resources']
# first resource
resource = resources[0]
# bbox - a list with 4 numbers inside
bbox = resource['bbox']
# Or in one line:
results['resourceSets'][0]['resources'][0]['bbox']
Parse the response into json using json.parse.
I tried doing it in javaScript and assigned the json response to a variable t.
was able to extract using this reference, some keys have list as their values that could be the problem you are facing.
t.resourceSets[0].resources[0].bbox
(4) [12.91842713075696, 77.56459359208381, 12.926152565898313, 77.57516165693963]

Python Key Value Error (Json)

I am trying to grab this data and print into a string of text i am having the worst! issues getting this to work.
Here is the source i am working with to get a better understanding i am working on an envirmental controller and my sonoff switch combined
https://github.com/FirstCypress/LiV/blob/master/software/liv/iotConnectors/sonoff/sonoff.py this code works for two pages once completed so ignore the keys for tempature etc
m = json.loads(content)
co2 = m["Value"]
I need the value of "Value" under the "TaskValues" it should be either a 1 or a 0 in almost any case how would i pulled that key in the right form?
"Sensors":[
{
"TaskValues": [
{"ValueNumber":1,
"Name":"Switch",
"NrDecimals":0,
"Value":0
}],
"DataAcquisition": [
{"Controller":1,
"IDX":0,
"Enabled":"false"
},
{"Controller":2,
"IDX":0,
"Enabled":"false"
},
{"Controller":3,
"IDX":0,
"Enabled":"false"
}],
"TaskInterval":0,
"Type":"Switch input - Switch",
"TaskName":"relias",
"TaskEnabled":"true",
"TaskNumber":1
}
],
"TTL":60000
}
You can get it by
m['Sensors'][0]['TaskValues'][0]['Value']
"Value" is nested in your json, as you've mentioned. To get what you want, you'll need to traverse the parent data structures:
m = json.loads(content)
# This is a list
a = m.get('Sensors')
# This is a dictionary
sensor = a[0]
# This is a list
taskvalue = sensor.get('TaskValues')
# Your answer
value = taskvalue[0].get('Value')

combining two pandas dataframes as single json output

I'm trying to combine two pandas dataframes into a single JSON output.
The json output below is the result from this code - df.to_json(orient = "split")
{
columns: [],
index: [],
data: [
[
"COMPANY ONE",
"123 HAPPY PLACE",
"GOTHAM CITY",
"NJ",
12345,
"US",
8675309,
"",
"",
"",
"",
""
],
[.....]
]
}
A little background, I get the data from a csv file, and usually I have to separate the file in two parts, one good and the other bad. I've been using pandas for this process, which is great. So df contains the good data and say dfbad contains the bad data.
I used df.to_json(orient = "split") to output the good data, which I really like the structure of it. Now I want to do the same thing for the bad data, same structure, so something like this:
[{good}, {bad}]
I apologize in advance if the example above is not clear.
I tried to this:
jsonify(good = df.to_json(orient = "split"), bad = dfbad.to_json(orient = "split"))
But i know this is not going to work because the result for good and bad are turned into a string; which I don't want, I want to be able to have access to it.
data_dict = {}
data_dict['bad'] = dfbad.to_dict()
data_dict['good'] = df.to_dict()
return pd.json.dumps(data_dict)
This returns fine as a json, but not the structure I want, the way .to_json(orient = "split") does, unless I have to customize it.
Can anybody help with this issue? or can pinpoint in another direction how to solve this issue.
Thanks in advance!
UPDATE:
I found the solution, here is what I did:
good_json = df.to_json(orient="split")
bad_json = dfbad.to_json(orient="split")
return jsonify(bad = json.loads(bad_json), good = json.loads(good_json))
I added json.loads, you have to import it - import json - and it's now returning as a JSON output. If you have other suggestions, please let me know. I'm open to learn more about Pandas.

How to find locations near a given location

I am trying to create a Bounding Box (or a circle) for the given latitude and longitude with some distance(or radius) using Python3.
I have gone through the previous solutions for this problem but I am having some doubt on how it works. There are some variables like halfsideinKm and some degree to radian and radian to degree conversion and I am unable to understand what are those conversions for and how it works.
Given lat and long finding binding box
Geocoding calculate bounding box
I have a database collection Locations(in MongoDB) which holds the lat and long.
My Requirement is if I enter a lat and long I want to have the list of Places(from my mongodb) which lie inside of the Bounding Box region(with a distance of say 20 Km).
Can anyone provide me with a solution for this problem or some explanation on how those codes work?
Can this be achieved using geopy?(because it says something about great circle distance calculation)
Database values
{
"place_id":"151142295",
"osm_type":"relation",
"osm_id":"65606",
"lat":"51.5073219",
"lon":"-0.1276474",
"display_name":"London, Greater London, England, United Kingdom",
"class":"place",
"type":"city",
"importance":0.9754895765402
},
{
"place_id":"4566287",
"osm_type":"node",
"osm_id":"485248691",
"lat":"42.988097",
"lon":"-81.2460295",
"display_name":"London, Ontario, Canada",
"class":"place",
"type":"city",
"importance":0.6515723047601
}
(just a sample of how data is stored in my db)
The very "first" thing you must do is change how you are storing your data if you intend to use geospatial queries with MongoDB. You have the option of legacy coordinate pairs or GeoJSON format. But your current storage with "lat" and "long" in separate fields and also as "strings" will not work.
Here is a schema fix for your collection, written for the mongo shell because this should be a one off operation. I'm advising on GeoJSON, as it is generally compatible with quite a few libraries, and all distances returned are in kilometers rather than radians.
var bulk = db.collection.initializeUnorderedBulkOp(),
count = 0;
db.collection.find().forEach(function(doc) {
bulk.find({ "_id": doc._id }).updateOne({
"$set": {
"location": {
"type": "Point",
"coordinates": [parseFloat(doc.lon),parseFloat(doc.lat)]
}
},
"$unset": { "lat": "", "lon": "" }
});
count++;
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.collection.initializeUnorderedBulkOp();
}
});
if ( count % 1000 !=0 )
bulk.execute();
Now the data is fixed and compatible with an index, create the index. What makes sense here with GeoJSON data is a "2sphere" index:
db.collection.createIndex({ "location": "2dsphere" })
Now you are ready to query. Sticking with the shell as the python syntax is identical and I don't know your library calls:
db.collection.find({
"location": {
"$nearSphere": {
"$geometry": {
"type": "Point",
"coordinates": [lon,lat]
},
"$maxDistance": distance
}
}
})
This query uses $nearSphere which will calculate properly on distance based on the curvature of the earth, ideal for real location data. Your three variables there are the "longitude", "latitude" ( in that order ) in the coordinates array and the "distance" under $maxDistance that you want to find things within that radius.
This is a very simple query procedure once your data is suitable and the required geospatial index is in place.
No need for messy calculations in your client, as the server does all the work.
The links to the relevant documentation parts are all included for your reference. Read them and learn more about geospatial queries with MongoDB.

Categories