diff --git a/bin/cmd/import.js b/bin/cmd/import.js index 571a456..4600327 100644 --- a/bin/cmd/import.js +++ b/bin/cmd/import.js @@ -49,6 +49,11 @@ module.exports = { coerce: parseFloat, describe: 'simplification tolerance for geometry module' }) + yargs.option('tweak_module_geometry_repair', { + type: 'number', + default: 0, + describe: 'repair method for geometry module (0=none, 1=MakeValid, 2=GeosMakeValid)' + }) yargs.option('tweak_module_shard_simplify', { type: 'number', default: 0.00003, @@ -81,7 +86,8 @@ module.exports = { verbose: argv.verbose, module: { geometry: { - simplify: argv.tweak_module_geometry_simplify + simplify: argv.tweak_module_geometry_simplify, + repair: argv.tweak_module_geometry_repair }, shard: { simplify: argv.tweak_module_shard_simplify, diff --git a/module/geometry/StatementInsert.js b/module/geometry/StatementInsert.js index 17072d3..dad7b40 100644 --- a/module/geometry/StatementInsert.js +++ b/module/geometry/StatementInsert.js @@ -4,37 +4,37 @@ const SqliteStatement = require('../../sqlite/SqliteStatement') class StatementInsert extends SqliteStatement { create (db, config) { try { - let dbname = _.get(config, 'database', 'main') - let simplify = _.get(config, 'module.geometry.simplify', 0.0) + const dbname = _.get(config, 'database', 'main') + const simplify = _.get(config, 'module.geometry.simplify', 0.0) + const repair = _.get(config, 'module.geometry.repair', 0) + + // parse WKB + let sql = 'GeomFromWKB( @geom, 4326 )' + + // optionally repair broken geometries + if (repair === 1) { + sql = `MakeValid( ${sql} )` + } else if (repair === 2) { + sql = `GeosMakeValid( ${sql} )` + } + + // optionally simplify geometries if (simplify > 0.0) { - this.statement = db.prepare(` - INSERT OR REPLACE INTO ${dbname}.geometry ( - source, - id, - role, - geom - ) VALUES ( - @source, - @id, - @role, - SimplifyPreserveTopology( GeomFromWKB( @geom, 4326 ), ${simplify} ) - ) - `) - } else { - this.statement = db.prepare(` - INSERT OR REPLACE INTO ${dbname}.geometry ( - source, - id, - role, - geom - ) VALUES ( - @source, - @id, - @role, - GeomFromWKB( @geom, 4326 ) - ) - `) + sql = `SimplifyPreserveTopology( ${sql}, ${simplify} )` } + + this.statement = db.prepare(` + INSERT OR REPLACE INTO ${dbname}.geometry ( + source, + id, + role, + geom + ) VALUES ( + @source, + @id, + @role, + ${sql} + )`) } catch (e) { this.error('PREPARE STATEMENT', e) } diff --git a/module/geometry/StatementInsert.test.js b/module/geometry/StatementInsert.test.js index 89e0140..4659d15 100644 --- a/module/geometry/StatementInsert.test.js +++ b/module/geometry/StatementInsert.test.js @@ -46,3 +46,78 @@ tap.test('create & drop', (t) => { t.end() }) + +tap.test('query config', (t) => { + const db = common.tempSpatialDatabase() + new TableGeometry().create(db) + new GeoColumnGeom().create(db) + + const stmts = { + default: new StatementInsert(), + simplify: new StatementInsert(), + repair: new StatementInsert(), + simplifyAndRepair: new StatementInsert() + } + + // no config specified + stmts.default.create(db) + t.equal(stmts.default.statement.source, ` + INSERT OR REPLACE INTO main.geometry ( + source, + id, + role, + geom + ) VALUES ( + @source, + @id, + @role, + GeomFromWKB( @geom, 4326 ) + )`) + + // repair only + stmts.repair.create(db, { module: { geometry: { repair: 1 } } }) + t.equal(stmts.repair.statement.source, ` + INSERT OR REPLACE INTO main.geometry ( + source, + id, + role, + geom + ) VALUES ( + @source, + @id, + @role, + MakeValid( GeomFromWKB( @geom, 4326 ) ) + )`) + + // simplify only + stmts.simplify.create(db, { module: { geometry: { simplify: 0.001 } } }) + t.equal(stmts.simplify.statement.source, ` + INSERT OR REPLACE INTO main.geometry ( + source, + id, + role, + geom + ) VALUES ( + @source, + @id, + @role, + SimplifyPreserveTopology( GeomFromWKB( @geom, 4326 ), 0.001 ) + )`) + + // simplify + repair + stmts.simplifyAndRepair.create(db, { module: { geometry: { simplify: 0.001, repair: 2 } } }) + t.equal(stmts.simplifyAndRepair.statement.source, ` + INSERT OR REPLACE INTO main.geometry ( + source, + id, + role, + geom + ) VALUES ( + @source, + @id, + @role, + SimplifyPreserveTopology( GeosMakeValid( GeomFromWKB( @geom, 4326 ) ), 0.001 ) + )`) + + t.end() +})