Skip to content

Latest commit

 

History

History
457 lines (350 loc) · 15.3 KB

File metadata and controls

457 lines (350 loc) · 15.3 KB

Coding doctrine

Geocontainer / Geolayer options

Options doctrine

Default values :

field_name_filter=None, bbox_extent=True, bbox_filter=None, serialize=False, feature_limit=None, feature_offset=None,

options list with concerned objects and keys

option name | obj concern | attribute | geometry |
-------------------- | ------------------ | --------- | --------- |
layer_id_or_name | geolayer | no matter | no matter |
field_name_filter | geolayer / feature | True | False |
geometry_type_filter | geolayer / feature | no matter | True |
bbox_extent | geolayer / feature | False | True |
bbox_filter | feature | False | True |
serialize | feature | both | both |
feature_limit | geolayer | no matter | no matter |
feature_offset | geolayer | no matter | no matter |
clean_data | geolayer / feature | True | False |

GEOMETRIES

When it is possible force geometries coordinates data like input is a Geometry Collection

variables

KEY format

a format key is always test in lower case and resitute in lowercase a geometry name must be agnostic. it is always tested in uppercase and is restitute in human readable string :

  • 'Point',
  • 'LineString',
  • 'Polygon',
  • 'MultiPoint',
  • 'MultiLineString',
  • 'MultiPolygon',
  • 'GeometryCollection'

DATA OR ATTRIBUTES

type | width | precision | index |

+===============+==========+===========+==========+ | 'Integer' | None | None | Optional | | 'IntegerList' | None | None | Optional | | 'Real' | Required | Required | Optional | | 'RealList' | Required | Required | Optional | | 'String' | Required | None | Optional | | 'StringList' | Required | None | Optional | | 'Binary' | None | None | Optional | | 'Date' | None | None | Optional | | 'Time' | None | None | Optional | | 'DateTime' | None | None | Optional | | 'Boolean' | None | None | Optional |

Driver geometry compatibility

[[0],[1], [2, 5], [3, 6], [4], [100]], # 'Esri Shapefile' [[1, 4], [2, 5], [3, 6], [100]], # TAB 'Mapinfo File' [[1, 4], [2, 5], [3, 6], [100]], # MIF/MID 'Mapinfo File' [[1, 2, 3, 4, 5, 6, 7, 100]], # KML [[1, 2, 3, 4, 5, 6, 7, 100]], # GML [[0, 1, 2, 3, 4, 5, 6, 7, 100]], # GeoJSON [[1], [2], [3, 6], [4], [5], [100]], # Geoconcept [[1], [2, 5], [3, 6], [4], [100]], # FileGDB [[1, 2, 3, 4, 5, 6, 7, 100]], # SQLite [[1, 2, 3, 4, 5, 6, 7, 100]], # POSTGRESQL [[1, 2, 3, 4, 5, 6, 7, 100]] # CSV

xxx_to_geolayer

variable csv esri shapefile geojson
path geolayer_name delimiter header null_string quote_character field_name_filter bbox_extent bbox_filter serialize geometry_type_filter feature_limit feature_offset force_field_conversion crs geometry field geometry_field_name geometry_format encoding
x x x x x
todo

x x x x x

x x x x x x

x

x x x x

x x x x

x

x

x x x x x x x x x

TODO add feature_limit and feature_offset to csv driver TODO add rename_field

geolayer_to_xxx

variable | csv | esri shapefile | geojson |
geolayer path overwrite add_extension driver_parameters indent delimiter header null_string quote_character write_geometry geometry_format geometry_field_name encoding

x x x x

x x x x x x x x

x x x x x

x x x x

x

TODO add rename_field

Contributor Guidelines

The code

Te code must be auto commented as much as possible

variables

Naming variable must general to specific. Example : you want a variable that store geolayer's name. Logicaly you have two possibilities : - name_geolayer - geolayer_name

Then the best practice if you want the name of field in a geolayer the variable name should be: geolayer_field_name because a geolayer contains field who have a name.

functions

naming : if the function name begin by "check" then the return is a boolean

Geoformat object

geolayer name

  • lower case
  • cannot begin by digit
  • can not contain '/' in name (to avoid to be consider as path)

outstanding issues

drop or delete ?

delete or drop ? when you want to supress something do we have to use delete or drop name ? maybe : - delete when you want to supress an object - drop when you want delete something in a object (a data inside an object that is not an object himself)

raise

how to andle with raise exception ? Must be restricve or not ? By example : if you want to drop/delete a field that not exists : do we return an Exception (because field name does not exists) ? undecided opinion : I think that we must be restrictive to avoid miscoding (except for boolean function, in case returning a False value would be considered as an error).

Quick Fix

  • split_geolayer_by_geometry_type -> output_geolayer use geometry_type_mapping value as geolayer name

dont take input geolayer name as prefix - rename point to vertex - bbox = True must become bbox = False. - print_metadata_field_table -> print field in order by index - create function geolayer_reorder_field (add in read me)

  • print metadata and feature without print usage in python script
    • print feature width representing field 6 because None value (1+4+1) (see id field bellow)
  • rename value_to_iterable_value to force_value_to_iterable_value
  • merge_feature (add rename auto like in merge_metadata) and check value in conformity with metadata. Update metadata to be field metadata and not only geolayer metadata in general.
  • add create create_field_in_feature (in feature_manipulation)
  • add / delete geometry (in feature_manipulation) if you add geolayer metadata it's verify integrity of geometry data
  • add / delete attributes (in feature_manipulation) if you add geolayer metadata it's verify integrity of attributes data
  • rethinking : single_geometry_to_multi_geometry especialy geometry collectoin where single must be grouped

Active Branch

TODO in master

allow functions with geometry in input to works with EMPTY geometries

clean typo in functions :
  • segment_intersects_segment

✔ segment_intersects_bbox

add_geojson_lib

✔ Add new homemade driver to read Geojson file ✔ Add new homemade driver to write Geojson file ✔ Redefine concept of Geolayer and Geocontainer

  • how options are articulated
  • write a documentation

✔ create generic function to create geometry on feature ✔ create generic function to create attribute on feature ✔ create generic function to create geolayer ✔ create generic function to create geocontainer ✔ compare with ogr function

add_posgresql_lib

https://hakibenita.com/fast-load-data-python-postgresql

Convex Hull

sources : https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain idea resolve by Quadtree: for each quad create a priority in function of priority according to its location

example of priority for Quad NW |---|---| | 0 | 1 | |---|–––| | 1 | 2 | |---|---|

example of priorty for Quad NE |---|---| | 1 | 0 | |---|–––| | 2 | 1 | |---|---|

example of priorty for Quad SE |---|---| | 2 | 1 | |---|–––| | 1 | 0 | |---|---|

example of priorty for Quad SW |---|---| | 1 | 2 | |---|–––| | 0 | 1 | |---|---|

example of cross sector 4 /

/ example of cross sector 8 |/ -*- /|

when vertex on priority 0 select him (forget the others in same quad):
if not
Select point in priority 1 (forget the others)
if not
Select priority 2 only adjacent quad (quad that share a frontier with priority 2 quad) have not priority 0 and priority 1 point)
compute cross sector for point #-- if there is neighbor quad with p0 or p1 #-- select point p0 or p1 by order of priorty and forget actual point and keep actual point

Distance

  • create function to calculate distance between (✔point / ✔segment / bbox)
  • allow to uses different distances types like (Euclidean, Manhattan, Minkowski, Tchebychev ...)
  • create generic function st_distance() between two geometries

Clauses

  • Generalise use to value_to_iterable_value and update it for this usage
  • Update clause where and add new tests
  • i_feat list transform to set (most compatible with combinations and intersections)

Simplify

  • optimize Visvalingam Whyatt :
    • do not calculate in a first loop all the areas of the triangles with coordinates.
    • Keep starting loop on reverse coordinate and adapt _recompute_idx_point_with_low_area in consequence (no need to

    recompute area for point before). - in _recompute_idx_point_with_low_area delete usage of .index search. - For perf-testing use script in /tests/perf/compare_func and try to make a generic function

Idea(s)

Driver

  • driver_to_geolayer -> make it possible to name a geolayer different from the name of the file from which it comes

Geoformat oriented objects

geocontainer

can be serialized (if True all geolayers contains in it are serialized) can contains none or more object in it

geolayer

can be serialized (if True all features contains in it are serialized) can contains none or more object in it

feature

can be serialized can contains one or more object in it :

  • geometry
  • attributes

Others ideas

  • offset limit in driver and print

  • recast_field_value :
    • we must full tested (with all types of data) this function
    • float to integer rounding ? do we have to keep python weird python rounding ?)
    • changing float precision : do we have to keep python weird python rounding ?)
  • generalize everywhere value_to_iterable_value but not in basical function only on functionnal function (functions that call basical function)

  • Refacto geolayer conversion :
    • recompute metadata when create_geolayer_from_i_feat_list is used ?
    • make generics function for options : feature serialize / geometry bbox filter / geometry X formating
  • in line_merge() function add as option : Precision for floatting number (must be added)
    • add precision to all function with coordinates
    • thinking globaly precision in coordinates
  • create a geolayer with a list of features [WIP in add_geojson_lib branch]

  • with Python 3.6 all dictonnary are ordered then "index" key in fields metadata is no need to be supported ?

  • create a geolayer with a list of features

  • review this feature clause_where_combination

  • add function in MAP_1635_2049 inside script.py

  • create new geolayer skeleton inspire from existing geolayer

  • add ogr layer in ogr_layer_to geolayer [KML / GML/ MAPINFO FILE / SQL LITE] [may be it's better to create our own driver ?]
    • test ogr driver (works in progress here : tests/geoformat/driver/ogr)
  • add translation and rotation geometry :
    def matrixRotation(x, y , angle):

    import numpy as np coordinate = np.matrix([[x],[y], [1]]) rotation = np.matrix([[math.cos(angle), math.sin(angle), 0], [-math.sin(angle), math.cos(angle), 0], [0, 0, 1]])

    result = rotation * coordinate

    return result.item(0), result.item(1)

    def matrixTranslation(x, y, transX, transY):

    import numpy as np coordinate = np.matrix([[x],[y], [1]]) translation = np.matrix([[1,0, transX],[0,1, transY],[0,0,1]])

    result = translation * coordinate

    return result.item(0), result.item(1)

create geolayer_to_geolayer function inspire from driver function but the aim is from a geolayer create a new geolayer with filter like : * geolayer_name=None, * field_name_filter=None, * geometry_type_filter=None, * bbox_extent=True, * bbox_filter=None, * serialize=False, * feature_limit=None, * feature_offset=None * force_field_conversion=False, * crs=None, * encoding="utf8"

Old active Branch

new_order_by_speedup

Testing branch for ordering a geolayer with a set of values

line_merge

Just merge when 2 points in extremity of lines are same (yes sir' exectp is it's a ring) Geometry collection [we force geometry to geometry collection at beggining) Warning when input geometry under linestring is a ring (she start and end at same point) [it's ok} Precision for floatting number (must be added) if linestring overlap ? [POSTGIS : do not do that, we do not too] WARNING line merge can reverse under geom order {not same order as postgis} what we do when geometry are duplicated in geometry ? [same as postgis]

grid_index_origin

Concern this functions :

To do : - ✔ transform parameter x_grid_origin and y_grid_origin to a simple point named grid_origin_point - ✔ allow to have an mesh size different for height and width (allow rectangular grid) and update process to compute automatically mesh size - ✔ update test - ✔ put all concerned functions in a separate module