Skip to content

Commit

Permalink
Merge pull request #905 from j3r3m1/division_per0
Browse files Browse the repository at this point in the history
Solve #863
  • Loading branch information
ebocher authored Jan 11, 2024
2 parents 9084906 + 23a4e87 commit 8d5254a
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@
package org.orbisgis.geoclimate.bdtopo

import groovy.transform.BaseScript
import net.postgis.jdbc.geometry.LineString
import org.locationtech.jts.geom.Geometry
import org.locationtech.jts.geom.Polygon
import org.orbisgis.data.H2GIS
import org.orbisgis.data.api.dataset.ISpatialTable
import org.orbisgis.data.jdbc.JdbcDataSource
import org.orbisgis.geoclimate.Geoindicators

Expand Down Expand Up @@ -164,7 +162,7 @@ String formatBuildingLayer(JdbcDataSource datasource, String building, String zo
height_roof = height_wall
}
//Update NB_LEV, HEIGHT_WALL and HEIGHT_ROOF
def formatedHeight = formatHeightsAndNbLevels(height_wall, height_roof, nb_lev, h_lev_min,
def formatedHeight = Geoindicators.WorkflowGeoIndicators.formatHeightsAndNbLevels(height_wall, height_roof, nb_lev, h_lev_min,
feature_type, building_type_level)

def zIndex = 0
Expand Down Expand Up @@ -753,63 +751,6 @@ String formatVegetationLayer(JdbcDataSource datasource, String vegetation, Strin
return outputTableName
}


/**
* Rule to guarantee the height wall, height roof and number of levels values
* @param heightWall value
* @param heightRoof value
* @param nbLevels value
* @param h_lev_min value
* @return a map with the new values
*/
static Map formatHeightsAndNbLevels(def heightWall, def heightRoof, def nbLevels, def h_lev_min,
def buildingType, def levelBuildingTypeMap) {
//Use the BDTopo values
if (heightWall != 0 && heightRoof != 0 && nbLevels != 0) {
return [heightWall: heightWall, heightRoof: heightRoof, nbLevels: nbLevels, estimated: false]
}
//Initialisation of heights and number of levels
// Update height_wall
boolean estimated = false
if (heightWall == 0) {
if (!heightRoof || heightRoof == 0) {
if (nbLevels == 0) {
nbLevels = levelBuildingTypeMap[buildingType]
if (!nbLevels) {
nbLevels = 1
}
heightWall = h_lev_min * nbLevels
heightRoof = heightWall
estimated = true
} else {
heightWall = h_lev_min * nbLevels
heightRoof = heightWall
}
} else {
heightWall = heightRoof
nbLevels = Math.max(Math.floor(heightWall / h_lev_min), 1)
}
} else if (heightWall == heightRoof) {
if (nbLevels == 0) {
nbLevels = Math.max(Math.floor(heightWall / h_lev_min), 1)
}
}
// Control of heights and number of levels
// Check if height_roof is lower than height_wall. If yes, then correct height_roof
else if (heightWall > heightRoof) {
heightRoof = heightWall
if (nbLevels == 0) {
nbLevels = Math.max(Math.floor(heightWall / h_lev_min), 1)
}
} else if (heightRoof > heightWall) {
if (nbLevels == 0) {
nbLevels = Math.max(Math.floor(heightRoof / h_lev_min), 1)
}
}
return [heightWall: heightWall, heightRoof: heightRoof, nbLevels: nbLevels, estimated: estimated]

}

/**
* This process is used to transform the BDTopo impervious table into a table that matches the constraints
* of the geoClimate Input Model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ Map computeAllGeoIndicators(JdbcDataSource datasource, String zone, String build
def indicatorUse = inputParameters.indicatorUse

//Estimate height
if (inputParameters.buildingHeightModelName && datasource.getRowCount(building) > 0) {
if (inputParameters.buildingHeightModelName && datasource.getRowCount(buildingEstimateTableName) > 0) {
def start = System.currentTimeMillis()
enableTableCache()
def buildingTableName
Expand Down Expand Up @@ -1424,7 +1424,7 @@ Map estimateBuildingHeight(JdbcDataSource datasource, String zone, String buildi
FROM $buildingIndicatorsForHeightEst a
RIGHT JOIN $building_estimate b
ON a.id_build=b.id_build
WHERE b.ESTIMATED = true AND a.ID_RSU IS NOT NULL;""".toString()
WHERE a.ID_RSU IS NOT NULL;""".toString()

info "Collect building indicators to estimate the height"

Expand All @@ -1435,7 +1435,7 @@ Map estimateBuildingHeight(JdbcDataSource datasource, String zone, String buildi
prefixName)

def buildingTableName = "BUILDING_TABLE_WITH_RSU_AND_BLOCK_ID"
def nbBuildingEstimated
int nbBuildingEstimated =0
def buildEstimatedHeight
if (datasource.getTable(gatheredScales).isEmpty()) {
info "No building height to estimate"
Expand All @@ -1462,11 +1462,11 @@ Map estimateBuildingHeight(JdbcDataSource datasource, String zone, String buildi

datasource.createIndex(buildEstimatedHeight, "id_build")

def newEstimatedHeigthWithIndicators = "NEW_BUILDING_INDICATORS_${UUID.randomUUID().toString().replaceAll("-", "_")}"
def formatedBuildEstimatedHeight = "INPUT_BUILDING_REFORMATED_${UUID.randomUUID().toString().replaceAll("-", "_")}"

//Use build table indicators
datasource.execute """DROP TABLE IF EXISTS $newEstimatedHeigthWithIndicators;
CREATE TABLE $newEstimatedHeigthWithIndicators as
datasource.execute """DROP TABLE IF EXISTS $formatedBuildEstimatedHeight;
CREATE TABLE $formatedBuildEstimatedHeight as
SELECT a.THE_GEOM, a.ID_BUILD,a.ID_SOURCE,
CASE WHEN b.HEIGHT_ROOF IS NULL THEN a.HEIGHT_WALL ELSE 0 END AS HEIGHT_WALL ,
COALESCE(b.HEIGHT_ROOF, a.HEIGHT_ROOF) AS HEIGHT_ROOF,
Expand All @@ -1476,14 +1476,13 @@ Map estimateBuildingHeight(JdbcDataSource datasource, String zone, String buildi

//We must format only estimated buildings
//Apply format on the new abstract table
def epsg = datasource."$newEstimatedHeigthWithIndicators".srid;
buildingTableName = formatEstimatedBuilding(datasource, newEstimatedHeigthWithIndicators, epsg)


def epsg = datasource.getSrid(formatedBuildEstimatedHeight)
buildingTableName = formatEstimatedBuilding(datasource, formatedBuildEstimatedHeight, epsg)
//Drop intermediate tables
datasource.execute """DROP TABLE IF EXISTS $estimated_building_with_indicators,
$newEstimatedHeigthWithIndicators, $buildEstimatedHeight,
$formatedBuildEstimatedHeight, $buildEstimatedHeight,
$gatheredScales""".toString()

}

return ["building" : buildingTableName,
Expand Down Expand Up @@ -2164,13 +2163,14 @@ String formatEstimatedBuilding(JdbcDataSource datasource, String inputTableName,
if (inputSpatialTable.rowCount > 0) {
def columnNames = inputSpatialTable.columns
queryMapper += " ${columnNames.join(",")} FROM $inputTableName"

datasource.withBatch(100) { stmt ->
datasource.eachRow(queryMapper) { row ->
def heightRoof = row.height_roof
def heightWall = heightRoof
def type = row.type
def nbLevels = Math.floor(heightRoof / h_lev_min)
def formatedData = formatHeightsAndNbLevels(null, heightRoof, 0, h_lev_min,
type, null)
def nbLevels = formatedData.nbLevels
def heightWall = formatedData.heightWall
stmt.addBatch """
INSERT INTO ${outputTableName} values(
ST_GEOMFROMTEXT('${row.the_geom}',$epsg),
Expand All @@ -2194,6 +2194,63 @@ String formatEstimatedBuilding(JdbcDataSource datasource, String inputTableName,
}


/**
* Rule to guarantee the height wall, height roof and number of levels values
* @param heightWall value
* @param heightRoof value
* @param nbLevels value
* @param h_lev_min value
* @return a map with the new values
*/
static Map formatHeightsAndNbLevels(def heightWall, def heightRoof, def nbLevels, def h_lev_min,
def buildingType, def levelBuildingTypeMap) {
//Use the BDTopo values
if (heightWall != 0 && heightRoof != 0 && nbLevels != 0) {
return [heightWall: heightWall, heightRoof: heightRoof, nbLevels: nbLevels, estimated: false]
}
//Initialisation of heights and number of levels
// Update height_wall
boolean estimated = false
if (heightWall == 0) {
if (!heightRoof || heightRoof == 0) {
if (nbLevels == 0) {
nbLevels = levelBuildingTypeMap[buildingType]
if (!nbLevels) {
nbLevels = 1
}
heightWall = h_lev_min * nbLevels
heightRoof = heightWall
estimated = true
} else {
heightWall = h_lev_min * nbLevels
heightRoof = heightWall
}
} else {
heightWall = heightRoof
nbLevels = Math.max(Math.floor(heightWall / h_lev_min), 1)
}
} else if (heightWall == heightRoof) {
if (nbLevels == 0) {
nbLevels = Math.max(Math.floor(heightWall / h_lev_min), 1)
}
}
// Control of heights and number of levels
// Check if height_roof is lower than height_wall. If yes, then correct height_roof
else if (heightWall > heightRoof) {
heightRoof = heightWall
if (nbLevels == 0) {
nbLevels = Math.max(Math.floor(heightWall / h_lev_min), 1)
}
} else if (heightRoof > heightWall) {
if (nbLevels == 0) {
nbLevels = Math.max(Math.floor(heightRoof / h_lev_min), 1)
}
}
return [heightWall: heightWall, heightRoof: heightRoof, nbLevels: nbLevels, estimated: estimated]

}


/**
* This utility method checks if a model exists
* - the model name must have the extension .model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ def saveToGeojson(def outputTable, def filePath, H2GIS h2gis_datasource, def out
*/
def saveToCSV(def outputTable, def filePath, def h2gis_datasource, def deleteOutputData) {
if (outputTable && h2gis_datasource.hasTable(outputTable)) {
h2gis_datasource.save("(SELECT ID_BUILD, ID_SOURCE FROM $outputTable WHERE estimated=true)", filePath, deleteOutputData)
h2gis_datasource.save("(SELECT ID_BUILD, ID_SOURCE FROM $outputTable)", filePath, deleteOutputData)
info "${outputTable} has been saved in ${filePath}."
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import groovy.json.JsonSlurper
import groovy.transform.BaseScript
import org.locationtech.jts.geom.Geometry
import org.locationtech.jts.geom.Polygon
import org.orbisgis.data.api.dataset.ISpatialTable
import org.orbisgis.data.jdbc.JdbcDataSource
import org.orbisgis.geoclimate.Geoindicators

import java.util.regex.Pattern

Expand All @@ -38,7 +38,6 @@ import java.util.regex.Pattern
* @param building The name of the raw buildings table in the DB
* @param zone an envelope to reduce the study area
* @param urban_areas used to improved the building type
* @param building The name of the raw buildings table in the DB
* @param hLevMin Minimum building level height
* @param jsonFilename Name of the json formatted file containing the filtering parameters
* @return outputTableName The name of the final buildings table
Expand All @@ -56,8 +55,7 @@ Map formatBuildingLayer(JdbcDataSource datasource, String building, String zone
DROP TABLE if exists ${outputEstimateTableName};
CREATE TABLE ${outputEstimateTableName} (
id_build INTEGER,
ID_SOURCE VARCHAR,
estimated boolean)
ID_SOURCE VARCHAR)
""".toString()

datasource """
Expand Down Expand Up @@ -101,7 +99,7 @@ Map formatBuildingLayer(JdbcDataSource datasource, String building, String zone
def heightRoof = getHeightRoof(height, heightPattern)
def heightWall = getHeightWall(heightRoof, roof_height)
def nbLevels = getNbLevels(b_lev, roof_lev)
def formatedHeight = formatHeightsAndNbLevels(heightWall, heightRoof, nbLevels, h_lev_min, type, typeAndLevel)
def formatedHeight = Geoindicators.WorkflowGeoIndicators.formatHeightsAndNbLevels(heightWall, heightRoof, nbLevels, h_lev_min, type, typeAndLevel)
def zIndex = getZIndex(row.'layer')
String roof_shape = row.'roof:shape'

Expand All @@ -125,13 +123,13 @@ Map formatBuildingLayer(JdbcDataSource datasource, String building, String zone
${roof_shape ? "'" + roof_shape + "'" : null})
""".toString()

stmt.addBatch """
if(formatedHeight.estimated) {
stmt.addBatch """
INSERT INTO ${outputEstimateTableName} values(
$id_build,
'${row.id}',
${formatedHeight.estimated})
'${row.id}')
""".toString()

}
id_build++
}
}
Expand Down Expand Up @@ -759,57 +757,6 @@ static float getHeightWall(height, r_height) {
return result
}

/**
* Rule to guarantee the height wall, height roof and number of levels values
* @param heightWall value
* @param heightRoof value
* @param nbLevels value
* @param h_lev_min value
* @return a map with the new values
*/
static Map formatHeightsAndNbLevels(def heightWall, def heightRoof, def nbLevels, def h_lev_min, def buildingType, def levelBuildingTypeMap) {
//Use the OSM values
if (heightWall != 0 && heightRoof != 0 && nbLevels != 0) {
return [heightWall: heightWall, heightRoof: heightRoof, nbLevels: nbLevels, estimated: false]
}
//Initialisation of heights and number of levels
// Update height_wall
boolean estimated = false
if (heightWall == 0) {
if (heightRoof == 0) {
if (nbLevels == 0) {
nbLevels = levelBuildingTypeMap[buildingType]
if (!nbLevels) {
nbLevels = 1
}
heightWall = h_lev_min * nbLevels
heightRoof = heightWall
estimated = true
} else {
heightWall = h_lev_min * nbLevels
heightRoof = heightWall
}
} else {
heightWall = heightRoof
nbLevels = Math.floor(heightWall / h_lev_min)
}
} else if (heightWall == heightRoof) {
if (nbLevels == 0) {
nbLevels = Math.floor(heightWall / h_lev_min)
}
}
// Control of heights and number of levels
// Check if height_roof is lower than height_wall. If yes, then correct height_roof
else if (heightWall > heightRoof) {
heightRoof = heightWall
if (nbLevels == 0) {
nbLevels = Math.floor(heightWall / h_lev_min)
}
}
return [heightWall: heightWall, heightRoof: heightRoof, nbLevels: nbLevels, estimated: estimated]
}


/**
* This function defines the value of the column height_roof according to the values of height and b_height
* @param row The row of the raw table to examine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,7 @@ def saveTablesInDatabase(JdbcDataSource output_datasource, JdbcDataSource h2gis_
} else {
output_datasource.execute """CREATE TABLE $output_table(ID_BUILD INTEGER, ID_SOURCE VARCHAR, ID_ZONE VARCHAR)""".toString()
}
IOMethods.exportToDataBase(h2gis_datasource.getConnection(), "(SELECT ID_BUILD, ID_SOURCE, '$id_zone' as ID_ZONE from $h2gis_table_to_save where estimated=true)".toString(),
IOMethods.exportToDataBase(h2gis_datasource.getConnection(), "(SELECT ID_BUILD, ID_SOURCE, '$id_zone' as ID_ZONE from $h2gis_table_to_save)".toString(),
output_datasource.getConnection(), output_table, 2, 100);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,18 +259,18 @@ class InputDataFormattingTest {
assertEquals 1038, h2GIS.getTable(buildingLayer).rowCount
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayer} where NB_LEV is null").count == 0
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayer} where NB_LEV<0").count == 0
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayer} where NB_LEV=0").count == 0
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayer} where HEIGHT_WALL is null").count == 0
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayer} where HEIGHT_WALL<0").count == 0
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayer} where HEIGHT_ROOF is null").count == 0
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayer} where HEIGHT_ROOF<0").count == 0
assertEquals 1038, h2GIS.getTable(buildingLayers.building_estimated).rowCount
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayers.building_estimated} where ESTIMATED = false").count == 4
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayers.building} join ${buildingLayers.building_estimated} using (id_build, id_source) where 1=1").count == 1038
assertEquals 1033, h2GIS.getTable(buildingLayers.building_estimated).rowCount
assertTrue h2GIS.firstRow("select count(*) as count from ${buildingLayers.building} join ${buildingLayers.building_estimated} using (id_build, id_source) where 1=1").count == 1033

//Buildings without estimation state
buildingLayers = OSM.InputDataFormatting.formatBuildingLayer(h2GIS, extractData.building)
assertEquals 1038, h2GIS.getTable(buildingLayers.building).rowCount
assertEquals 1038, h2GIS.getTable(buildingLayers.building_estimated).rowCount
assertEquals 1033, h2GIS.getTable(buildingLayers.building_estimated).rowCount
}


Expand Down
Loading

0 comments on commit 8d5254a

Please sign in to comment.