Skip to content

Commit

Permalink
refactor & add heading algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
anitagraser committed Dec 6, 2018
1 parent cb0bbc5 commit 74f3e59
Show file tree
Hide file tree
Showing 13 changed files with 424 additions and 29 deletions.
2 changes: 1 addition & 1 deletion __init__.py
Expand Up @@ -25,7 +25,7 @@

__revision__ = '$Format:%H$'

from .trajectoryProviderPlugin import TrajectoryProviderPlugin
from .qgis_processing.trajectoryProviderPlugin import TrajectoryProviderPlugin


def classFactory(iface):
Expand Down
40 changes: 40 additions & 0 deletions geometryUtils.py
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
geometryUtils.py
---------------------
Date : December 2018
Copyright : (C) 2018 by Anita Graser
Email : anitagraser@gmx.at
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""

__author__ = 'Anita Graser'
__date__ = 'December 2018'
__copyright__ = '(C) 2018, Anita Graser'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'


import math
from shapely.geometry import Point


def azimuth(point1, point2):
angle = math.atan2(point2.x - point1.x, point2.y - point1.y)
azimuth = math.degrees(angle)
if angle < 0:
azimuth += 360
#print("{}->{}: angle={} azimuth={}".format(point1, point2, angle, azimuth))
return azimuth

173 changes: 173 additions & 0 deletions qgis_processing/addHeadingAlgorithm.py
@@ -0,0 +1,173 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
trajectoriesFromPointLayer.py
---------------------
Date : December 2018
Copyright : (C) 2018 by Anita Graser
Email : anitagraser@gmx.at
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""

__author__ = 'Anita Graser'
__date__ = 'December 2018'
__copyright__ = '(C) 2018, Anita Graser'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

import os
import sys
import pandas as pd
import numpy as np
from geopandas import GeoDataFrame
from shapely.geometry import Point, LineString, Polygon
from shapely.affinity import translate
from datetime import datetime, timedelta

from qgis.PyQt.QtCore import QCoreApplication, QVariant
from qgis.PyQt.QtGui import QIcon

from qgis.core import (QgsField,QgsFields,
QgsGeometry,
QgsFeature,
QgsFeatureSink,
QgsFeatureRequest,
QgsProcessing,
QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterString,
QgsProcessingParameterField,
QgsProcessingParameterNumber,
QgsProcessingParameterBoolean,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterEnum,
QgsWkbTypes
)

sys.path.append("..")

from processing_trajectory.trajectory import Trajectory
from .qgisUtils import trajectories_from_qgis_point_layer

pluginPath = os.path.dirname(__file__)


class AddHeadingAlgorithm(QgsProcessingAlgorithm):
# script parameters
INPUT = 'INPUT'
TRAJ_ID_FIELD = 'OBJECT_ID_FIELD'
TIMESTAMP_FIELD = 'TIMESTAMP_FIELD'
TIMESTAMP_FORMAT = 'TIMESTAMP_FORMAT'
OUTPUT = 'OUTPUT'

def __init__(self):
super().__init__()

def name(self):
return "add_heading"

def icon(self):
return QIcon(os.path.join(pluginPath, "icons", "icon.png"))

def tr(self, text):
return QCoreApplication.translate("add_heading", text)

def displayName(self):
return self.tr("Add heading to points")

def group(self):
return self.tr("Basic")

def groupId(self):
return "TrajectoryBasic"

def shortHelpString(self):
return self.tr("""
<h3>Add heading to points</h3>
<p>Todo</p>
""")

def helpUrl(self):
return "https://github.com/anitagraser/processing-trajectory"

def createInstance(self):
return type(self)()

def initAlgorithm(self, config=None):
# input layer
self.addParameter(QgsProcessingParameterFeatureSource(
name=self.INPUT,
description=self.tr("Input point layer"),
types=[QgsProcessing.TypeVectorPoint]))
# fields
self.addParameter(QgsProcessingParameterField(
name=self.TRAJ_ID_FIELD,
description=self.tr("Trajectory ID field"),
defaultValue="trajectory_id",
parentLayerParameterName=self.INPUT,
type=QgsProcessingParameterField.Any,
allowMultiple=False,
optional=False))
self.addParameter(QgsProcessingParameterField(
name=self.TIMESTAMP_FIELD,
description=self.tr("Timestamp field"),
defaultValue="t",
parentLayerParameterName=self.INPUT,
type=QgsProcessingParameterField.Any,
allowMultiple=False,
optional=False))
self.addParameter(QgsProcessingParameterString(
name=self.TIMESTAMP_FORMAT,
description=self.tr("Timestamp format"),
defaultValue="%Y-%m-%d %H:%M:%S+00",
optional=False))
# output layer
self.addParameter(QgsProcessingParameterFeatureSink(
name=self.OUTPUT,
description=self.tr("Trajectories"),
type=QgsProcessing.TypeVectorLine))

def processAlgorithm(self, parameters, context, feedback):
input_layer = self.parameterAsSource(parameters, self.INPUT, context)
traj_id_field = self.parameterAsFields(parameters, self.TRAJ_ID_FIELD, context)[0]
timestamp_field = self.parameterAsFields(parameters, self.TIMESTAMP_FIELD, context)[0]
timestamp_format = self.parameterAsString(parameters, self.TIMESTAMP_FORMAT, context)

fields = input_layer.fields()
output_fields = fields
output_fields.append(QgsField('heading', QVariant.Double))

(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
output_fields,
QgsWkbTypes.Point,
input_layer.sourceCrs())

trajectories = trajectories_from_qgis_point_layer(input_layer, timestamp_field, traj_id_field, timestamp_format)

for traj in trajectories:
traj.add_heading()
for index, row in traj.df.iterrows():
pt = QgsGeometry.fromWkt(row['geometry'].wkt)
f = QgsFeature()
f.setGeometry(pt)
attributes = []
for field in fields:
if field.name() == timestamp_field:
attributes.append(str(index))
else:
attributes.append(row[field.name()])
f.setAttributes(attributes)
sink.addFeature(f, QgsFeatureSink.FastInsert)

# default return type for function
return {self.OUTPUT: dest_id}
Expand Up @@ -26,6 +26,9 @@
__revision__ = '$Format:%H$'

import os
import sys

sys.path.append("..")

import pandas as pd
import numpy as np
Expand Down Expand Up @@ -55,8 +58,8 @@
QgsWkbTypes
)

from .trajectory import Trajectory
from .trajectoryUtils import trajectories_from_qgis_point_layer
from processing_trajectory.trajectory import Trajectory
from .qgisUtils import trajectories_from_qgis_point_layer

pluginPath = os.path.dirname(__file__)

Expand Down
Binary file added qgis_processing/icons/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 8 additions & 4 deletions trajectoryUtils.py → qgis_processing/qgisUtils.py
Expand Up @@ -2,9 +2,9 @@

"""
***************************************************************************
trajectoryUtils.py
qgisUtils.py
---------------------
Date : January 2018
Date : December 2018
Copyright : (C) 2018 by Anita Graser
Email : anitagraser@gmx.at
***************************************************************************
Expand All @@ -18,21 +18,25 @@
"""

__author__ = 'Anita Graser'
__date__ = 'January 2018'
__date__ = 'December 2018'
__copyright__ = '(C) 2018, Anita Graser'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

import sys

sys.path.append("..")

import pandas as pd
import numpy as np
from geopandas import GeoDataFrame
from shapely.geometry import Point, LineString, Polygon
from shapely.affinity import translate
from datetime import datetime, timedelta

from .trajectory import Trajectory
from processing_trajectory.trajectory import Trajectory


def trajectories_from_qgis_point_layer(layer, time_field_name, trajectory_id_field, time_format):
Expand Down
Expand Up @@ -18,14 +18,17 @@
"""

__author__ = 'Anita Graser'
__date__ = 'Dec 2018'
__date__ = 'December 2018'
__copyright__ = '(C) 2018, Anita Graser'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

import os
import sys

sys.path.append("..")

import pandas as pd
import numpy as np
Expand Down Expand Up @@ -55,8 +58,8 @@
QgsWkbTypes
)

from .trajectory import Trajectory
from .trajectoryUtils import trajectories_from_qgis_point_layer
from processing_trajectory.trajectory import Trajectory
from .qgisUtils import trajectories_from_qgis_point_layer

pluginPath = os.path.dirname(__file__)

Expand Down
11 changes: 8 additions & 3 deletions trajectoryProvider.py → qgis_processing/trajectoryProvider.py
Expand Up @@ -4,7 +4,7 @@
***************************************************************************
trajectoryProvider.py
---------------------
Date : January 2018
Date : December 2018
Copyright : (C) 2018 by Anita Graser
Email : anitagraser@gmx.at
***************************************************************************
Expand All @@ -18,14 +18,15 @@
"""

__author__ = 'Anita Graser'
__date__ = 'January 2018'
__date__ = 'December 2018'
__copyright__ = '(C) 2018, Anita Graser'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

import os
import sys

from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtCore import QCoreApplication
Expand All @@ -34,8 +35,11 @@

from processing.core.ProcessingConfig import ProcessingConfig, Setting

sys.path.append("..")

from .trajectoriesFromPointLayerAlgorithm import TrajectoriesFromPointLayerAlgorithm
from .clipTrajectoriesByExtentAlgorithm import ClipTrajectoriesByExtentAlgorithm
from .addHeadingAlgorithm import AddHeadingAlgorithm

pluginPath = os.path.dirname(__file__)

Expand Down Expand Up @@ -70,7 +74,8 @@ def setActive(self, active):

def getAlgs(self):
algs = [TrajectoriesFromPointLayerAlgorithm(),
ClipTrajectoriesByExtentAlgorithm()]
ClipTrajectoriesByExtentAlgorithm(),
AddHeadingAlgorithm()]
return algs

def loadAlgorithms(self):
Expand Down
Expand Up @@ -25,6 +25,10 @@

__revision__ = '$Format:%H$'

import sys

sys.path.append("..")

from qgis.core import QgsApplication

from .trajectoryProvider import TrajectoryProvider
Expand Down

0 comments on commit 74f3e59

Please sign in to comment.