kepler.gl is a tool that can visualize various data on a map. This time, we will visualize GPS data as a video.
A csv file created from gpx data. The breakdown is as follows.
ID | Times of Day | longitude | latitude | speed | trackID | segmentID | pointID |
---|---|---|---|---|---|---|---|
int | datetime | float | float | float | int | int | int |
Of these, if you classify by ID and trackID, the trip can be uniquely identified.
Of course, not limited to this format, latitude, longitude, (altitude), and time data may be collected in some form.
According to the official documentation
How to use trip layer to animate path Data format Currently trip layer support a special geoJSON format where the coordinate linestring has a 4th element denoting timestamp. In order to animate the path, the geoJSON data needs to contain LineString in its features' geometry, and the coordinates in the LineString need to have 4 elements in the format of [longitude, latitude, altitude, timestamp], with the last element being a timestamp. Valid timestamp formats include unix in seconds such as 1564184363 or in milliseconds such as 1564184363000.
It seems that. In summary, we need the following:
Thankfully, we also have sample data,
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"vendor": "A"
},
"geometry": {
"type": "LineString",
"coordinates": [
[-74.20986, 40.81773, 0, 1564184363],
[-74.20987, 40.81765, 0, 1564184396],
[-74.20998, 40.81746, 0, 1564184409]
]
}
}
]
}
This format is required.
It seems to be about the same as Json. When I tried to download Google's location history, it was provided in Json format, and I felt that the Json file containing geographic information was called GeoJson for the purpose of distinction. In fact, I was able to read a file with the same content but only the extension .json.
If you look at the sample data again,
It has a structure called. In other words, if the structure satisfies this, it will be read.
The column names of each data are as follows. (Since there is no altitude data this time, speed data is used instead.)
ID | Times of Day | longitude | latitude | speed | trackID | segmentID | pointID |
---|---|---|---|---|---|---|---|
"ID" | "time" | "longitude" | "latitude" | "speed" | "trackID" | "segmentID" | "pointID" |
First, convert the time from datetime type to timestamp type (UNIX seconds).
df["time"] = df["time"].apply(lambda x: x.timestamp())
#DataFrame
Next, extract only the necessary items from the DataFrame. You can get multiple items at once by specifying them in the list.
df_coordinate = df[["longitude","latitude","speed","time"]]
#DataFrame
Next, make it possible to classify by ID and trackID.
g = df_coordinate.groupby(["ID","trackID"])
#DataFrameGroupBy
Then list each line (one line for df [["longitude", "latitude", "speed", "time"]]). A Series of lists for each df_coordinate ID and trackID is created in coordinate_list.
coordinate_list= g.apply(lambda d : d.values.tolist())
#Series It's easy to make a mistake here
Finally, convert Series to list.
coordinate_list = coordinate_list.values.tolist()
#list
Now you have a list of one trip of the list [longitude, latitude, altitude, UNIX seconds].
--List of all trips --List of 1 trip --List of 1 point --Longitude --Latitude --Elevation (speed)
It is a structure.
Create GeoJson data using the list created in the previous section. For this, I used a library called geojson. As an amateur's recognition, it is a module that arranges it in json format. As I wrote earlier, the required data is in the following format. It is steadily to create these data so as to assemble them from the bottom.
This module is simple, for example, if you want to create a Feature, you can do as follows. In other words, it will add self-introduction parts and parentheses without permission.
> Feature(geometry=my_point) # doctest: +ELLIPSIS
{"geometry": {"coordinates": [-3.68..., 40.4...], "type": "Point"}, "properties": {}, "type": "Feature"}
The one assembled with reference to this example sentence is shown below.
#Make a list to accumulate features
feature_list = list()
#Accumulate Features in Feature list
for i in range(len(coordinate_list)):
#Substitute a list for one trip into pts
pts = coordinate_list[i]
#Substitute pts converted to GeoJson format for ls
ls = geojson.LineString(pts)
#Create a Feature with ls as geometry and with properties
#feature_Add to the end of list
feature_list.append(geojson.Feature(properties={'tripID': str(i)},geometry=ls))
#feature_Convert list to FeatureCollection
Tripdata = geojson.FeatureCollection(feature_list)
As a result, Tripdata contains the required plaintext.
By the way, it is possible to put the identification information for each feature in properties. Depending on the device, various classifications such as classification by person and classification by time can be performed.
If you can do this, it's almost over. The data is completed by creating a new file with the extension .geojson and writing the plain text there.
path = './Tripdata.geojson'
with open(path, 'w') as f:
f.write(geojson.dumps(Tripdata))
f.close()
I wrote it as visualization exaggeratedly, but all I have to do is drag and drop the data I created earlier. It is also possible to classify based on the information of properties.
For all data, if only the date is set to the same day, only the time zone can be visualized, so it is easy to understand the time zone with a lot of movement at a glance. Conversion is easy in datetime, so replace () should be done before converting to UNIX seconds.
df["time"] = df["time"].apply(lambda x: x.replace(year=2021,month=1,day=1))
df["time"] = df["time"].apply(lambda x: x.timestamp())
You can make a very nice visualization with these series of steps, so please try it.
Recommended Posts