Git Product home page Git Product logo

orbisdata's Introduction

ALERT

After several years of development, it is time to reorganize the OrbisGIS architecture to offer to the users and the developers a robust libraries and framework, a better documentation and a more user-friendly GUI. Because the OrbisGIS team is at the heart of open source communities, because it supports collective work and the sharing of tools and methods rather than reinventing the wheel, we have decided to split OrbisGIS in a two main libraries :

These libraries take profit of the FOSS ecosystem and the next OrbisGIS user interface will be developped on top of the Eclipse RCP framework and the dbeaver tool. Many dbeaver features are in line with the needs of the OrbisGIS users and its functions (SQL editor, tree database explorer, table viewer...). We are therefore thinking of adding OrbisGIS features to dbeaver and use it in replacement to the current OrbisGIS (based on DockingFrames). OrbisRCP aggregates all OrbisGIS plugins available for DBeaver. See : https://github.com/orbisgis/orbisrcp

Note that the H2GIS extension and the CTS library are still being actively developed by the OrbisGIS team.

OrbisGIS Build Status

OrbisGIS is a cross-platform open-source Geographic Information System (GIS) created by research and for research. It is leaded by CNRS within the French Lab-STICC laboratory (DECIDE team of Vannes) and licensed under GPLv3. OrbisGIS proposes new methods and techniques to model, represent, process and share spatial data, making it easy to monitor geographical territories and manage their evolution. In a world ever-increasingly aware of its ecological footprint and the relevance of sustainable development, a systematic approach to evaluating public policies is of paramount importance. Such an approach must take into account relevant environmental, social and economic factors to facilitate efficient decision making and planning. As an integrated modeling platform containing analytical tools for computing various indicators at different spatial and temporal scales, OrbisGIS is already an indispensable instrument for many. Come see what all the buzz is about!

For general information, visit our website. Feel free to contact us or use the mailing list.

Developers, check out our GitHub Wiki.

Users, please consult the on-line documentation on doc.orbisgis.org.

Quick build instructions

OrbisGIS uses Maven. To launch a full build (including the tests), run the following command:

$ mvn clean install

To run OrbisGIS using Maven:

$ cd orbisgis-dist
$ mvn exec:exec

To build a release as a standalone zip file:

cd orbisgis-dist
mvn package assembly:single

orbisdata's People

Contributors

ebocher avatar spalominos avatar vquillien avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

orbisdata's Issues

Array as input process

@test
void testArrayInput(){
def process = processFactory.create(
"title",
[inputA : ['st_area', 'st_type', 'st_perimeter']],
[outputA : String],
{ inputA ->[outputA : inputA[0]+'the_geom) as area']}
)
}

@j3r3m1

Groovy console

Add a module which provides a Groovy console preloading the classes H2GIS, POSTGIS, ProcessFactory

ProcessManager

The idea is to add a process manager to manager several process factories, register, delete a process.

Use cases

ProcessManager pm = new ProcessManager()

ps.getFactory("idOfTheFactory") -> Return a factory
ps.getFactory() -> Return the default factory

a factory can be protected so it's not possible to remove or delete a process.

ps.factories() -> List the factory ids

OrbisProcess trouble

@ebocher @SPalominos
I have started to code indicators using the OrbisProcess syntax and I am currently facing several problems (you can find the entire code at the end of the message):

  1. I code in the Groovy console within the OrbisGIS plat-form and when I run my code, the script is executed but nothing is actually performed. I have tried to print random words at the beginning of the script and they appear only if I remove the following lines:
    import org.orbisgis.datamanager.h2gis.H2GIS

  2. I do not know what is the expected method to use SQL queries within the OrbisProcess. I have tried two different versions (in "process1" I recover the database from the input ITable whereas in "process2" I pass the database and the Table name as inputs. What do you think would be the best solution ?

// The OrbisData library is imported
@GrabResolver(name='orbisgis', root='http://repo.orbisgis.org/')
@Grab(group='org.orbisgis', module='data-manager', version='1.0-SNAPSHOT')

// The H2Gis module is also imported
import org.orbisgis.datamanager.h2gis.H2GIS



// Create the tables needed to test the functions
def h2GIS = H2GIS.open([databaseName: './target/loadH2GIS'])
h2GIS.execute("""
     DROP TABLE IF EXISTS building_test;
     DROP TABLE IF EXISTS rsu_test;
     CREATE TABLE building_test (id_build int, the_geom geometry, height_wall float, height_roof float);
     CREATE TABLE rsu_test (id_rsu int, the_geom geometry);
     INSERT INTO building_test VALUES (1, 'POLYGON((4 4, 10 4, 10 30, 4 30, 4 4))'::GEOMETRY, 8), (2, 'POLYGON((12 4, 20 4, 20 9, 12 9, 12 4))'::GEOMETRY, 10), (3, 'POLYGON((25 4, 45 4, 45 9, 25 9, 25 4))'::GEOMETRY, 8), (4, 'POLYGON((25 25, 40 25, 40 37, 25 37, 25 25))'::GEOMETRY, 5), (5, 'POLYGON((12 25, 25 25, 25 35, 12 35, 12 25))'::GEOMETRY, 12), (6, 'POLYGON((52 2, 54 2, 54 10, 52 10, 52 2))'::GEOMETRY, 15);
     INSERT INTO rsu_test VALUES (1, 'POLYGON((0 0, 50 0, 50 40, 0 40, 0 0))'::GEOMETRY), (2, 'POLYGON((50 0, 55 0, 55 30, 50 30, 50 0))'::GEOMETRY);
""")

def process1 = processFactory.create(
      "Building area without SQL passed",
      [inputA: ITable, inputB: String, inputC: String, inputD: String],
      [outputA : ITable],
      { inputA, inputB, inputC, inputD -> 
      // Recover the DataBase where is located the inputA Table
      sql = inputA.getDataBase()
      // Recover the name of the input Table in order to be used in the SQL queries
      inputA_name = inputA.getTableName()    // Note that I have not found any function to get the Table name...
      // Calculate the value of the indicator and store it in a new Table
      sql.execute("create table $inputB as select $inputD, st_area($inputD) as $inputC from $inputA_name")
      [outputA : sql.getSpatialTable("$inputA_name")] }
)

process1.execute([inputA: h2GIS.getSpatialTable("building_test"), inputB: "building_area", inputC: "building_area", inputD: "the_geom"])

def process2 = processFactory.create(
      "Building area with SQL passed",
      [inputA: String, inputB: String, inputC: String, inputD: String, inputE: Database],
      [outputA : ITable],
      { inputA, inputB, inputC, inputD, inputE -> 
      // Calculate the value of the indicator and store it in a new Table
      inputE.execute("create table $inputB as select $inputD, st_area($inputD) as $inputC from $inputA")
      [outputA : inputE.getSpatialTable("$inputB")] }
)

process2.execute([inputA: "building_test", inputB: "building_area", inputC: "building_area", inputD: "the_geom", inputE: h2GIS])

Groovy console

Provide a customized groovy console that pre-load the OrbisData libraries.
It can be used to execute Geoclimate scripts.

Add a module which provides a Groovy console preloading the classes H2GIS, POSTGIS, ProcessFactory

Orbisprocess

I share here some examples about orbisprocess library. A library to write process based on orbiswps job and the famous geoscript library.

//Declare
Process p = new Process([inputA: String],[outputA: String], { inputA ->
          [outputA: inputA.trim]
         }
         )
//Execute
 p.execute([inputA : 'OrbisGIS is nice'])

Note that the input and output parameters must be controlled.

The method expression

This method is recursive on the type Function. It separate the different type of expression : Function, ValueReference, Literal and Object.

For the type object, there are problems because there aren't any solution to know the structure of the type.
The only solution was that we add a condition for each type that we can find. Example: the GML.

Custom ascii print

What do you think if we add a short syntax to print values, something as

datasource.getTable("sylvain") as out

will print

+-----------+
| gamer |
+-----------+
| one |
| two |
| three |
+-----------+

the same for

datasource.getTable("sylvain").columnNames as out

Default value trouble: order

The default value is now taken into account (#93). However, I got a problem in the following example:

public static IProcess computeRSUIndicators() {
    return processFactory.create("Compute the geoindicators at block scale",
            [datasource                 : JdbcDataSource, buildingTable              : String,
             rsuTable                   : String,         prefixName                 : "rsu_indicators"],
[output: String],
{datasource, buildingTable, prefixName, rsuTable}
...

The prefixName and rsuTable are inverted in the closure and the default prefixName value is assigned to rsuTable. Is it a normal behaviour ? Then I have to verify that the inputs are in the same order in the declaration and in the closure ?

H2GIS and POSTGIS open signatures

To H2GIS add open(String path), open(String path, String user, String password)
To POSTGIS add open(String path, String user, String password)
And replace open(String fileName) by open(File fileName)

Usefull methods

  • SpatialTable.extend() -> Return the full extend of the spatial table
  • SpatialTable.estimatedExtend() -> Return the estimated extend
  • SpatialTable.srid() -> Return the srid code of the spatial table
  • SpatialTable.columns() -> Returns all column informations

Seee SFSUtilities.java in H2GIS

In/Output configuration

Add a new way to declare the process in/outputs in order to set additional information (WPS style) like the minOccurs, description, keywords ...

The syntax will look like :

.create("Process title",
    [inputA : String, 
        inputB : Literal.String.description("input description").minOccurs(0).maxOccurs(42)]
        inputB : Complex.JdbcTable.description("input description").minOccurs(0).maxOccurs(42)]
    ...
)

Column on empty table

@test
void testColumnEmptyRow() {
def h2GIS = H2GIS.open([databaseName: './target/loadH2GIS'])
h2GIS.execute(""" DROP TABLE IF EXISTS h2gis;
CREATE TABLE h2gis (id int, the_geom geometry(point));""")
assertTrue(h2GIS.getSpatialTable("h2gis")."THE_GEOM")
assertTrue(h2GIS.getSpatialTable("h2gis").the_geom)
}

return MissingProperty No such property: THE_GEOM

must return a JDBCColumn

H2Network dependency

Add

        <dependency>
            <groupId>org.orbisgis</groupId>
            <artifactId>h2gis-network</artifactId>
        </dependency>

as a dependency to OrbisData

getSpatialTable getTable extend get methods ?

In order to filter the columns (as for the SQL DSL builder), I propose to add two new methods on IJdbcDataSource interface

ISpatialTable getSpatialTable(String tableName, String... fields);

ITable getTable(String tableName, String... fields);

Log process name

It would be nice if we could automatically log the name of the process that is executed

GroovyObject methods and missingMethod constistance

Each class should have the same behaviour for the GroovyObject methods and missingMethod :

//getters
obj.getValue()
obj.value()
obj.value
//setters
obj.setValue("toto")
obj.value("toto")
obj.value = "toto"

Process result

In order to simplify the acces of process results, add the syntax simplification process.resultName like :

process.getResults().output -> process.output

Default value not taken into account

In IProcesses, how should we deal with default values ?
For example, in geoclimate, I have the following function :

/**
 * This process is used to merge the geometries that touch each other
 *
 * @param datasource A connexion to a database (H2GIS, PostGIS, ...) where are stored the input Table and in which
 * the resulting database will be stored
 * @param inputTableName The input table tos create the block (group of geometries)
 * @param distance A distance to group the geometries
 * @param prefixName A prefix used to name the output table
 * @param outputTableName The name of the output table
 * @return A database table name and the name of the column ID
 */
static IProcess createBlocks(){
    return processFactory.create("Merge the geometries that touch each other",
            [inputTableName: String, distance : double, prefixName: String, datasource: JdbcDataSource],
            [outputTableName : String, outputIdBlock: String],
            { inputTableName,distance =0.0, prefixName="block", datasource ->
                logger.info("Merging the geometries...")

                def columnIdName = "id_block"

                // The name of the outputTableName is constructed
                String baseName = "created_blocks"
                String outputTableName = prefixName + "_" + baseName

                datasource.execute "DROP TABLE IF EXISTS $outputTableName".toString()
                datasource.execute "CREATE TABLE $outputTableName as select EXPLOD_ID as $columnIdName, the_geom ".toString()+
                        "from st_explode ('(select ST_UNION(ST_ACCUM(ST_BUFFER(THE_GEOM,$distance))) as the_geom".toString()+
                        " from $inputTableName)')".toString()
                logger.info("The geometries have been merged")
                [outputTableName: outputTableName, outputIdBlock: columnIdName]
            }
    )
}

When I call it, I would use the default value of distance. If I set it to null or if I do not declare it, it set the distance to null instead of my default value.

    @Test
    void createBlocksTest() {
        def h2GIS = H2GIS.open([databaseName: '/tmp/spatialunitsdb'])
        String sqlString = new File(this.class.getResource("data_for_tests.sql").toURI()).text
        h2GIS.execute(sqlString)
        h2GIS.execute("drop table if exists build_tempo; " +
                "create table build_tempo as select * from building_test where id_build <27")
        def  blockP =  Geoclimate.SpatialUnits.createBlocks()
        blockP.execute([inputTableName: "build_tempo",distance:null,
                     prefixName: "block", datasource: h2GIS])
        String outputTable = blockP.results.outputTableName
        def countRows =  h2GIS.firstRow("select count(*) as numberOfRows from $outputTable".toString())
        assertEquals 12 , countRows.numberOfRows
    }

Access ResultSetMetaData [GROOVY]

Proposals :

h2gis.getSpatialTable("buildings").row{ meta ->
    meta.tableName == 'buildings'
   meta.columnCount 
   meta.srid //Return the SRID of the table
 
    //First one
    meta.getColumnLabel(1)
    meta.getColumnName(1)
    meta.getColumnTypeName(1) 
    //All
    meta*.columnName
    //Filtering names
    metaData.any{ it.columnName.contains('geom') }
})

or

h2gis.getSpatialTable("buildings").columnNames
//-> related to println sql.firstRow('select * from buildings').keySet()

Creation of an object JaxB Sort By from a Xml file

I created a class SqlToFes. This class has a public stactic method which takes a String and return an JaxB Object (Filter or Sort By).

But for the parameter String from the method, I don't know his structure at beginnig :
SELECT FROM WHERE ORDER BY (full request) or only the line of the WHERE (or the ORDER BY).

Cookbook

Write a cookbook/documentation for the usage of orbisdata.

Add check before/after process execution on mappers.

Add test before and after the process execution inside a mapper with a syntax like :

mapper.before(pA).with(pA.inA1).check({inA1 -> inA1 == "t"}).stopOnFail("Message")
mapper.after(pA).with(pA.outA1).check({outA1 -> outA1 == "tutu"}).continueOnFail("Message").stopOnSuccess(Message)

Consistant syntax

The syntax in orbisdata is not always the same. Sometimes we use syntax like :

fct(A, B, C, D)

and other times we use :

obj.a(A).b(B).c(C).d(D)

We should be consistant.

Remove deprecated

Remove deprecated annotation before release :

  • ProcessFactory.class

Import and Export methods

Add on IJdbcDataSource interface two methods import and export.

Signatures

IJdbcDataSource.import('/tmp/file.shp');
IJdbcDataSource.import('/tmp/file.shp', 'tableName');
IJdbcDataSource.import('/tmp/file.shp', 'tableName', 'encoding', 'delete');

IJdbcDataSource.export('/tmp/file.shp', 'tableName');
IJdbcDataSource.export('/tmp/file.shp', 'tableName', 'encoding');

Improve getColumnNames

println(h2GIS.getSpatialTable("parcelle").columnNames)
-> Takes 2 s

println((h2GIS.getSpatialTable("parcelle").limit(0) as ITable).columnNames)

-> Takes 8 ms

So it could be nice to add a workaround to accelerate the getColumnNames

Index creation

I have tried the commands you have proposed to create indexes on spatial tables and I got the following error message:
'No such property: the_geom for class: org.orbisgis.datamanager.h2gis.H2gisSpatialTable'

Here is what I have executed:

H2gisSpatialTable rsuSpatialTable = datasource.getSpatialTable(rsuTable)
if(!(rsuSpatialTable[geometricColumnRsu].spatialIndexed)){
    rsuSpatialTable[geometricColumnRsu].createSpatialIndex()

Note that it is the same problem if I write rsuSpatialTable.the_geom and that I have performed a mvn clean install in a new terminal outside IntelliJ.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.