Skip to main content
Bounty Ended with 75 reputation awarded by CommunityBot
added 347 characters in body
Source Link
J. Monticolo
  • 15.9k
  • 1
  • 29
  • 65

I tried to create a working Python code and I considered that you have many SQLite DBs with just one layer (same name as the DB file in lowercase) in your folders r1 and d1.

Your databases are SQLite DB not spatially aware and I loaded the layers with ogr and assign a projection, in your case the OSGB 1936 / British National Grid EPSG: 27700, to tell what coordinate reference system (CRS) layers have.

Once QGIS know the projections, it can do the Service area processing and export geometries.

Here is my working code under QGIS 3.16 (Windows, but I took your question OSX paths for the code below) :

import os
import processing
import glob
import string

#Folder where my road networks are stored
Select_folderRoads='//Mac/Home/FINAL/March2021/r1/'
#Folder where the starting points/nodes are stored
Select_folderSDH='//Mac/Home/FINAL/March2021/d1/'
#Folder where the output is to be stored
Save_results='//Mac/Home/FINAL/March2021/path250m/'
# Set working directory to roads folder
os.chdir(Select_folderRoads)

uk_crs = QgsCoordinateReferenceSystem(27700)

# iterate over roads DB network layers
for dbname in glob.glob("*.sqlite"):
    # get layer name from SQLite DB name
    lyr_name = dbname.split(".sqlite")[0].lower()
    # get roads and points layers, set their CRS
    roads_layer = QgsVectorLayer(f"{Select_folderRoads}{dbname}|layername={lyr_name}", "roads_lyr", "ogr")
    roads_layer.setCrs(uk_crs)
    points_layer = QgsVectorLayer(f"{Select_folderSDH}{dbname}|layername={lyr_name}", "points_lyr", "ogr")
    points_layer.setCrs(uk_crs)

    # processing algorithm that output result as GPKG
    result = processing.run(
        "native:serviceareafromlayer",
        {'DEFAULT_DIRECTION': 2,
        'DEFAULT_SPEED': 50.0,
        'DIRECTION_FIELD': '',
        'INCLUDE_BOUNDS': False,
        'INPUT': roads_layer,
        'OUTPUT_LINES': f"{Save_results}{lyr_name}",
        'START_POINTS': points_layer,
        'STRATEGY': 0,
        'TOLERANCE': 0.0,
        'TRAVEL_COST': 250.0,
        'VALUE_BACKWARD': '',
        'VALUE_BOTH': '',
        'VALUE_FORWARD': ''}
    )

I tried to create a working Python code and I considered that you have many SQLite DBs with just one layer (same name as the DB file in lowercase) in your folders r1 and d1.

Here is my working code under QGIS 3.16 (Windows, but I took your question OSX paths for the code below) :

import os
import processing
import glob
import string

#Folder where my road networks are stored
Select_folderRoads='//Mac/Home/FINAL/March2021/r1/'
#Folder where the starting points/nodes are stored
Select_folderSDH='//Mac/Home/FINAL/March2021/d1/'
#Folder where the output is to be stored
Save_results='//Mac/Home/FINAL/March2021/path250m/'
# Set working directory to roads folder
os.chdir(Select_folderRoads)

uk_crs = QgsCoordinateReferenceSystem(27700)

# iterate over roads DB network layers
for dbname in glob.glob("*.sqlite"):
    # get layer name from SQLite DB name
    lyr_name = dbname.split(".sqlite")[0].lower()
    # get roads and points layers, set their CRS
    roads_layer = QgsVectorLayer(f"{Select_folderRoads}{dbname}|layername={lyr_name}", "roads_lyr", "ogr")
    roads_layer.setCrs(uk_crs)
    points_layer = QgsVectorLayer(f"{Select_folderSDH}{dbname}|layername={lyr_name}", "points_lyr", "ogr")
    points_layer.setCrs(uk_crs)

    # processing algorithm that output result as GPKG
    result = processing.run(
        "native:serviceareafromlayer",
        {'DEFAULT_DIRECTION': 2,
        'DEFAULT_SPEED': 50.0,
        'DIRECTION_FIELD': '',
        'INCLUDE_BOUNDS': False,
        'INPUT': roads_layer,
        'OUTPUT_LINES': f"{Save_results}{lyr_name}",
        'START_POINTS': points_layer,
        'STRATEGY': 0,
        'TOLERANCE': 0.0,
        'TRAVEL_COST': 250.0,
        'VALUE_BACKWARD': '',
        'VALUE_BOTH': '',
        'VALUE_FORWARD': ''}
    )

I tried to create a working Python code and I considered that you have many SQLite DBs with just one layer (same name as the DB file in lowercase) in your folders r1 and d1.

Your databases are SQLite DB not spatially aware and I loaded the layers with ogr and assign a projection, in your case the OSGB 1936 / British National Grid EPSG: 27700, to tell what coordinate reference system (CRS) layers have.

Once QGIS know the projections, it can do the Service area processing and export geometries.

Here is my working code under QGIS 3.16 (Windows, but I took your question OSX paths for the code below) :

import os
import processing
import glob
import string

#Folder where my road networks are stored
Select_folderRoads='//Mac/Home/FINAL/March2021/r1/'
#Folder where the starting points/nodes are stored
Select_folderSDH='//Mac/Home/FINAL/March2021/d1/'
#Folder where the output is to be stored
Save_results='//Mac/Home/FINAL/March2021/path250m/'
# Set working directory to roads folder
os.chdir(Select_folderRoads)

uk_crs = QgsCoordinateReferenceSystem(27700)

# iterate over roads DB network layers
for dbname in glob.glob("*.sqlite"):
    # get layer name from SQLite DB name
    lyr_name = dbname.split(".sqlite")[0].lower()
    # get roads and points layers, set their CRS
    roads_layer = QgsVectorLayer(f"{Select_folderRoads}{dbname}|layername={lyr_name}", "roads_lyr", "ogr")
    roads_layer.setCrs(uk_crs)
    points_layer = QgsVectorLayer(f"{Select_folderSDH}{dbname}|layername={lyr_name}", "points_lyr", "ogr")
    points_layer.setCrs(uk_crs)

    # processing algorithm that output result as GPKG
    result = processing.run(
        "native:serviceareafromlayer",
        {'DEFAULT_DIRECTION': 2,
        'DEFAULT_SPEED': 50.0,
        'DIRECTION_FIELD': '',
        'INCLUDE_BOUNDS': False,
        'INPUT': roads_layer,
        'OUTPUT_LINES': f"{Save_results}{lyr_name}",
        'START_POINTS': points_layer,
        'STRATEGY': 0,
        'TOLERANCE': 0.0,
        'TRAVEL_COST': 250.0,
        'VALUE_BACKWARD': '',
        'VALUE_BOTH': '',
        'VALUE_FORWARD': ''}
    )
review code, iterate over many SQLite (not spatialite DB), set CRS
Source Link
J. Monticolo
  • 15.9k
  • 1
  • 29
  • 65

I tried to create a working Python code and I considered that you have onlymany SQLite DBs with just one Spatialitelayer (same name as the DB file in each oflowercase) in your r1 and d1 folders, each DB contains same amount of layers with same names, just r1 geometries are roads and d1 points.

Here is my working code under QGIS 3.16 (Windows, but I took your question OSX paths for the code below) :

import os
import processing
import glob
import string

# Folder#Folder where my road networks are stored
Select_folderRoads = "Select_folderRoads='//Mac/Home/FINAL/March2021/r1/"'
# Folder#Folder where the starting points/nodes are stored
Select_folderSDH = "Select_folderSDH='//Mac/Home/FINAL/March2021/d1/"'
# Folder#Folder where the output is to be stored
Save_results = "Save_results='//Mac/Home/FINAL/March2021/path250m/"'
# Set working directory to roads folder
os.chdir(Select_folderRoads)
# get roads Spatialite DB name
sqlite_db = glob.glob("*.sqlite")
# get layers DB paths
roads_db = f"{Select_folderRoads}{sqlite_db[0]}"
points_db = f"{Select_folderSDH}{sqlite_db[0]}"
# create a layer from the roads DB to get layers names
uri = QgsDataSourceUri()
uri.setDatabase(roads_db)
# get DB vector layers
query = "(SELECT table_name FROM vector_layers)"
uri.setDataSource("", query, "")
db_tablesuk_crs = QgsVectorLayer(uri.uriQgsCoordinateReferenceSystem(), "db_tables", "spatialite"27700)
# if table layer is valid
if db_tables.isValid():
    # iterate over roads DB network layers
    for tabdbname in db_tablesglob.getFeaturesglob("*.sqlite"):
        # get layer name
  from SQLite DB name
    lyr_name = tabdbname.attributesplit("table_name"".sqlite")[0].lower()
        # get roads layerand path
points layers, set their CRS
    testinlayerroads_layer = QgsVectorLayer(f"{roads_dbSelect_folderRoads}{dbname}|layername={lyr_name}"
        # points, layer"roads_lyr", path"ogr")
    roads_layer.setCrs(uk_crs)
    startnamepoints_layer = QgsVectorLayer(f"{points_dbSelect_folderSDH}{dbname}|layername={lyr_name}", "points_lyr", "ogr")
    points_layer.setCrs(uk_crs)

    # processing algorithm that output result as GPKG
        result = processing.run(
            "native:serviceareafromlayer",
            {'DEFAULT_DIRECTION': 2,
            'DEFAULT_SPEED': 50.0,
            'DIRECTION_FIELD': '',
            'INCLUDE_BOUNDS': False,
            'INPUT': testinlayerroads_layer,
            'OUTPUT_LINES': f"{Save_results}{lyr_name}",
            'START_POINTS': startnamepoints_layer,
            'STRATEGY': 0,
            'TOLERANCE': 0.0,
            'TRAVEL_COST': 250.0,
            'VALUE_BACKWARD': '',
            'VALUE_BOTH': '',
            'VALUE_FORWARD': ''}
        )

I tried to create a working Python code and I considered that you have only one Spatialite DB in each of your r1 and d1 folders, each DB contains same amount of layers with same names, just r1 geometries are roads and d1 points.

Here is my working code under QGIS 3.16 (Windows) :

import os
import processing
import glob
import string

# Folder where my road networks are stored
Select_folderRoads = "//Mac/Home/FINAL/March2021/r1/"
# Folder where the starting points/nodes are stored
Select_folderSDH = "//Mac/Home/FINAL/March2021/d1/"
# Folder where the output is to be stored
Save_results = "//Mac/Home/FINAL/March2021/path250m/"
# Set working directory to roads folder
os.chdir(Select_folderRoads)
# get roads Spatialite DB name
sqlite_db = glob.glob("*.sqlite")
# get layers DB paths
roads_db = f"{Select_folderRoads}{sqlite_db[0]}"
points_db = f"{Select_folderSDH}{sqlite_db[0]}"
# create a layer from the roads DB to get layers names
uri = QgsDataSourceUri()
uri.setDatabase(roads_db)
# get DB vector layers
query = "(SELECT table_name FROM vector_layers)"
uri.setDataSource("", query, "")
db_tables = QgsVectorLayer(uri.uri(), "db_tables", "spatialite")
# if table layer is valid
if db_tables.isValid():
    # iterate over roads DB network layers
    for tab in db_tables.getFeatures():
        # get layer name
         lyr_name = tab.attribute("table_name")
        # roads layer path
        testinlayer = f"{roads_db}|layername={lyr_name}"
        # points layer path
        startname = f"{points_db}|layername={lyr_name}"
        # processing algorithm that output result as GPKG
        result = processing.run(
            "native:serviceareafromlayer",
            {'DEFAULT_DIRECTION': 2,
            'DEFAULT_SPEED': 50.0,
            'DIRECTION_FIELD': '',
            'INCLUDE_BOUNDS': False,
            'INPUT': testinlayer,
            'OUTPUT_LINES': f"{Save_results}{lyr_name}",
            'START_POINTS': startname,
            'STRATEGY': 0,
            'TOLERANCE': 0.0,
            'TRAVEL_COST': 250.0,
            'VALUE_BACKWARD': '',
            'VALUE_BOTH': '',
            'VALUE_FORWARD': ''}
        )

I tried to create a working Python code and I considered that you have many SQLite DBs with just one layer (same name as the DB file in lowercase) in your folders r1 and d1.

Here is my working code under QGIS 3.16 (Windows, but I took your question OSX paths for the code below) :

import os
import processing
import glob
import string

#Folder where my road networks are stored
Select_folderRoads='//Mac/Home/FINAL/March2021/r1/'
#Folder where the starting points/nodes are stored
Select_folderSDH='//Mac/Home/FINAL/March2021/d1/'
#Folder where the output is to be stored
Save_results='//Mac/Home/FINAL/March2021/path250m/'
# Set working directory to roads folder
os.chdir(Select_folderRoads)

uk_crs = QgsCoordinateReferenceSystem(27700)

# iterate over roads DB network layers
for dbname in glob.glob("*.sqlite"):
    # get layer name from SQLite DB name
    lyr_name = dbname.split(".sqlite")[0].lower()
    # get roads and points layers, set their CRS
    roads_layer = QgsVectorLayer(f"{Select_folderRoads}{dbname}|layername={lyr_name}", "roads_lyr", "ogr")
    roads_layer.setCrs(uk_crs)
    points_layer = QgsVectorLayer(f"{Select_folderSDH}{dbname}|layername={lyr_name}", "points_lyr", "ogr")
    points_layer.setCrs(uk_crs)

    # processing algorithm that output result as GPKG
    result = processing.run(
        "native:serviceareafromlayer",
        {'DEFAULT_DIRECTION': 2,
        'DEFAULT_SPEED': 50.0,
        'DIRECTION_FIELD': '',
        'INCLUDE_BOUNDS': False,
        'INPUT': roads_layer,
        'OUTPUT_LINES': f"{Save_results}{lyr_name}",
        'START_POINTS': points_layer,
        'STRATEGY': 0,
        'TOLERANCE': 0.0,
        'TRAVEL_COST': 250.0,
        'VALUE_BACKWARD': '',
        'VALUE_BOTH': '',
        'VALUE_FORWARD': ''}
    )
Source Link
J. Monticolo
  • 15.9k
  • 1
  • 29
  • 65

I tried to create a working Python code and I considered that you have only one Spatialite DB in each of your r1 and d1 folders, each DB contains same amount of layers with same names, just r1 geometries are roads and d1 points.

Here is my working code under QGIS 3.16 (Windows) :

import os
import processing
import glob
import string

# Folder where my road networks are stored
Select_folderRoads = "//Mac/Home/FINAL/March2021/r1/"
# Folder where the starting points/nodes are stored
Select_folderSDH = "//Mac/Home/FINAL/March2021/d1/"
# Folder where the output is to be stored
Save_results = "//Mac/Home/FINAL/March2021/path250m/"
# Set working directory to roads folder
os.chdir(Select_folderRoads)
# get roads Spatialite DB name
sqlite_db = glob.glob("*.sqlite")
# get layers DB paths
roads_db = f"{Select_folderRoads}{sqlite_db[0]}"
points_db = f"{Select_folderSDH}{sqlite_db[0]}"
# create a layer from the roads DB to get layers names
uri = QgsDataSourceUri()
uri.setDatabase(roads_db)
# get DB vector layers
query = "(SELECT table_name FROM vector_layers)"
uri.setDataSource("", query, "")
db_tables = QgsVectorLayer(uri.uri(), "db_tables", "spatialite")
# if table layer is valid
if db_tables.isValid():
    # iterate over roads DB network layers
    for tab in db_tables.getFeatures():
        # get layer name
        lyr_name = tab.attribute("table_name")
        # roads layer path
        testinlayer = f"{roads_db}|layername={lyr_name}"
        # points layer path
        startname = f"{points_db}|layername={lyr_name}"
        # processing algorithm that output result as GPKG
        result = processing.run(
            "native:serviceareafromlayer",
            {'DEFAULT_DIRECTION': 2,
            'DEFAULT_SPEED': 50.0,
            'DIRECTION_FIELD': '',
            'INCLUDE_BOUNDS': False,
            'INPUT': testinlayer,
            'OUTPUT_LINES': f"{Save_results}{lyr_name}",
            'START_POINTS': startname,
            'STRATEGY': 0,
            'TOLERANCE': 0.0,
            'TRAVEL_COST': 250.0,
            'VALUE_BACKWARD': '',
            'VALUE_BOTH': '',
            'VALUE_FORWARD': ''}
        )