get centroid latitude and longitude of h3 hexagon - python

I know ho to get h3 hexagon ids for various resolutions and add them to a pandas dataframe containing latitudes and longitudes. Is it possible to get the centroid latitude and longitude of each h3 hexagon given its id? I saw function but do not know how to use it in this context cell_to_latlng. Any pointers would be very much appreciated. thanks.
PS:
import h3
dir(h3)
does not show cell_to_lat_lng btw?!
This does not work:
from h3 import h3
h3.cell_to_lat_lng('88396c0331fffff')
I get:
AttributeError: module 'h3.api.basic_str' has no attribute 'cell_to_lat_lng'

you can first create a new column in your pandas dataframe to hold the centroid latitude and longitude values. Then, for each row in the dataframe, you can use the cell_to_lat_lng function to convert the hexagon ID to its centroid latitude and longitude, and store the result in the corresponding row of the new columns.
E.G
import h3
# create new columns to hold centroid latitude and longitude
df['centroid_lat'] = 0.0
df['centroid_lng'] = 0.0
# iterate over rows in dataframe and compute centroid for each hexagon
for index, row in df.iterrows():
hex_id = row['hex_id']
lat, lng = h3.cell_to_lat_lng(hex_id)
df.at[index, 'centroid_lat'] = lat
df.at[index, 'centroid_lng'] = lng

There's currently a discrepancy between the docs and the released version of the h3-py library - the docs are for v4, but the released version is still v3 (v4 is in beta). In H3v3, the function you want is called h3_to_geo(hex_id).

Related

Combine latitude and longitude into same column while adding an 'x or y' column in Python

I have a database that requires input data to be in an atypical format. Normally latitude and longitude would be in separate columns. In this case I need to bring them into the same column and then add an additional column to differentiate coordinate type. I am a python novice so I am in a bit of a bind as to where to start.
I need to get from this:
Location
Latitude
Longitude
Place1
32.123
120.123
Place2
31.321
121.321
To this:
Location
Lat/Long
Coords
Place1
Latitude
32.123
Place1
Longitude
120.123
Place2
Latitude
31.321
Place2
Longitude
121.321
Edit - This is a simplified example. The data I'm working with has a dozen other columns all of which I would like to preserve, only lengthening with the lat/long columns.
My initial thought was to create two exports of dataframe, one where I take the latitude field and one where I take the longitude field, and then recombine them (duplicating the records), but then calculating the values for the 'Lat/Long' and 'Coords' fields respectively. I do not know a) whether or not this is the right approach or; b) a clean path to get there. Any thoughts would be appreciated.

Python and Pandas - Distances with latitude and longitude

I am trying compare distances between points (in this case fake people) in longitudes and latitudes.
I can import the data, then convert the lat and long data to radians and get the following output with pandas:
lat long
name
Veronica Session 0.200081 0.246723
Lynne Donahoo 0.775020 -1.437292
Debbie Hanley 0.260559 -1.594263
Lisandra Earls 1.203430 -2.425601
Sybil Leef -0.029293 0.592702
From there i am trying to compare different points and get the distance between them.
I came across a post that seemed to be of use (https://stackoverflow.com/a/40453439/15001056) but I am unable to get this working for my data set.
Any help in calculating the distance between points would be appreciated. Idealy id like to expand and optimise the route once the distance function is working.
I used the function in the answer you linked and it worked fine. Can't confirm that the distance is in the unit you need though.
df['dist'] = \
haversine(df.lat.shift(), df.long.shift(),
df.loc[1:, 'lat'], df.loc[1:, 'long'], to_radians=False)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Veronica Session 0.200081 0.246723 NaN
Lynne Donahoo 0.775020 -1.437292 9625.250626
Debbie Hanley 0.260559 -1.594263 3385.893020
Lisandra Earls 1.203430 -2.425601 6859.234096
Sybil Leef -0.029293 0.592702 12515.848878

Why i am gething different h3 index with same latitude and longitude

I am working with a SQlite hexagon index database and other information, the Hexagons index is the primary key. This database is generated by code written in python, and other codes written in C use the hexagonal index to access the information stored in the database.
for res_hex in [12,11,10,9,8]:
index_hex = h3.geo_to_h3(sonde[1], sonde[0], res_hex)
sonde[1] is latitude, sonde[0] is longitude res_hex is the resolution.
In fact, I have a list of objects represented by their latitude and longitude in a text file, I calculate the indexes around them with different resolutions (8 to 12). that I enter the database.
But my problem is that when I calculate the hexagon in code c with lat, lon and the resolution, I do not find it in the base. This even if the calculation is based on the same file.
GeoCoord geo = {latitude, longitude};
H3Index currentIndex = geoToH3(&geo, resolution);
Thanks for your help
I have find a solution, in C Lat/Lon must be in radians but it is not the case in python

How to delete CSV table values outside of a longitude/latitude radius?

I have a csv file with a table that has the columns Longitude, Latitude, and Wind Speed. I have a code that takes a csv file and deletes values outside of a specified bound. I would like to retain values whose longitude/latitude is within a 0.5 lon/lat radius of a point located at -71.5 longitude and 40.5 latitude.
My example code below deletes any values whose longitude and latitude isn't between -71 to -72 and 40 to 41 respectively. Of course, this retains values within a square bound ±0.5 lon/lat around my point of interest. But I am interested in finding values within a circular bound with radius 0.5 lon/lat of my point of interest. How should I modify my code?
import pandas as pd
import numpy
df = pd.read_csv(r"C:\\Users\\xil15102\\Documents\\results\\EasternLongIsland50.csv") #file path
indexNames=df[(df['Longitude'] <= -72)|(df['Longitude']>=-71)|(df['Latitude']<=40)|(df['Latitude']>=41)].index
df.drop(indexNames,inplace=True)
df.to_csv(r"C:\\Users\\xil15102\\Documents\\results\\EasternLongIsland50.csv")
Basically you need to check if a value is a certain distance from a central point (-71.5 and 40.5); to do this use the pythagorean theorem/distance formula:
d = sqrt(dx^2+dy^2).
So programmatically, I would do this like:
from math import sqrt
drop_indices = []
for row in range(len(df)):
if (sqrt(abs(-71.5 - df[row]['Longitude'])*abs(-71.5 - df[row]['Longitude']) + abs(40.5-df[row]['Latitude'])*abs(40.5-df[row]['Latitude']))) > 0.5:
drop_indices.append(row)
df.drop(drop_indices)
Sorry that is a sort for disgusting way to get rid of the rows and your way looks much better, but the code should work.
You should write a function to calculate the distance from your point of interest and drop those. Some help here. Pretty sure the example below should work if you implement is_not_in_area as a function to calculate the distance and check if dist < 0.5.
df = df.drop(df[is_not_in_area(df.lat, df.lon)].index)
(This code lifted from here)
Edit: drop the ones that aren't in area, not the ones that are haha.

Pandas - How do I look for a set of values in a column and if it is present return a value in another column

I am new to pandas. I have a csv file which has a latitude and longitude columns and also a tile ID column, the file has around 1 million rows. I have a list of around a hundred tile ID's and want to get the latitude and longitude coordinates for these tile ID's. Currently I have:
good_tiles_str = [str(q) for q in good_tiles]#setting list elements to string data type
file['tile'] = file.tile.astype(str)#setting title column to string data type
for i in range (len(good_tiles_str)):
x = good_tiles_str[i]
lat = file.loc[file['tile'].str.contains(x), 'BL_Latitude'] #finding lat coordinates
long = file.loc[file['tile'].str.contains(x), 'BL_Longitude'] #finding long coordinates
print(lat)
print(long)
This method is very slow and I know it is not the correct way as I heard you should not use for loops like this whilst using pandas. Also, it does not work as it doesn't find all the latitude and longitude points for the tile ID's
Any help would be very gladly appreciated
There is no need to iterate rows explicitly , I think as far as I understood your question.
If you wish a particular assignment given a condition, you can do so explicitly. Here's one way using numpy.where; we use ~ to indicate "negative".
rule1= file['tile'].str.contains(x)
rule2= file['tile'].str.contains(x)
file['flag'] = np.where(rule1 , 'BL_Latitude', " " )
file['flag'] = np.where(rule2 & ~rule1, 'BL_Longitude', file['flag'])
Try this:
search_for = '|'.join(good_tiles_str)
good = file[file.tile.str.contains(search_for)]
good = good[['BL_Latitude', 'BL_Longitude']].drop_duplicates()

Categories