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

feature: GeometryZM, time #56

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tyrauber
Copy link
Contributor

Point already accepts a time property. Waypoint and Trackpoint, currently only supply lon, lat, and elevation. This PR adds point[3] as the time param. This enables this library to import geojson with points that contain lon,lat,elevation and time, and will now work with RGeo::Cartesian.factor has_m_coordinate: true.

Additional Background:

You can extend GPX to patch to_geom:

module GPX
  class GPXFile < Base

    def to_geom
      factory = RGeo::Cartesian.factory(srid: 4326, has_z_coordinate: true, has_m_coordinate: true)
      if !self.tracks.empty?
        factory.collection(self.tracks.map do |track|
         factory.multi_line_string(track.segments.map do |segment|
            factory.line_string(
              segment.points.map do |point|
                factory.point(point.lon, point.lat, point.elevation.to_f, point.time.to_i)
              end
            )
          end)
        end)
      elsif !self.routes.empty?
        factory.multi_line_string(self.routes.map do |route|
          factory.line_string(
            route.points.map do |point|
              factory.point(point.lon, point.lat, point.elevation.to_f, point.time.to_i)
            end)
        end)
      end
    end
 end

This change makes it so you can import geojson structured with elevation and time and import it into a GeometryZM column:

# Ruby initialize method
 @gpx = GPX::GeoJSON.convert_to_gpx(geojson_data: options[:geojson])
 self.geom = @gpx.to_geom

You might need to alter the geom column from GeometryZ to GeometryZM:

ALTER TABLE gpx_tracks ALTER COLUMN geom TYPE geometry(GeometryZM, 4326) USING ST_Force4D(geom);

You can now create a method to extract total duration:

   CREATE OR REPLACE FUNCTION ST_Geom_Duration(geom geometry)
     RETURNS DOUBLE PRECISION AS $$
     DECLARE
         linestrings geometry[];
         line geometry;
         min_m DOUBLE PRECISION;
         max_m DOUBLE PRECISION;
         total_duration DOUBLE PRECISION := 0;
         i INT;
     BEGIN
         -- Extract all linestrings from the geometry collection
         linestrings := array(
             SELECT ST_GeometryN(geom, generate_series(1, ST_NumGeometries(geom)))
         );
     
         -- Loop through each linestring
         FOR i IN 1 .. array_length(linestrings, 1) LOOP
             line := linestrings[i];
     
             -- Extract the minimum M value from the linestring
             SELECT MIN(ST_M((dp).geom))
             INTO min_m
             FROM (
                 SELECT ST_DumpPoints(line) AS dp
             ) AS points;
     
             -- Extract the maximum M value from the linestring
             SELECT MAX(ST_M((dp).geom))
             INTO max_m
             FROM (
                 SELECT ST_DumpPoints(line) AS dp
             ) AS points;
     
             -- Add the duration of the current linestring to the total duration
             total_duration := total_duration + (max_m - min_m);
         END LOOP;
     
         -- Convert the total duration from milliseconds to seconds and return
         RETURN total_duration / 1000;
     END;
     $$ LANGUAGE plpgsql;

I doubt anyone else needs to do this, but I did, so I thought I'd share.

Point already accepts a time property. Waypoint and Trackpoint, currently only supply lon, lat, and elevation. This PR adds point[3] as the time param. This should hopefully enable it to work with RGeo::Cartesian.factor has_m_coordinate: true
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

Successfully merging this pull request may close these issues.

1 participant