Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

h3 index converted to Geocoordinates: how to export to geojson #66

Open
JB-data opened this issue Jul 15, 2020 · 4 comments
Open

h3 index converted to Geocoordinates: how to export to geojson #66

JB-data opened this issue Jul 15, 2020 · 4 comments

Comments

@JB-data
Copy link

JB-data commented Jul 15, 2020

Hi,
I had 2 quesions related to using h3ToGeoBoundary:
Question 1:
I am doing some preprocessing in spark using h3, and I want to save my results into a format that can easily be exported. My goal is to load the data in geomesa/geoserver. I notice that using h3ToGeoBoundary I get results that are a list of GeoCoord like this:
[GeoCoord{lat=50.346809, lng=14.153511}, GeoCoord{lat=50.316251, lng=14.138129}, GeoCoord{lat=50.294416, lng=14.173950}, GeoCoord{lat=50.303130, lng=14.225160}, GeoCoord{lat=50.333686, lng=14.240581}, GeoCoord{lat=50.355530, lng=14.204753}]
I assume this is the google coordinate type: https://pub.dev/documentation/google_directions_api/latest/google_directions_api/GeoCoord-class.html.
But is this compatible with geospark/geomesa?

It would be very helpful, if there was an option to save this as let's say geojson like there is for h3-js (https://github.com/uber/h3-js#module_h3.h3ToGeoBoundary where a boolean decides how it is saved).
Is there an example somewhere, if I have let's say 10k h3 indexes how to save it into a format that other geospatial tools (geomesa or geospark ) can read?

Question2:
Also when I want to apply a udf to a full column with h3 indexes, this works:
//works
val h3ToGeoBoundary = udf{ (h3Index: Long) =>
H3.instance.h3ToGeoBoundary(h3Index).toString()
}
but this does not:
//does not work
val h3ToGeoBoundaryGeoJson = udf{ (h3Index: Long) =>
H3.instance.h3ToGeoBoundary(h3Index)
}
//error:java.lang.UnsupportedOperationException: Schema for type java.util.List[com.uber.h3core.util.GeoCoord] is not supported
This means that if I want to create a dataframe with couple 1000 rows, I can only have that in string format, which does not allow me to do transformations on it (like selecting each element of the list, and using those coordinates to turn it myself into geojson).
Any clue how to solve this?

Thanks!
PS: great job-very user friendly and cool library.

@isaacbrodsky
Copy link
Collaborator

GeoCoord here is an immutable object constructed by H3-Java so as to not tie it to different frameworks. It contains the latitude and longitude in degrees.

We don't currently have the options around GeoJson output formatting. H3-JS needs that option because it represents coordinates as either lat,lng or lng,lat. In Java these are typed fields, so there is no possibility of switching them. We could add support for formatting or parsing H3 geometries into GeoSpark/GeoJSON/WKT/etc. in a module alongside h3-java. I think this would be a separate set of functions so that only users needing that functionality pull in those dependencies.

Unfortunately I am not very familiar with GeoSpark, for your example, I'd suggest adding the conversion to GeoJSON directly to the UDF. E.g. convertToGeoJson(H3.instance.h3ToGeoBoundary(h3Index)) It looks like GeoSpark doesn't permit GeoCoords within Lists - this might be an issue of GeoCoord not implementing Serializable but I'm not 100% sure.

@JB-data
Copy link
Author

JB-data commented Jul 17, 2020

Thanks for response!
Indeed, such a separate module would be a big plus. The current GeoCoord field comes from https://github.com/uber/h3-java/blob/master/src/main/java/com/uber/h3core/util/GeoCoord.java - for exporting to other geospatial tools it might have been more convenient to just write an array of (lat,long) tuples (without any strings)?

Thanks for the suggestion about the UDF. I believe you might be right about the serializable. I assume convertToGeo should be constructed then using some regular expressions after converting the result of h3ToGeoBoundary to a string, which indeed should be feasible.

Best&good luck with this project.

@isaacbrodsky
Copy link
Collaborator

You may still be able to avoid string serialization by mapping the GeoCoords into the form you need For example, you could do something like:

List<GeoCoord> coords = h3.h3ToGeoBoundary(index);
// convert to arrays of lat,lon
List<double[]> rawCoords = coords.stream().map(c -> new double[]{c.lat, c.lon}).collect(Collectors.toList());
return rawCoords;

@icemagno
Copy link

See #78

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants