Exemplo n.º 1
0
    def require_input(self):
        """Ensure input files are entered in dialog exist.

        :raises: ImportDialogError - when one or all
        of the input files are empty
        """
        database_name = self.database.text()
        host_name = self.host.text()
        port_number = self.port.text()
        user_name = self.user_name.text()
        password = self.password.text()
        network_table = self.network_table.text()
        catchment_table = self.catchment_table.text()
        contour_interval = self.contour_interval.text()

        if database_name and host_name and port_number and \
                user_name and password and network_table and \
                catchment_table:
            return

        display_warning_message_box(
                    self,
                    self.tr('Error'),
                    self.tr('Input cannot be empty.'))

        raise ImportDialogError()
Exemplo n.º 2
0
def clear_network_cache(connection, cursor, arguments, dialog):
    """Clear a network cache if exists

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """

    try:
        sql = """DROP VIEW IF EXISTS network_cache"""

        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()

    except Exception as exception:
        display_warning_message_box(
            dialog, "Error", "Error in clearing network view")
Exemplo n.º 3
0
def clear_network_cache(connection, cursor, arguments, dialog):
    """Clear a network cache if exists

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """

    try:
        sql = """DROP VIEW IF EXISTS network_cache"""

        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()

    except Exception as exception:
        display_warning_message_box(dialog, "Error",
                                    "Error in clearing network view")
Exemplo n.º 4
0
def create_routable_network(connection, cursor, arguments, dialog):
    """Create routable network using the network view with the nodes.
       This takes long time to complete.

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """

    try:
        sql = """CREATE TABLE IF NOT EXISTS routable_network AS
               SELECT a.*, b.id as start_id, c.id as end_id FROM
               network_cache
               AS a
               JOIN nodes AS b ON a.pgr_startpoint = b.the_geom JOIN
               nodes AS c
               ON  a.pgr_endpoint = c.the_geom """
        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()
    except Exception as exception:
        display_warning_message_box(dialog, "Error",
                                    "Error in creating routable network")
Exemplo n.º 5
0
def create_network_view(connection, cursor, arguments, dialog):
    """Create network view, to improve performance of queries using it

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """
    clear_network_cache(connection, cursor, arguments, dialog)

    try:
        sql = """ CREATE OR REPLACE VIEW network_cache as
            SELECT *, pgr_startpoint(%(network_geom)s),
            pgr_endpoint(%(network_geom)s) FROM %(network_table)s
            """ % arguments

        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()

    except Exception as exception:
        display_warning_message_box(dialog, "Error",
                                    "Error in creating network view")
Exemplo n.º 6
0
def prepare_drivetimes_table(connection, cursor, arguments, dialog):
    """

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    :param progress_percentage: the percentage of progress bar
    :type progress_percentage: int

    """
    try:
        sql = """ DROP TABLE IF EXISTS catchment_final"""
        sql = clean_query(sql)

        cursor.execute(sql)

        connection.commit()

        sql = """ CREATE TABLE IF NOT EXISTS catchment_final AS
               SELECT id, the_geom, min (cost) AS %s
               FROM catchment_with_cost
               GROUP By id, the_geom
            """ % "drivetime"

        sql = clean_query(sql)

        cursor.execute(sql)

        connection.commit()

        sql = """DROP TABLE IF EXISTS catchment_final_no_null"""

        sql = clean_query(sql)

        cursor.execute(sql)

        connection.commit()

        sql = """ CREATE TABLE catchment_final_no_null AS
                SELECT *, (drivetime * 60) AS minutes FROM catchment_final
                WHERE %s IS NOT NULL """ % "drivetime"

        sql = clean_query(sql)

        cursor.execute(sql)

        connection.commit()
    except Exception as exception:
        display_warning_message_box(dialog, "Error",
                                    "Error in preparing drivetimes table")
Exemplo n.º 7
0
def create_routable_network(connection, cursor, arguments, dialog):
    """Create routable network using the network view with the nodes.
       This takes long time to complete.

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """

    try:
        sql = """CREATE TABLE IF NOT EXISTS routable_network AS
               SELECT a.*, b.id as start_id, c.id as end_id FROM
               network_cache
               AS a
               JOIN nodes AS b ON a.pgr_startpoint = b.the_geom JOIN
               nodes AS c
               ON  a.pgr_endpoint = c.the_geom """
        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()
    except Exception as exception:
        display_warning_message_box(
            dialog, "Error", "Error in creating routable network")
Exemplo n.º 8
0
def create_network_view(connection, cursor, arguments, dialog):
    """Create network view, to improve performance of queries using it

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """
    clear_network_cache(connection, cursor, arguments, dialog)

    try:
        sql = """ CREATE OR REPLACE VIEW network_cache as
            SELECT *, pgr_startpoint(%(network_geom)s),
            pgr_endpoint(%(network_geom)s) FROM %(network_table)s
            """ % arguments

        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()

    except Exception as exception:
        display_warning_message_box(
            dialog, "Error", "Error in creating network view")
Exemplo n.º 9
0
    def load_isochrone_map(self, base_path):
        """Load the isochrone map in the qgis

        :param base_path: Output path where layers are
        :type base_path:str
        """

        if not os.path.exists(base_path):
            message = self.tr("Error, failed to load the isochrone map")
            raise FileMissingError(message)
        else:
            for layer in os.listdir(base_path):
                layer_name = QFileInfo(layer).baseName

                if file.endswith(".asc"):
                    self.iface.addRasterLayer(file, layer_name)
                    continue
                elif file.endswith(".shp"):
                    self.iface.addVectorLayer(file, layer_name, 'ogr')
                    continue
                else:
                    continue
        canvas_srid = self.canvas.mapRenderer().destinationCrs().srsid()
        on_the_fly_projection = self.canvas.hasCrsTransformEnabled()
        if canvas_srid != 4326 and not on_the_fly_projection:
            if Qgis.QGIS_VERSION_INT >= 20400:
                self.canvas.setCrsTransformEnabled(True)
            else:
                display_warning_message_box(
                    self.iface, self.tr('Enable \'on the fly\''),
                    self.tr(
                        'Your current projection is different than EPSG:4326.'
                        'You should enable \'on the fly\' to display '
                        'correctly the isochrone map'))
Exemplo n.º 10
0
    def accept(self):
        """Create an isochrone map and display it in QGIS."""
        error_dialog_title = self.tr("Error")
        try:
            self.save_state()
            self.require_input()

            database_name = self.database.text()
            host_name = self.host.text()
            port_number = self.port.text()
            user_name = self.user_name.text()
            password = self.password.text()
            network_table = self.network_table.text()
            network_geom = self.network_geom_column.text()
            network_id_column = self.network_id_column.text()
            catchment_geom = self.catchment_geom_column.text()
            catchment_table = self.catchment_table.text()
            catchment_id_column = self.catchment_id_column.text()
            contour_interval = self.contour_interval.text()

            if self.style.isChecked():
                style_checked = True
            else:
                style_checked = False

            isochrone(
                database_name,
                host_name,
                port_number,
                user_name,
                password,
                network_table,
                network_geom,
                network_id_column,
                catchment_table,
                catchment_geom,
                catchment_id_column,
                style_checked,
                contour_interval,
                self,
                self.progress_dialog)

            self.done(QDialog.Accepted)

        except ImportDialogError as exception:
            display_warning_message_box(
                self, error_dialog_title, exception.message)
            pass
        except Exception as exception:  # pylint: disable=broad-except
            # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
            display_warning_message_box(
                self, error_dialog_title, exception.message)
            pass
        finally:
            dialog_title = self.tr("Success")
Exemplo n.º 11
0
def update_catchment(connection, cursor, arguments, dialog):
    """Calculating the nearest nodes to the catchment areas,
       these nodes will be used in accessibility calculations.

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """

    try:
        update_catchment_table(connection, cursor, arguments, dialog)

        sql = """ALTER TABLE %(catchment_table)s
               ADD COLUMN the_nearest_node integer;

              CREATE TABLE IF NOT EXISTS temp AS
               SELECT a.gid, b.id, min(a.dist)

               FROM
                 (SELECT %(catchment_table)s.%(catchment_id)s as gid,
                         min(st_distance(
                         %(catchment_table)s.%(catchment_geom)s,
                         nodes.the_geom))
                          AS dist
                  FROM %(catchment_table)s, nodes
                  GROUP BY %(catchment_table)s.%(catchment_id)s) AS a,
                 (SELECT %(catchment_table)s.%(catchment_id)s as gid,
                 nodes.id, st_distance(
                 %(catchment_table)s.%(catchment_geom)s,
                 nodes.the_geom) AS dist
                  FROM %(catchment_table)s, nodes) AS b
               WHERE a.dist = b. dist
                     AND a.gid = b.gid
               GROUP BY a.gid, b.id; """ % arguments
        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()

        populate_catchment_table(connection, cursor, arguments, dialog)

    except Exception as exception:
        display_warning_message_box(dialog, "Error",
                                    "Error in updating catchment table")
Exemplo n.º 12
0
def generate_drivetimes_contour(raster_layer, interval, parent_dialog):
    """Create drive times contour

    :param raster_layer: Interpolated raster layer with drivetimes
    :type raster_layer: QgsRasterLayer

    :param interval: drivetimes interval
    :type interval: int

    :param parent_dialog: A dialog that called this function.
    :type parent_dialog: QProgressDialog

    :returns layer: Vector layer with contour drivetimes
    :rtype layer: QgsVectorLayer

    """
    drivetime_layer = None

    try:
        Processing.initialize()
        Processing.updateAlgsList()

        output_vector = processing.runalg(
                'gdalogr:contour',
                raster_layer,
                interval,
                'minutes',
                None,
                '[temporary_file]')

        drivetime_layer = QgsVectorLayer(
                output_vector['OUTPUT_VECTOR'],
                'time(min)',
                'ogr')

    except Exception as exception:  # pylint: disable=broad-except
            # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
        if parent_dialog:
            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    'Error'),
                parent_dialog.tr('Error loading isochrone map,'
                                 'please check if you have processing '
                                 'plugin installed '))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map,'
                'please check if you have processing '
                'plugin installed ')

    return drivetime_layer
Exemplo n.º 13
0
def update_catchment(connection, cursor, arguments, dialog):
    """Calculating the nearest nodes to the catchment areas,
       these nodes will be used in accessibility calculations.

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """

    try:
        update_catchment_table(connection, cursor, arguments, dialog)

        sql = """ALTER TABLE %(catchment_table)s
               ADD COLUMN the_nearest_node integer;

              CREATE TABLE IF NOT EXISTS temp AS
               SELECT a.gid, b.id, min(a.dist)

               FROM
                 (SELECT %(catchment_table)s.%(catchment_id)s as gid,
                         min(st_distance(
                         %(catchment_table)s.%(catchment_geom)s,
                         nodes.the_geom))
                          AS dist
                  FROM %(catchment_table)s, nodes
                  GROUP BY %(catchment_table)s.%(catchment_id)s) AS a,
                 (SELECT %(catchment_table)s.%(catchment_id)s as gid,
                 nodes.id, st_distance(
                 %(catchment_table)s.%(catchment_geom)s,
                 nodes.the_geom) AS dist
                  FROM %(catchment_table)s, nodes) AS b
               WHERE a.dist = b. dist
                     AND a.gid = b.gid
               GROUP BY a.gid, b.id; """ % arguments
        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()

        populate_catchment_table(connection, cursor, arguments, dialog)

    except Exception as exception:
        display_warning_message_box(
            dialog, "Error", "Error in updating catchment table")
Exemplo n.º 14
0
def create_network_view(
        connection,
        cursor,
        arguments,
        dialog,
        progress_dialog):
    """Create network view, to improve performance of queries using it

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    :param progress_dialog: Progress dialog
    :type progress_dialog: Qdialog

    """

    progress_dialog.setValue(0)
    label_text = tr("Creating network view table")
    progress_dialog.setLabelText(label_text)

    drop_network_cache(connection, cursor, arguments, dialog)

    try:
        sql = """ CREATE OR REPLACE VIEW network_cache as
            SELECT *, pgr_startpoint(%(network_geom)s),
            pgr_endpoint(%(network_geom)s) FROM %(network_table)s
            """ % arguments

        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()

    except Exception as exception:
        message = "Error in creating network view \n {}". \
            format(str(exception))

        display_warning_message_box(
            dialog, "Error",
            message
        )

        raise IsochroneDBError
Exemplo n.º 15
0
def create_nodes(connection, cursor, arguments, dialog):
    """Create network nodes, this will help in creating
       a sql routable network table

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """
    try:

        drop_table(connection, cursor, "nodes")

        sql = """CREATE TABLE IF NOT EXISTS nodes AS
               SELECT row_number() OVER (ORDER BY foo.p)::integer AS id,
               foo.p AS the_geom
               FROM (
               SELECT DISTINCT network_cache.pgr_startpoint AS p
                FROM network_cache
               UNION
               SELECT DISTINCT network_cache.pgr_endpoint AS p
               FROM network_cache
               ) foo
               GROUP BY foo.p"""
        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()
    except Exception as exception:
        message = "Error in creating network nodes \n {}". \
                  format(str(exception))

        display_warning_message_box(
            dialog, "Error",
            message
        )

        raise IsochroneDBError
Exemplo n.º 16
0
def generate_drivetimes_contour(raster_layer, interval, parent_dialog):
    """Create drive times contour

    :param raster_layer: Interpolated raster layer with drivetimes
    :type raster_layer: QgsRasterLayer

    :param interval: drivetimes interval
    :type interval: int

    :param parent_dialog: A dialog that called this function.
    :type parent_dialog: QProgressDialog

    :returns layer: Vector layer with contour drivetimes
    :rtype layer: QgsVectorLayer

    """
    drivetime_layer = None

    try:
        Processing.initialize()
        Processing.updateAlgsList()

        output_vector = processing.runalg('gdalogr:contour', raster_layer,
                                          interval, 'minutes', None,
                                          '[temporary_file]')

        drivetime_layer = QgsVectorLayer(output_vector['OUTPUT_VECTOR'],
                                         'time(min)', 'ogr')

    except Exception as exception:  # pylint: disable=broad-except
        # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
        if parent_dialog:
            display_warning_message_box(
                parent_dialog, parent_dialog.tr('Error'),
                parent_dialog.tr('Error loading isochrone map,'
                                 'please check if you have processing '
                                 'plugin installed '))
        else:
            display_warning_message_box(
                parent_dialog, 'Error', 'Error loading isochrone map,'
                'please check if you have processing '
                'plugin installed ')

    return drivetime_layer
Exemplo n.º 17
0
def create_nodes(connection, cursor, arguments, dialog):
    """Create network nodes, this will help in creating
       a sql routable network table

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    """
    try:
        sql = """CREATE TABLE IF NOT EXISTS nodes AS
               SELECT row_number() OVER (ORDER BY foo.p)::integer AS id,
               foo.p AS the_geom
               FROM (
               SELECT DISTINCT network_cache.pgr_startpoint AS p
                FROM network_cache
               UNION
               SELECT DISTINCT network_cache.pgr_endpoint AS p
               FROM network_cache
               ) foo
               GROUP BY foo.p"""
        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()
    except Exception as exception:
        display_warning_message_box(
            dialog, "Error", "Error in creating network nodes")
Exemplo n.º 18
0
    def load_isochrone_map(self, base_path):
        """Load the isochrone map in the qgis

        :param base_path: Output path where layers are
        :type base_path:str
        """

        if not os.path.exists(base_path):
            message = self.tr("Error, failed to load the isochrone map")
            raise FileMissingError(message)
        else:
            for layer in os.listdir(base_path):
                layer_name = QFileInfo(layer).baseName

                if file.endswith(".asc"):
                    self.iface.addRasterLayer(file, layer_name)
                    continue
                elif file.endswith(".shp"):
                    self.iface.addVectorLayer(file, layer_name, 'ogr')
                    continue
                else:
                    continue
        canvas_srid = self.canvas.mapRenderer().destinationCrs().srsid()
        on_the_fly_projection = self.canvas.hasCrsTransformEnabled()
        if canvas_srid != 4326 and not on_the_fly_projection:
            if QGis.QGIS_VERSION_INT >= 20400:
                self.canvas.setCrsTransformEnabled(True)
            else:
                display_warning_message_box(
                    self.iface,
                    self.tr('Enable \'on the fly\''),
                    self.tr(
                        'Your current projection is different than EPSG:4326.'
                        'You should enable \'on the fly\' to display '
                        'correctly the isochrone map')
                    )
Exemplo n.º 19
0
def prepare_map_style(
        uri,
        progress_percentage,
        contour_interval,
        progress_dialog,
        temp_layer,
        parent_dialog,
        args):
    """Prepare map style if user requested for it

    :param uri: Identifier for the final layer table
    :type uri: QgsDataSourceUri

    :param progress_percentage: Progress percentage.
    :type progress_percentage: int

    :param contour_interval: Drivetime interval.
    :type contour_interval: int

    :param progress_dialog: Dialog for progress.
    :type progress_dialog: QDialog

    :param temp_layer: Temporary result layer.
    :type temp_layer: QgsVectorLayer

    :param parent_dialog: Isochrone parent dialog.
    :type parent_dialog: QDialog

    :param args: Database tables arguments
    :type args: {}

    """

    progress_percentage += 1
    if progress_dialog:
        progress_dialog.setValue(progress_percentage)
    label_text = tr("Exporting and preparing isochrone map")
    progress_dialog.setLabelText(label_text)

    if progress_dialog.wasCanceled():
        return

    # TODO implement style creation logic

    # Run interpolation on the final file (currently using IDW)
    raster_file = idw_interpolation(temp_layer, parent_dialog)

    # Generate drivetimes contour
    try:
        drivetime_layer = generate_drivetimes_contour(
            raster_file,
            contour_interval,
            parent_dialog)

        # Load all the required layers

        load_map_layers(uri, parent_dialog, drivetime_layer, args)

    except Exception as exception:
        message = 'Error generating drivetimes \n {}'. \
            format(str(exception))

        display_warning_message_box(
            parent_dialog,
            parent_dialog.tr(
                'Error'),
            parent_dialog.tr(
                message
            )
        )

        raise IsochroneMapStyleError

    progress_percentage += 4
    if progress_dialog:
        progress_dialog.setValue(progress_percentage)
        label_text = tr("Done, loading isochrone map")
        progress_dialog.setLabelText(label_text)

        if progress_dialog.wasCanceled():
            return
Exemplo n.º 20
0
def calculate_drivetimes(
        connection,
        cursor,
        arguments,
        dialog,
        progress_percentage):

    """
    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    :param progress_percentage: the percentage of progress bar
    :type progress_percentage: int

    :returns Progress percentage
    :rtype int

    """

    index = 0

    try:
        rows = query_nearest_nodes(connection, cursor, arguments, dialog)

        # Convert unique column to integer as required by
        # the pgr_dijkstra function

        sql = """ALTER TABLE routable_network ALTER COLUMN
                %(network_id)s SET DATA TYPE int4""" % arguments

        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()

        for row in rows:
            # This step is 45% of all steps so calculating
            # percentage of each increment accordingly

            percentage = ((index + 1) / len(rows)) * 45
            percentage = round(percentage, 0)
            catchment_id = row[0]
            arguments["catchment_current_id"] = catchment_id
            if index == 0:
                sql = """ CREATE TABLE
                        IF NOT EXISTS catchment_with_cost AS
                    SELECT
                    id,
                    the_geom,
                    (SELECT sum(cost) FROM (
                       SELECT * FROM pgr_dijkstra('
                       SELECT %(network_id)s AS id,
                          start_id::int4 AS source,
                          end_id::int4 AS target,
                          cost::float8 AS cost
                       FROM routable_network',
                       %(catchment_current_id)s,
                       id,
                       false,
                       false)) AS foo ) AS cost
                    FROM nodes;""" % arguments
                sql = clean_query(sql)
                cursor.execute(sql)
            else:
                sql = """ INSERT INTO catchment_with_cost (
                    SELECT
                        id,
                        the_geom,
                        (SELECT sum(cost) FROM (
                           SELECT * FROM pgr_dijkstra('
                           SELECT  %(network_id)s AS id,
                              start_id::int4 AS source,
                              end_id::int4 AS target,
                              cost::float8 AS cost
                           FROM routable_network',
                           %(catchment_current_id)s,
                           id,
                           false,
                           false)) AS foo ) AS cost
                    FROM nodes);""" % arguments

                sql = clean_query(sql)

                cursor.execute(sql)

            index += 1
            connection.commit()
            progress_percentage += percentage
            if dialog:
                dialog.setValue(progress_percentage)
                label_text = tr(
                str(index) +
                " catchment area(s) out of " +
                str(len(rows)) +
                " is(are) done")
                dialog.setLabelText(label_text)
        if dialog:
            label_text = tr("Preparing all the catchment areas table")
            dialog.setLabelText(label_text)

    except Exception as exception:
        display_warning_message_box(
            dialog, "Error", "Error in calculating drivetimes")

    return progress_percentage
Exemplo n.º 21
0
def idw_interpolation(layer, parent_dialog):
    """Run interpolation using inverse distance weight algorithm

    :param layer: Vector layer with drivetimes
    :type layer: QgsVectorLayer

    :param parent_dialog: A dialog for showing progress.
    :type parent_dialog: QProgressDialog

    :returns raster_layer: Interpolated raster layer with drivetimes
    :rtype raster_layer: QgsRasterLayer

    """
    raster_layer = None
    try:
        Processing.initialize()

        # Create temporary file

        temp_output_file = tempfile.NamedTemporaryFile()
        temp_output_file_path = temp_output_file.name + '.tif'

        saved_layer = save_layer(layer)

        params = {'INPUT': saved_layer.dataProvider().dataSourceUri(),
                  'Z_FIELD': 'minutes',
                  'POWER': 2,
                  'SMOOTHING': 0,
                  'RADIUS_1': 0,
                  'RADIUS_2': 0,
                  'ANGLE': 0,
                  'MAX_POINTS': 0,
                  'MIN_POINTS': 0,
                  'NODATA': 0,
                  'DATA_TYPE': 5,
                  'OUTPUT': temp_output_file_path
                  }

        output_raster = processing.run(
            'gdal:gridinversedistance', params
        )

        output_file = output_raster['OUTPUT']

        # retrieving the raster output , styling it and load it in Qgis

        raster_layer = QgsRasterLayer(output_file, 'styled map')

        raster_layer = style_raster_layer(raster_layer, parent_dialog)

        QgsProject.instance().addMapLayer(raster_layer)

        # TODO use stored static style instead of dynamic one??
        #  map_style = resources_path(
        #     'styles',
        #     'qgis',
        #     'map.qml')
        # raster_layer.loadNamedStyle(map_style)
        #
        # raster_layer.triggerRepaint()

    except Exception as exception:  # pylint: disable=broad-except
            # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
        if parent_dialog:
            message = 'Error loading isochrone map,'\
                      'please check if you have processing '\
                      'plugin installed \n'.\
                      format(str(exception))
            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    'Error'),
                parent_dialog.tr(message))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map,'
                'please check if you have processing '
                'plugin installed ')

        raise IsochroneMapStyleError

    return raster_layer
Exemplo n.º 22
0
def style_raster_layer(raster_layer, parent_dialog):
    """Style interpolated raster layer

        :param raster_layer: Interpolated raster layer
        :type raster_layer: QgsRasterLayer

        :param parent_dialog: A dialog for showing progress.
        :type parent_dialog: QProgressDialog

        :returns raster_layer: Styled interpolated raster layer
        :rtype raster_layer: QgsRasterLayer

    """
    if raster_layer:
        if raster_layer.isValid():
            color_shader = QgsColorRampShader()
            color_shader.setColorRampType(QgsColorRampShader.Interpolated)
            colors = {
                'deep_green': '#1a9641',
                'light_green': '#a6d96a',
                'pale_yellow': '#ffffc0',
                'light_red': '#fdae61',
                'red': '#d7191c'
            }
            provider = raster_layer.dataProvider()
            stats = provider.bandStatistics(
                1,
                QgsRasterBandStats.All,
                raster_layer.extent(),
                0)

            values = {}

            if stats:
                min = stats.minimumValue
                max = stats.maximumValue
                stat_range = max - min
                add = stat_range / 4
                values[0] = min
                value = min
                for index in range(1, 4):
                    value += add
                    values[index] = value
                values[4] = max
            else:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Error'),
                    parent_dialog.tr('Error loading isochrone map'
                                     ' Problem indexing the isochrones map'))

            color_list = [
                QgsColorRampShader.ColorRampItem(
                    values[0],
                    QColor(colors['deep_green'])),
                QgsColorRampShader.ColorRampItem(
                    values[1],
                    QColor(colors['light_green'])),
                QgsColorRampShader.ColorRampItem(
                    values[2],
                    QColor(colors['pale_yellow'])),
                QgsColorRampShader.ColorRampItem(
                    values[3],
                    QColor(colors['light_red'])),
                QgsColorRampShader.ColorRampItem(
                    values[4],
                    QColor(colors['red']))
            ]

            color_shader.setColorRampItemList(color_list)
            raster_shader = QgsRasterShader()
            raster_shader.setRasterShaderFunction(color_shader)

            renderer = QgsSingleBandPseudoColorRenderer(
                raster_layer.dataProvider(),
                1,
                raster_shader)

            raster_layer.setRenderer(renderer)
            raster_layer.triggerRepaint()

        else:
            if parent_dialog:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Problem'),
                    parent_dialog.tr('Problem styling the isochrone map'))
            else:
                display_warning_message_box(
                    parent_dialog,
                    'Problem',
                    'Problem styling the isochrone map')

    else:
        if parent_dialog:

            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    'Error'),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load interpolated file!'))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map '
                'Could not load interpolated file!')

    return raster_layer
Exemplo n.º 23
0
def generate_drivetimes_contour(raster_layer, interval, parent_dialog):
    """Create drive times contour

    :param raster_layer: Interpolated raster layer with drivetimes
    :type raster_layer: QgsRasterLayer

    :param interval: drivetimes interval
    :type interval: int

    :param parent_dialog: A dialog that called this function.
    :type parent_dialog: QProgressDialog

    :returns layer: Vector layer with contour drivetimes
    :rtype layer: QgsVectorLayer

    """
    drivetime_layer = None

    try:
        Processing.initialize()

        temp_output_file = tempfile.NamedTemporaryFile()
        temp_output_file_path = temp_output_file.name + '.shp'

        params = {
                'INPUT': raster_layer,
                'INTERVAL': interval,
                'FIELD_NAME': 'minutes',
                'CREATE_3D': False,
                'IGNORE_NODATA': False,
                'NODATA': 0,
                'BAND': 1,
                'OUTPUT': temp_output_file_path
        }

        output_vector = processing.run(
            'gdal:contour', params
        )

        drivetime_layer = QgsVectorLayer(
                output_vector['OUTPUT'],
                'time(min)',
                'ogr')

    except Exception as exception:  # pylint: disable=broad-except
            # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
        if parent_dialog:
            message = 'Error loading isochrone map,' \
                      'please check if you have processing ' \
                      'plugin installed \n'. \
                      format(str(exception))
            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    'Error'),
                parent_dialog.tr(message))
        else:
            message = 'Error loading isochrone map,'\
                      'please check if you have processing '\
                        'plugin installed \n'.\
                        format(str(exception))

            display_warning_message_box(
                parent_dialog,
                'Error',
                message)

        raise IsochroneMapStyleError

    return drivetime_layer
Exemplo n.º 24
0
def prepare_drivetimes_table(connection, cursor, arguments, dialog):
    """

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    :param progress_percentage: the percentage of progress bar
    :type progress_percentage: int

    """
    try:
        drop_table(connection, cursor, "catchment_final")

        sql = """ CREATE TABLE IF NOT EXISTS catchment_final AS
               SELECT id, the_geom, min (cost) AS %s
               FROM catchment_with_cost
               GROUP By id, the_geom
            """ % "drivetime"

        sql = clean_query(sql)
        cursor.execute(sql)
        connection.commit()

        # drop_table(connection, cursor, "catchment_final_mid")

        # TODO find best approach of getting max_hours
        # use these hours incase catchment is unreachable
        # maximum_time = max_drivetime(
        #     connection,
        #     cursor)
        #
        # max_hours = maximum_time + maximum_time * 0.05
        #
        # sql = """ CREATE TABLE catchment_final_mid AS
        #                 SELECT *, coalesce(drivetime, %f) as valid_drivetime
        #                 FROM catchment_final
        #                 """ % max_hours
        # sql = clean_query(sql)
        # cursor.execute(sql)
        # connection.commit()

        drop_table(connection, cursor, "catchment_final_no_null")

        sql = """ CREATE TABLE catchment_final_no_null AS
                SELECT *, (drivetime * 60) AS minutes FROM catchment_final
                WHERE %s IS NOT NULL
                """ % "drivetime"

        sql = clean_query(sql)
        cursor.execute(sql)
        connection.commit()

    except Exception as exception:
        message = "Error in preparing drivetimes table \n {}". \
            format(str(exception))

        display_warning_message_box(
            dialog,
            "Error",
            message
        )

        raise IsochroneDBError
Exemplo n.º 25
0
def load_map_layers(uri, parent_dialog, drivetime_layer, args):
    """Style map layers and load them in Qgis

    :param uri: Connection to the database
    :type uri: QgsDataSourceURI

    :param parent_dialog: A dialog that called this function.
    :type parent_dialog: QProgressDialog

    :param drivetime_layer: A layer containing drivetimes
    :type drivetime_layer: QgsVectorLayer

    :param args: List containing database parameters
    :type args: {}

    """

    uri.setDataSource(
        args['network_schema'],
        args['network_table'],
        args['network_geom'])
    network_layer = QgsVectorLayer(
        uri.uri(),
        "network",
        "postgres")

    uri.setDataSource(
        args['catchment_schema'],
        args['catchment_table'],
        args['catchment_geom'])
    catchment_layer = QgsVectorLayer(
        uri.uri(),
        "catchment",
        "postgres")

    # Style the tin, contour and network

    drivetime_style = resources_path(
        'styles',
        'qgis',
        'drivetimes.qml')
    drivetime_layer.loadNamedStyle(drivetime_style)

    network_style = resources_path(
        'styles',
        'qgis',
        'network.qml')
    network_layer.loadNamedStyle(network_style)

    catchment_style = resources_path(
        'styles',
        'qgis',
        'catchment.qml')
    catchment_layer.loadNamedStyle(catchment_style)

    if drivetime_layer.isValid():
        QgsMapLayerRegistry.instance().addMapLayers(
            [drivetime_layer])
    else:
        if parent_dialog:
            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    "Error"),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load drivetimes file!'))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map '
                'Could not load drivetimes file!')

    if network_layer.isValid():
        QgsMapLayerRegistry.instance().addMapLayers(
            [network_layer])
    else:
        if parent_dialog:
            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    "Error"),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load network file!'))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map '
                'Could not load network file!')

    if catchment_layer.isValid():
        QgsMapLayerRegistry.instance().addMapLayers(
            [catchment_layer])
    else:
        if parent_dialog:
            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    "Error"),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load catchment file!'))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map '
                'Could not load catchment file!')
Exemplo n.º 26
0
def calculate_drivetimes(connection, cursor, arguments, dialog,
                         progress_percentage):
    """
    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    :param progress_percentage: the percentage of progress bar
    :type progress_percentage: int

    :returns Progress percentage
    :rtype int

    """

    index = 0

    try:
        rows = query_nearest_nodes(connection, cursor, arguments, dialog)

        # Convert unique column to integer as required by
        # the pgr_dijkstra function

        sql = """ALTER TABLE routable_network ALTER COLUMN
                %(network_id)s SET DATA TYPE int4""" % arguments

        sql = clean_query(sql)

        cursor.execute(sql)
        connection.commit()

        for row in rows:
            # This step is 45% of all steps so calculating
            # percentage of each increment accordingly

            percentage = ((index + 1) / len(rows)) * 45
            percentage = round(percentage, 0)
            catchment_id = row[0]
            arguments["catchment_current_id"] = catchment_id
            if index == 0:
                sql = """ CREATE TABLE
                        IF NOT EXISTS catchment_with_cost AS
                    SELECT
                    id,
                    the_geom,
                    (SELECT sum(cost) FROM (
                       SELECT * FROM pgr_dijkstra('
                       SELECT %(network_id)s AS id,
                          start_id::int4 AS source,
                          end_id::int4 AS target,
                          cost::float8 AS cost
                       FROM routable_network',
                       %(catchment_current_id)s,
                       id,
                       false,
                       false)) AS foo ) AS cost
                    FROM nodes;""" % arguments
                sql = clean_query(sql)
                cursor.execute(sql)
            else:
                sql = """ INSERT INTO catchment_with_cost (
                    SELECT
                        id,
                        the_geom,
                        (SELECT sum(cost) FROM (
                           SELECT * FROM pgr_dijkstra('
                           SELECT  %(network_id)s AS id,
                              start_id::int4 AS source,
                              end_id::int4 AS target,
                              cost::float8 AS cost
                           FROM routable_network',
                           %(catchment_current_id)s,
                           id,
                           false,
                           false)) AS foo ) AS cost
                    FROM nodes);""" % arguments

                sql = clean_query(sql)

                cursor.execute(sql)

            index += 1
            connection.commit()
            progress_percentage += percentage
            if dialog:
                dialog.setValue(progress_percentage)
                label_text = tr(
                    str(index) + " catchment area(s) out of " +
                    str(len(rows)) + " is(are) done")
                dialog.setLabelText(label_text)
        if dialog:
            label_text = tr("Preparing all the catchment areas table")
            dialog.setLabelText(label_text)

    except Exception as exception:
        display_warning_message_box(dialog, "Error",
                                    "Error in calculating drivetimes")

    return progress_percentage
Exemplo n.º 27
0
def isochrone(
        database_name,
        host_name,
        port_number,
        user_name,
        password,
        network,
        network_geom,
        network_id_column,
        catchment,
        catchment_geom,
        catchment_id_column,
        style_checked,
        contour_interval,
        parent_dialog,
        progress_dialog=None):

        """Contains main logic on creating isochrone map
        :param database_name: Database name
        :type database_name: str

        :param host_name: Database host
        :type host_name: str

        :param port_number: Port number for the host
        :type port_number: str

        :param user_name: Username for connection with database
        :type user_name: str

        :param password: Password
        :type password: str

        :param network: Schema and Table containing the network.
        :type network: str

        :param network_geom: Geometry column in network.
        :type network_geom: str

        :param network_id_column: Id column in network.
        :type network_id_column: str

        :param catchment: Schema and Table containing catchment areas.
        :type catchment: str

        :param catchment_geom: Geometry column in catchment.
        :type catchment_geom: str

        :param catchment_id_column: Id column in catchment.
        :type catchment_id_column: str

        :param style_checked: Value for either to create a map style
        or not.
        :type  style_checked: boolean

        :param contour_interval: Interval between contour, if contour
        will be generated
        :type  contour_interval: int

        :param parent_dialog: A dialog that called this function.
        :type parent_dialog: QProgressDialog

        :param progress_dialog: A progess dialog .
        :type progress_dialog: QProgressDialog

        :returns layer_name: temporary path of the isochrones map layer
        :rtype layer_name: str
        """

        # Import files into database, have tables
        # connect to database
        # add the files get the tables name

        connection = psycopg2.connect(
            "dbname='" + str(database_name) + "' "
            "user='******' "
            "host='" + str(host_name) + "' "
            "password='******' ")

        curr = connection.cursor()

        # Create nodes from network

        if progress_dialog:
            progress_dialog.show()

            # Infinite progress bar when the server is fetching data.
            # The progress bar will be updated with the file size later.
            progress_dialog.setMinimum(0)
            progress_dialog.setMaximum(100)

            label_text = tr("Creating network nodes table")
            progress_dialog.setLabelText(label_text)
            progress_dialog.setValue(0)

        network_array = network.split('.')
        network_table = str(network_array[1])
        network_schema = network_array[0]
        catchment = catchment.split('.')
        catchment_table = catchment[1]
        catchment_schema = catchment[0]

        if not network_geom:
            network_geom = "geom"
        if not catchment_geom:
            catchment_geom = "geom"

        arguments = {}
        arguments["network_table"] = network_table
        arguments["network_geom"] = network_geom
        arguments["network_id"] = network_id_column
        arguments["catchment_table"] = catchment_table
        arguments["catchment_geom"] = catchment_geom
        arguments["catchment_id"] = catchment_id_column
        arguments["database_name"] = database_name
        arguments["port_number"] = port_number

        create_network_view(connection, curr, arguments, parent_dialog)

        create_nodes(connection, curr, arguments, parent_dialog)

        # Create routable network
        progress_percentage = 10
        if progress_dialog:
            progress_dialog.setValue(progress_percentage)
            label_text = tr("Creating a routable network table")
            progress_dialog.setLabelText(label_text)

        create_routable_network(connection, curr, arguments, parent_dialog)

        # Find nearest nodes from the catchments
        progress_percentage = 30
        if progress_dialog:
            progress_dialog.setValue(progress_percentage)
            label_text = tr("Preparing the catchment table")
            progress_dialog.setLabelText(label_text)

        update_catchment(connection, curr, arguments, parent_dialog)

        # Calculate drivetime for the nearest nodes

        progress_percentage = 50
        if progress_dialog:
            progress_dialog.setValue(progress_percentage)
            label_text = tr("Calculating drivetime for each catchment area")
            progress_dialog.setLabelText(label_text)

        progress_percentage = calculate_drivetimes(
            connection,
            curr,
            arguments,
            progress_dialog,
            progress_percentage)

        prepare_drivetimes_table(connection, curr, arguments, parent_dialog)

        uri = QgsDataSourceURI()
        # set host name, port, database name, username and password
        uri.setConnection(
            host_name,
            port_number,
            database_name,
            user_name,
            password)
        # set database schema, table name, geometry column and optionally
        # subset (WHERE clause)
        uri.setDataSource(
            network_schema,
            "catchment_final_no_null",
            "the_geom")

        # Export table as shapefile

        layer = QgsVectorLayer(uri.uri(), "isochrones", "ogr")
        temp_layer = QgsVectorLayer(uri.uri(), "isochrones", "postgres")

        QgsMapLayerRegistry.instance().addMapLayers([temp_layer])

        if iface:
            iface.mapCanvas().refresh()

        layer_name = temp_layer.dataProvider().dataSourceUri()

        if style_checked:
            progress_percentage += 1
            if progress_dialog:
                progress_dialog.setValue(progress_percentage)
                label_text = tr("Exporting and preparing isochrone map")
                progress_dialog.setLabelText(label_text)

            # TODO implement style creation logic

            # Run interpolation on the final file (currently using IDW)

            raster_file = idw_interpolation(layer, parent_dialog)

            # Generate drivetimes contour
            try:
                drivetime_layer = generate_drivetimes_contour(
                    raster_file,
                    contour_interval,
                    parent_dialog)
                # Load all the required layers

                args = {}
                args['network_schema'] = network_schema
                args['network_table'] = network_table
                args['network_geom'] = network_geom
                args['catchment_schema'] = catchment_schema
                args['catchment_table'] = catchment_table
                args['catchment_geom'] = catchment_geom

                load_map_layers(uri, parent_dialog, drivetime_layer, args)

            except Exception as exception:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Error'),
                    parent_dialog.tr('Error generating drivetimes'))

            progress_percentage += 4
            if progress_dialog:
                progress_dialog.setValue(progress_percentage)
                label_text = tr("Done loading isochrone map")
                progress_dialog.setLabelText(label_text)

        if progress_dialog:
            progress_dialog.setValue(100)
            progress_dialog.done(QDialog.Accepted)

        return layer_name
Exemplo n.º 28
0
def idw_interpolation(layer, parent_dialog):
    """Run interpolation using inverse distance weight algorithm

    :param layer: Vector layer with drivetimes
    :type layer: QgsVectorLayer

    :param parent_dialog: A dialog that called this function.
    :type parent_dialog: QProgressDialog

    :returns raster_layer: Interpolated raster layer with drivetimes
    :rtype raster_layer: QgsRasterLayer

    """
    raster_layer = None
    try:
        Processing.initialize()
        Processing.updateAlgsList()

        output_raster = processing.runalg('gdalogr:gridinvdist', layer,
                                          'minutes', 2, 0, 0, 0, 0, 0, 0, 0, 5,
                                          "[temporary file]")

        output_file = output_raster['OUTPUT']
        file_info = QFileInfo(output_file)
        base_name = file_info.baseName()

        # retrieving the raster output , styling it and load it in Qgis

        raster_layer = QgsRasterLayer(output_file, base_name)

    except Exception as exception:  # pylint: disable=broad-except
        # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
        if parent_dialog:
            display_warning_message_box(
                parent_dialog, parent_dialog.tr('Error'),
                parent_dialog.tr('Error loading isochrone map,'
                                 'please check if you have processing '
                                 'plugin installed '))
        else:
            display_warning_message_box(
                parent_dialog, 'Error', 'Error loading isochrone map,'
                'please check if you have processing '
                'plugin installed ')

    if raster_layer:
        if raster_layer.isValid():
            color_shader = QgsColorRampShader()
            color_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)
            colors = {
                'deep_green': '#1a9641',
                'light_green': '#a6d96a',
                'pale_yellow': '#ffffc0',
                'light_red': '#fdae61',
                'red': '#d7191c'
            }
            provider = raster_layer.dataProvider()
            stats = provider.bandStatistics(1, QgsRasterBandStats.All,
                                            raster_layer.extent(), 0)

            values = {}

            if stats:
                min = stats.minimumValue
                max = stats.maximumValue
                stat_range = max - min
                add = stat_range / 4
                values[0] = min
                value = min
                for index in range(1, 4):
                    value += add
                    values[index] = value
                values[4] = max
            else:
                display_warning_message_box(
                    parent_dialog, parent_dialog.tr('Error'),
                    parent_dialog.tr('Error loading isochrone map'
                                     ' Problem indexing the isochrones map'))

            color_list = [
                QgsColorRampShader.ColorRampItem(values[0],
                                                 QColor(colors['deep_green'])),
                QgsColorRampShader.ColorRampItem(values[1],
                                                 QColor(
                                                     colors['light_green'])),
                QgsColorRampShader.ColorRampItem(values[2],
                                                 QColor(
                                                     colors['pale_yellow'])),
                QgsColorRampShader.ColorRampItem(values[3],
                                                 QColor(colors['light_red'])),
                QgsColorRampShader.ColorRampItem(values[4],
                                                 QColor(colors['red']))
            ]

            color_shader.setColorRampItemList(color_list)
            raster_shader = QgsRasterShader()
            raster_shader.setRasterShaderFunction(color_shader)

            renderer = QgsSingleBandPseudoColorRenderer(
                raster_layer.dataProvider(), 1, raster_shader)
            raster_layer.setRenderer(renderer)

        else:
            if parent_dialog:
                display_warning_message_box(
                    parent_dialog, parent_dialog.tr('Problem'),
                    parent_dialog.tr('Problem styling the isochrone map'))
            else:
                display_warning_message_box(
                    parent_dialog, 'Problem',
                    'Problem styling the isochrone map')

        QgsMapLayerRegistry.instance().addMapLayers([raster_layer])

    else:
        if parent_dialog:

            display_warning_message_box(
                parent_dialog, parent_dialog.tr('Error'),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load interpolated file!'))
        else:
            display_warning_message_box(
                parent_dialog, 'Error', 'Error loading isochrone map '
                'Could not load interpolated file!')

    return raster_layer
Exemplo n.º 29
0
def load_map_layers(uri, parent_dialog, drivetime_layer, args):
    """Style map layers and load them in Qgis

    :param uri: Connection to the database
    :type uri: QgsDataSourceURI

    :param parent_dialog: A dialog that called this function.
    :type parent_dialog: QProgressDialog

    :param drivetime_layer: A layer containing drivetimes
    :type drivetime_layer: QgsVectorLayer

    :param args: List containing database parameters
    :type args: {}

    """

    uri.setDataSource(args['network_schema'], args['network_table'],
                      args['network_geom'])
    network_layer = QgsVectorLayer(uri.uri(), "network", "postgres")

    uri.setDataSource(args['catchment_schema'], args['catchment_table'],
                      args['catchment_geom'])
    catchment_layer = QgsVectorLayer(uri.uri(), "catchment", "postgres")

    # Style the tin, contour and network

    drivetime_style = resources_path('styles', 'qgis', 'drivetimes.qml')
    drivetime_layer.loadNamedStyle(drivetime_style)

    network_style = resources_path('styles', 'qgis', 'network.qml')
    network_layer.loadNamedStyle(network_style)

    catchment_style = resources_path('styles', 'qgis', 'catchment.qml')
    catchment_layer.loadNamedStyle(catchment_style)

    if drivetime_layer.isValid():
        QgsMapLayerRegistry.instance().addMapLayers([drivetime_layer])
    else:
        if parent_dialog:
            display_warning_message_box(
                parent_dialog, parent_dialog.tr("Error"),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load drivetimes file!'))
        else:
            display_warning_message_box(
                parent_dialog, 'Error', 'Error loading isochrone map '
                'Could not load drivetimes file!')

    if network_layer.isValid():
        QgsMapLayerRegistry.instance().addMapLayers([network_layer])
    else:
        if parent_dialog:
            display_warning_message_box(
                parent_dialog, parent_dialog.tr("Error"),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load network file!'))
        else:
            display_warning_message_box(
                parent_dialog, 'Error', 'Error loading isochrone map '
                'Could not load network file!')

    if catchment_layer.isValid():
        QgsMapLayerRegistry.instance().addMapLayers([catchment_layer])
    else:
        if parent_dialog:
            display_warning_message_box(
                parent_dialog, parent_dialog.tr("Error"),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load catchment file!'))
        else:
            display_warning_message_box(
                parent_dialog, 'Error', 'Error loading isochrone map '
                'Could not load catchment file!')
Exemplo n.º 30
0
def prepare_drivetimes_table(connection, cursor, arguments, dialog):
    """

    :param connection: Database connection
    :type connection:

    :param cursor: Database connection cursor
    :type cursor:

    :param arguments: List of required parameters in
     querying the database
    :type arguments: {}

    :param dialog: Dialog attached to this method
    :type dialog: Qdialog

    :param progress_percentage: the percentage of progress bar
    :type progress_percentage: int

    """
    try:
        sql = """ DROP TABLE IF EXISTS catchment_final"""
        sql = clean_query(sql)

        cursor.execute(sql)

        connection.commit()

        sql = """ CREATE TABLE IF NOT EXISTS catchment_final AS
               SELECT id, the_geom, min (cost) AS %s
               FROM catchment_with_cost
               GROUP By id, the_geom
            """ % "drivetime"

        sql = clean_query(sql)

        cursor.execute(sql)

        connection.commit()

        sql = """DROP TABLE IF EXISTS catchment_final_no_null"""

        sql = clean_query(sql)

        cursor.execute(sql)

        connection.commit()

        sql = """ CREATE TABLE catchment_final_no_null AS
                SELECT *, (drivetime * 60) AS minutes FROM catchment_final
                WHERE %s IS NOT NULL """ % "drivetime"

        sql = clean_query(sql)

        cursor.execute(sql)

        connection.commit()
    except Exception as exception:
        display_warning_message_box(
            dialog,
            "Error",
            "Error in preparing drivetimes table")
Exemplo n.º 31
0
def idw_interpolation(layer, parent_dialog):
    """Run interpolation using inverse distance weight algorithm

    :param layer: Vector layer with drivetimes
    :type layer: QgsVectorLayer

    :param parent_dialog: A dialog that called this function.
    :type parent_dialog: QProgressDialog

    :returns raster_layer: Interpolated raster layer with drivetimes
    :rtype raster_layer: QgsRasterLayer

    """
    raster_layer = None
    try:
        Processing.initialize()
        Processing.updateAlgsList()

        output_raster = processing.runalg(
        'gdalogr:gridinvdist',
        layer,
        'minutes',
        2, 0, 0, 0, 0, 0, 0, 0, 5,
        "[temporary file]")

        output_file = output_raster['OUTPUT']
        file_info = QFileInfo(output_file)
        base_name = file_info.baseName()

        # retrieving the raster output , styling it and load it in Qgis

        raster_layer = QgsRasterLayer(output_file, base_name)

    except Exception as exception:  # pylint: disable=broad-except
            # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
        if parent_dialog:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Error'),
                    parent_dialog.tr('Error loading isochrone map,'
                                     'please check if you have processing '
                                     'plugin installed '))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map,'
                'please check if you have processing '
                'plugin installed ')

    if raster_layer:
        if raster_layer.isValid():
            color_shader = QgsColorRampShader()
            color_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)
            colors = {
                'deep_green': '#1a9641',
                'light_green': '#a6d96a',
                'pale_yellow': '#ffffc0',
                'light_red': '#fdae61',
                'red': '#d7191c'
            }
            provider = raster_layer.dataProvider()
            stats = provider.bandStatistics(
                1,
                QgsRasterBandStats.All,
                raster_layer.extent(),
                0)

            values = {}

            if stats:
                min = stats.minimumValue
                max = stats.maximumValue
                stat_range = max - min
                add = stat_range / 4
                values[0] = min
                value = min
                for index in range(1, 4):
                    value += add
                    values[index] = value
                values[4] = max
            else:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Error'),
                    parent_dialog.tr('Error loading isochrone map'
                                     ' Problem indexing the isochrones map'))

            color_list = [
                QgsColorRampShader.ColorRampItem(
                    values[0],
                    QColor(colors['deep_green'])),
                QgsColorRampShader.ColorRampItem(
                    values[1],
                    QColor(colors['light_green'])),
                QgsColorRampShader.ColorRampItem(
                    values[2],
                    QColor(colors['pale_yellow'])),
                QgsColorRampShader.ColorRampItem(
                    values[3],
                    QColor(colors['light_red'])),
                QgsColorRampShader.ColorRampItem(
                    values[4],
                    QColor(colors['red']))
            ]

            color_shader.setColorRampItemList(color_list)
            raster_shader = QgsRasterShader()
            raster_shader.setRasterShaderFunction(color_shader)

            renderer = QgsSingleBandPseudoColorRenderer(
                raster_layer.dataProvider(),
                1,
                raster_shader)
            raster_layer.setRenderer(renderer)

        else:
            if parent_dialog:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Problem'),
                    parent_dialog.tr('Problem styling the isochrone map'))
            else:
                display_warning_message_box(
                    parent_dialog,
                    'Problem',
                    'Problem styling the isochrone map')

        QgsMapLayerRegistry.instance().addMapLayers([raster_layer])

    else:
        if parent_dialog:

            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    'Error'),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load interpolated file!'))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map '
                'Could not load interpolated file!')

    return raster_layer
Exemplo n.º 32
0
def isochrone(database_name,
              host_name,
              port_number,
              user_name,
              password,
              network,
              network_geom,
              network_id_column,
              catchment,
              catchment_geom,
              catchment_id_column,
              style_checked,
              contour_interval,
              parent_dialog,
              progress_dialog=None):
    """Contains main logic on creating isochrone map
        :param database_name: Database name
        :type database_name: str

        :param host_name: Database host
        :type host_name: str

        :param port_number: Port number for the host
        :type port_number: str

        :param user_name: Username for connection with database
        :type user_name: str

        :param password: Password
        :type password: str

        :param network: Schema and Table containing the network.
        :type network: str

        :param network_geom: Geometry column in network.
        :type network_geom: str

        :param network_id_column: Id column in network.
        :type network_id_column: str

        :param catchment: Schema and Table containing catchment areas.
        :type catchment: str

        :param catchment_geom: Geometry column in catchment.
        :type catchment_geom: str

        :param catchment_id_column: Id column in catchment.
        :type catchment_id_column: str

        :param style_checked: Value for either to create a map style
        or not.
        :type  style_checked: boolean

        :param contour_interval: Interval between contour, if contour
        will be generated
        :type  contour_interval: int

        :param parent_dialog: A dialog that called this function.
        :type parent_dialog: QProgressDialog

        :param progress_dialog: A progess dialog .
        :type progress_dialog: QProgressDialog

        :returns layer_name: temporary path of the isochrones map layer
        :rtype layer_name: str
        """

    # Import files into database, have tables
    # connect to database
    # add the files get the tables name

    connection = psycopg2.connect("dbname='" + str(database_name) + "' "
                                  "user='******' "
                                  "host='" + str(host_name) + "' "
                                  "password='******' ")

    curr = connection.cursor()

    # Create nodes from network

    if progress_dialog:
        progress_dialog.show()

        # Infinite progress bar when the server is fetching data.
        # The progress bar will be updated with the file size later.
        progress_dialog.setMinimum(0)
        progress_dialog.setMaximum(100)

        label_text = tr("Creating network nodes table")
        progress_dialog.setLabelText(label_text)
        progress_dialog.setValue(0)

    network_array = network.split('.')
    network_table = str(network_array[1])
    network_schema = network_array[0]
    catchment = catchment.split('.')
    catchment_table = catchment[1]
    catchment_schema = catchment[0]

    if not network_geom:
        network_geom = "geom"
    if not catchment_geom:
        catchment_geom = "geom"

    arguments = {}
    arguments["network_table"] = network_table
    arguments["network_geom"] = network_geom
    arguments["network_id"] = network_id_column
    arguments["catchment_table"] = catchment_table
    arguments["catchment_geom"] = catchment_geom
    arguments["catchment_id"] = catchment_id_column
    arguments["database_name"] = database_name
    arguments["port_number"] = port_number

    create_network_view(connection, curr, arguments, parent_dialog)

    create_nodes(connection, curr, arguments, parent_dialog)

    # Create routable network
    progress_percentage = 10
    if progress_dialog:
        progress_dialog.setValue(progress_percentage)
        label_text = tr("Creating a routable network table")
        progress_dialog.setLabelText(label_text)

    create_routable_network(connection, curr, arguments, parent_dialog)

    # Find nearest nodes from the catchments
    progress_percentage = 30
    if progress_dialog:
        progress_dialog.setValue(progress_percentage)
        label_text = tr("Preparing the catchment table")
        progress_dialog.setLabelText(label_text)

    update_catchment(connection, curr, arguments, parent_dialog)

    # Calculate drivetime for the nearest nodes

    progress_percentage = 50
    if progress_dialog:
        progress_dialog.setValue(progress_percentage)
        label_text = tr("Calculating drivetime for each catchment area")
        progress_dialog.setLabelText(label_text)

    progress_percentage = calculate_drivetimes(connection, curr, arguments,
                                               progress_dialog,
                                               progress_percentage)

    prepare_drivetimes_table(connection, curr, arguments, parent_dialog)

    uri = QgsDataSourceURI()
    # set host name, port, database name, username and password
    uri.setConnection(host_name, port_number, database_name, user_name,
                      password)
    # set database schema, table name, geometry column and optionally
    # subset (WHERE clause)
    uri.setDataSource(network_schema, "catchment_final_no_null", "the_geom")

    # Export table as shapefile

    layer = QgsVectorLayer(uri.uri(), "isochrones", "ogr")
    temp_layer = QgsVectorLayer(uri.uri(), "isochrones", "postgres")

    QgsMapLayerRegistry.instance().addMapLayers([temp_layer])

    if iface:
        iface.mapCanvas().refresh()

    layer_name = temp_layer.dataProvider().dataSourceUri()

    if style_checked:
        progress_percentage += 1
        if progress_dialog:
            progress_dialog.setValue(progress_percentage)
            label_text = tr("Exporting and preparing isochrone map")
            progress_dialog.setLabelText(label_text)

        # TODO implement style creation logic

        # Run interpolation on the final file (currently using IDW)

        raster_file = idw_interpolation(layer, parent_dialog)

        # Generate drivetimes contour
        try:
            drivetime_layer = generate_drivetimes_contour(
                raster_file, contour_interval, parent_dialog)
            # Load all the required layers

            args = {}
            args['network_schema'] = network_schema
            args['network_table'] = network_table
            args['network_geom'] = network_geom
            args['catchment_schema'] = catchment_schema
            args['catchment_table'] = catchment_table
            args['catchment_geom'] = catchment_geom

            load_map_layers(uri, parent_dialog, drivetime_layer, args)

        except Exception as exception:
            display_warning_message_box(
                parent_dialog, parent_dialog.tr('Error'),
                parent_dialog.tr('Error generating drivetimes'))

        progress_percentage += 4
        if progress_dialog:
            progress_dialog.setValue(progress_percentage)
            label_text = tr("Done loading isochrone map")
            progress_dialog.setLabelText(label_text)

    if progress_dialog:
        progress_dialog.setValue(100)
        progress_dialog.done(QDialog.Accepted)

    return layer_name