Skip to content

Commit

Permalink
1.0 Release with latest GDAL3 bindings (#73)
Browse files Browse the repository at this point in the history
* break everything

1. stop removing prefixes from GDAL function names, thereby overloading them
2. removes the C submodule, everything is not together in the main module

I realize the function renaming is quite breaking. In the README.md I wrote
a bit about the changes and how to update code with the [renamer](https://gist.github.com/visr/0a2ad3fe92073345c93c2ca42f5f58a0#file-renamer-jl).

Before we had many methods of (for instance) destroy. We used multiple dispatch to select the right C function if you called GDAL.destroy(x),
depending on the type of x:

```json
"destroy": [
        "gdaldestroy",
        "gdal_cg_destroy",
        "ogr_fld_destroy",
        "ogr_gfld_destroy",
        "ogr_fd_destroy",
        "ogr_f_destroy",
        "ogr_ds_destroy",
        "ogr_sm_destroy",
        "ogr_st_destroy",
        "ogr_stbl_destroy"
    ]
```

This only worked because we rewrote the wrapping code, to pretend that `Ptr{Cvoid}` was actually `Ptr{OGRFeatureH}`, where `OGRFeatureH` was an abstract type
we put in https://github.com/JuliaGeo/GDAL.jl/blob/b75ac1c3a351ac934e35827289a0d522a1fa7005/src/types.jl. While it was nice to use dispatch here,
it did not match well with the C API. Firstly, it meant that wrapping became a complicated puzzle which did not neccesarily work. In `types.jl` we used
subtyping to simulate that some functions could take different types of inputs. Now it is up to the user to select the right function. The functions
will accept everything that can be converted to the types that C expects. This is in line with the new default Clang.jl behavior. This more straightforward
wrapping of the GDAL C API is a better fit for this package, allowing others such as ArchGDAL.jl to try to make it more Julian.

Regarding the C submodule, since we now do less rewriting, there is no strong reason anymore to keep them separate, folding them together.

* address review comments

* add link to renamer.jl

* EzXML fix deprecation warning

* Set release to 1.0.0
  • Loading branch information
visr committed Aug 22, 2019
1 parent b75ac1c commit 9beaa4e
Show file tree
Hide file tree
Showing 42 changed files with 4,975 additions and 19,690 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/deps/deps_*.jl
/deps/build.log
/deps/usr
/gen/C
/gen/doxygen.xml
*.jl.cov
*.jl.*.cov
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ uuid = "add2ef01-049f-52c4-9ee2-e494f65e021a"
keywords = ["GDAL", "IO"]
license = "MIT"
desc = "Wrapper for GDAL - Geospatial Data Abstraction Library"
version = "0.3.0"
version = "1.0.0"

[deps]
BinaryProvider = "b99e7846-7c00-51b0-8f62-c81ae34c0232"
Expand Down
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![Build status](https://ci.appveyor.com/api/projects/status/github/JuliaGeo/GDAL.jl?svg=true&branch=master)](https://ci.appveyor.com/project/JuliaGeo/gdal-jl/branch/master)

Julia wrapper for [GDAL - Geospatial Data Abstraction Library](http://gdal.org/).
This package is a binding to the C API of GDAL/OGR. It provides only a C style usage, where resources must be closed manually, and datasets are pointers. *Note: this also means that before being able to use any drivers (for input/output of different formats), they must be registered first using `GDAL.allregister()`.*
This package is a binding to the C API of GDAL/OGR. It provides only a C style usage, where resources must be closed manually, and datasets are pointers. *Note: this also means that before being able to use any drivers (for input/output of different formats), they must be registered first using `GDAL.gdalallregister()`.*

Other packages can build on top of this to provide a more Julian user experience. See for example [ArchGDAL.jl](https://github.com/yeesian/ArchGDAL.jl).

Expand All @@ -22,29 +22,31 @@ Docstrings are automatically inserted from the GDAL documentation. Note that the
```
julia> using GDAL
help?> GDAL.creategeometry
help?> GDAL.ogr_g_creategeometry
OGR_G_CreateGeometry(OGRwkbGeometryType eGeometryType) -> OGRGeometryH
Create an empty geometry of desired type.
Parameters
––––––––––––
Parameters
––––––––––––
• eGeometryType: the type code of the geometry to be created.
eGeometryType: the type code of the geometry to be created.
Returns
–––––––––
Returns
–––––––––
handle to the newly create geometry or NULL on failure. Should be freed with
OGR_G_DestroyGeometry() after use.
handle to the newly create geometry or NULL on failure. Should be freed with OGRGDestroyGeometry() after use.
```

Further usage documentation is not yet available, but the files `test/tutorial_raster.jl` and `test/tutorial_vector.jl` should provide a good hint based on the API tutorials from [GDAL.org](http://gdal.org/).

The bulk of this package is generated automatically by the scripts under `gen/`. For developer documentation regarding this process see `gen/README.md`.

## Low-level and mid-level API
Next to the functions available in the `GDAL` module, there is also a submodule `GDAL.C` available. `GDAL.C` is the low-level wrapping, without any error checking, function renaming or type wrapping. If you know what you are doing and don't want this package to get in your way, use this. Currently the `GDAL.C` module provides a more complete wrapping, though the intention is to make the complete user facing C API available in both modules.
## Changelog

Since GDAL.jl v0.2.0 the package has changed considerably. The GDAL C function names are no longer being shortened. This brought many complications forcing us to simulate GDAL's types to disambiguate methods. As an example, the old `GDAL.open` now has to be made explicit: use `GDAL.gdalopen`, `ogr_dr_open`, or `ogropen`. Other options are simpler, `GDAL.allregister` can only become `GDAL.gdalallregister`. To help with updating old code in a semi automatic fashion, look at [this script](https://gist.github.com/visr/0a2ad3fe92073345c93c2ca42f5f58a0#file-renamer-jl) which uses [MacroTools.jl](https://mikeinnes.github.io/MacroTools.jl/stable/sourcewalk/) to do function renaming.

The `GDAL.C` submodule no longer exists. All functions that were there and not in the main `GDAL` module, have now been moved over.

## Troubleshooting

Expand All @@ -56,7 +58,7 @@ GDALError (CE_Failure, code 6):
The SQLite driver needs to be compiled to support the SQLite SQL dialect
```

This means that the GDAL binaries you are using, which normally come from the [GDALBuilder](https://github.com/JuliaGeo/GDALBuilder), are not compiled with support for the format or feature you need. GDAL is a large library with many optional dependencies which allow support for more formats. Currently the amount of formats supported is still limited, but will grow over time. Lists of available formats can be found [here](http://www.gdal.org/formats_list.html) for rasters and [here](http://www.gdal.org/ogr_formats.html) for vectors. If you need support for another format, consider making an issue or PR at the GDALBuilder repository. Many formats need external libraries as added dependencies. This means a BinaryBuilder repository also needs to be available for that library, and added as a dependency.
This means that the GDAL binaries you are using, which normally come from the [GDALBuilder](https://github.com/JuliaGeo/GDALBuilder), are not compiled with support for the format or feature you need. GDAL is a large library with many optional dependencies which allow support for more formats. Currently the amount of formats supported is still limited, but will grow over time. Lists of available formats can be found [here](https://gdal.org/drivers/raster/index.html) for rasters and [here](https://gdal.org/drivers/vector/index.html) for vectors. If you need support for another format, consider making an issue or PR at the GDALBuilder repository. Many formats need external libraries as added dependencies. This means a BinaryBuilder repository also needs to be available for that library, and added as a dependency.

### Using the GDAL and OGR utilities

Expand Down
4 changes: 2 additions & 2 deletions gen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ Below are the steps needed to create an XML file from which the documentation is
3. Copy the result to `GDAL.jl/gen/doxygen.xml`

### Run the wrapping scripts
1. Run `julia gen/wrap_gdal.jl` to generate the low level wrapping (GDAL + documentation)
2. Run `julia gen/rewriter.jl` to generate the higher level wrapping from the low level wrapping (GDAL + documentation)
1. Run `julia gen/wrap.jl` to generate the wrapping (GDAL + documentation). If you get `UndefVarError` from `common.jl`, empty the file and retry.
2. Run `julia gen/wrap.jl` again.
72 changes: 69 additions & 3 deletions gen/doc.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# this file is included by wrap_gdal.jl and rewriter.jl
# and provides several shared functions for building docstrings
# this file is included by wrap.jl and provides several functions for building docstrings

"Build docstring for a function from a Doxygen XML node"
function build_function(node::EzXML.Node)
Expand All @@ -8,7 +7,7 @@ function build_function(node::EzXML.Node)
# code block with function definition
print(io, " ", text(node, "name"), "(")
nspace = position(io)
params = findall(node, "param")
params = findall("param", node)
if isempty(params)
print(io, ")")
end
Expand Down Expand Up @@ -72,7 +71,74 @@ function build_docstring(node::EzXML.Node)
end
end

"Return the text of a subelement `el` of `node`"
function text(node::EzXML.Node, el::AbstractString)
s = findfirst(el, node)
s === nothing ? "" : strip(nodecontent(s))
end

"Wrap the single- or multi-line docstring in appropriate quotes"
function addquotes(docstr::AbstractString)
if '\n' in docstr
string("\"\"\"\n", docstr, "\"\"\"")
else
# single line docstring
repr(rstrip(docstr, '.'))
end
end

"Get the C name out of a expression"
function cname(ex)
if @capture(ex, function f_(args__) ccall((a_, b_), xs__) end)
String(eval(a))
else
# TODO make MacroTools.namify work for structs and macros
if MacroTools.isexpr(ex) && ex.head === :struct
String(ex.args[2])
elseif MacroTools.isexpr(ex) && ex.head === :macrocall
# if the enum has a type specified
String(ex.args[3].args[1])
else
String(namify(ex))
end
end
end

"Based on a name, find the best XML node to generate docs from"
function findnode(name::String, doc::EzXML.Document)
# Names are not unique. We know that kind='friend' (not sure what it is)
# does not give good docs and is never the only one, so we skip those.
# First we use XPath to find all nodes with this name and not kind='friend'.
memberdef = "/doxygen/compounddef/sectiondef/memberdef"
nofriend = "not(@kind='friend')" # :-(
nodes = findall("$memberdef[name='$name' and $nofriend]", doc)

if length(nodes) == 0
return nothing
elseif length(nodes) == 1
return first(nodes)
else
# If we get multiple nodes back, we have to select the best one.
# Looking at the documentation, sometimes there are two similar docstrings,
# but one comes from a .cpp file, as seen in location's file attribute,
# and the other comes from a .h file (.c is the third option).
# Even though this is a C binding, the .cpp node includes the argument names
# which makes for an easier to read docstring, since they can be referenced
# to the argument names in the parameters list.
# Therefore if .cpp is one of the options, go for that.

# ExXML uses libxml2 which only supports XPath 1.0, meaning
# ends-with(@file,'.cpp') is not available, but according to
# https://stackoverflow.com/a/11857166/2875964 we can rewrite this as
cpp = "'.cpp' = substring(@file, string-length(@file) - string-length('.cpp') +1)"

for node in nodes
cppnode = findfirst("location[$cpp]/..", node)
if cppnode !== nothing
return cppnode
end
end
# .cpp not present, just pick the first
return first(nodes)
end
end
Loading

0 comments on commit 9beaa4e

Please sign in to comment.