1 /* 2 geojson.h -- Gaia common support for the GeoJSON parser 3 4 version 5.0, 2020 August 1 5 6 Author: Sandro Furieri a.furieri@lqt.it 7 8 ------------------------------------------------------------------------------ 9 10 Version: MPL 1.1/GPL 2.0/LGPL 2.1 11 12 The contents of this file are subject to the Mozilla Public License Version 13 1.1 (the "License"); you may not use this file except in compliance with 14 the License. You may obtain a copy of the License at 15 http://www.mozilla.org/MPL/ 16 17 Software distributed under the License is distributed on an "AS IS" basis, 18 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 19 for the specific language governing rights and limitations under the 20 License. 21 22 The Original Code is the SpatiaLite library 23 24 The Initial Developer of the Original Code is Alessandro Furieri 25 26 Portions created by the Initial Developer are Copyright (C) 2018-2021 27 the Initial Developer. All Rights Reserved. 28 29 Contributor(s): 30 31 32 Alternatively, the contents of this file may be used under the terms of 33 either the GNU General Public License Version 2 or later (the "GPL"), or 34 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 35 in which case the provisions of the GPL or the LGPL are applicable instead 36 of those above. If you wish to allow use of your version of this file only 37 under the terms of either the GPL or the LGPL, and not to allow others to 38 use your version of this file under the terms of the MPL, indicate your 39 decision by deleting the provisions above and replace them with the notice 40 and other provisions required by the GPL or the LGPL. If you do not delete 41 the provisions above, a recipient may use your version of this file under 42 the terms of any one of the MPL, the GPL or the LGPL. 43 44 */ 45 46 47 /** 48 \file geojson.h 49 50 GeoJSON structures 51 */ 52 53 #ifndef _GEOJSON_H 54 #ifndef DOXYGEN_SHOULD_SKIP_THIS 55 #define _GEOJSON_H 56 #endif 57 58 #ifdef __cplusplus 59 extern "C" 60 { 61 #endif 62 63 /* constant values for GeoJSON objects */ 64 65 /** UNKNOWN */ 66 #define GEOJSON_UNKNOWN 0 67 68 /** FeatureCollection object */ 69 #define GEOJSON_FCOLLECTION 101 70 71 /** Feature object */ 72 #define GEOJSON_FEATURE 102 73 74 /** Properties object */ 75 #define GEOJSON_PROPERTIES 103 76 77 78 /* constant values for GeoJSON geometries */ 79 80 /** POINT */ 81 #define GEOJSON_POINT 201 82 83 /** LINESTRING */ 84 #define GEOJSON_LINESTRING 202 85 86 /** POLYGON */ 87 #define GEOJSON_POLYGON 203 88 89 /** MULTIPOINT */ 90 #define GEOJSON_MULTIPOINT 204 91 92 /** MULTILINESTRING */ 93 #define GEOJSON_MULTILINESTRING 205 94 95 /** MULTIPOLYGON */ 96 #define GEOJSON_MULTIPOLYGON 206 97 98 /** GEOMETRYCOLLECTION */ 99 #define GEOJSON_GEOMCOLLECTION 207 100 101 102 /* constant values for GeoJSON datatypes */ 103 104 /** Text */ 105 #define GEOJSON_TEXT 301 106 107 /** Integer (namely Int64) */ 108 #define GEOJSON_INTEGER 302 109 110 /** Floating Point Double precision */ 111 #define GEOJSON_DOUBLE 303 112 113 /** Boolean - TRUE */ 114 #define GEOJSON_TRUE 304 115 116 /** Boolean - FALSE */ 117 #define GEOJSON_FALSE 305 118 119 /** NULL */ 120 #define GEOJSON_NULL 306 121 122 123 /* constant values for GeoJSON sizes */ 124 125 /** number of objects per each block */ 126 #define GEOJSON_BLOCK 4096 127 128 /** max fixed length for Text Strings */ 129 #define GEOJSON_MAX 1024 130 131 /** number of stack levels */ 132 #define GEOJSON_STACK 16 133 134 135 /* GeoJSON objects and data structures */ 136 137 /** 138 an object wrapping a GeoJSON Property (aka data attribute) 139 */ 140 typedef struct geojson_property_str 141 { 142 /** Property name */ 143 char *name; 144 /** datatype */ 145 int type; 146 /** pointer to Text value */ 147 char *txt_value; 148 /** Integer value */ 149 sqlite3_int64 int_value; 150 /** Double value */ 151 double dbl_value; 152 /** pointer to next item [linked list] */ 153 struct geojson_property_str *next; 154 } geojson_property; 155 156 /** 157 pointer to Property 158 */ 159 typedef geojson_property *geojson_property_ptr; 160 161 /** 162 an object wrapping a GeoJSON Feature 163 */ 164 typedef struct geojson_feature_str 165 { 166 /** unique Feature ID */ 167 int fid; 168 /** start offset; Geometry object */ 169 long geom_offset_start; 170 /** end offset: Geometry object */ 171 long geom_offset_end; 172 /** start offset: Properties object */ 173 long prop_offset_start; 174 /** end offset: Properties object */ 175 long prop_offset_end; 176 /** pointer to the Geometry string */ 177 char *geometry; 178 /** linked list of Properties - pointer to first item */ 179 geojson_property_ptr first; 180 /** linked list of Properties - pointer to last item */ 181 geojson_property_ptr last; 182 } geojson_feature; 183 184 /** 185 pointer to Feature 186 */ 187 typedef geojson_feature *geojson_feature_ptr; 188 189 /** 190 an object wrapping an entry (aka Object) in the GeoJSON file 191 */ 192 typedef struct geojson_entry_str 193 { 194 /** name of the parent object [key] */ 195 char *parent_key; 196 /** object type */ 197 int type; 198 /** count of Properties children */ 199 int properties; 200 /** count of Geometry children */ 201 int geometry; 202 /** object's start offset */ 203 long offset_start; 204 /** object's end offset */ 205 long offset_end; 206 } geojson_entry; 207 208 /** 209 pointer to Entry 210 */ 211 typedef geojson_entry *geojson_entry_ptr; 212 213 /** 214 an object wrapping a block of entries in the GeoJSON file */ 215 typedef struct geojson_block_str 216 { 217 /** index of the next free entry in the block */ 218 int next_free_entry; 219 /** array of entries */ 220 geojson_entry entries[GEOJSON_BLOCK]; 221 /** pointer to next item [linked list] */ 222 struct geojson_block_str *next; 223 } geojson_block; 224 225 /** 226 pointer to Block 227 */ 228 typedef geojson_block *geojson_block_ptr; 229 230 /** 231 an object wrapping a data Column 232 */ 233 typedef struct geojson_column_str 234 { 235 /** column name */ 236 char *name; 237 /** number of Text values */ 238 int n_text; 239 /** number of Int values */ 240 int n_int; 241 /** number of Double values */ 242 int n_double; 243 /** number of Boolean values */ 244 int n_bool; 245 /** number of NULL values */ 246 int n_null; 247 /** pointer to next item [linked list] */ 248 struct geojson_column_str *next; 249 } geojson_column; 250 251 /** 252 pointer to Column 253 */ 254 typedef geojson_column *geojson_column_ptr; 255 256 /** 257 an object wrapping a GeoJSON parser 258 */ 259 typedef struct geojson_parser_str 260 { 261 /** file handle */ 262 FILE *in; 263 /** linked list of Blocks - pointer to first item */ 264 geojson_block_ptr first; 265 /** linked list of Blocks - pointer to last item */ 266 geojson_block_ptr last; 267 /** total number of Features */ 268 int count; 269 /** array of Features */ 270 geojson_feature_ptr features; 271 /** linked list of Columns - pointer to first item */ 272 geojson_column_ptr first_col; 273 /** linked list of Columns - pointer to last item */ 274 geojson_column_ptr last_col; 275 /** total number of Point Geometries */ 276 int n_points; 277 /** total number of Linestring Geometries */ 278 int n_linestrings; 279 /** total number of Polygon Geometries */ 280 int n_polygons; 281 /** total number of MultiPoint Geometries */ 282 int n_mpoints; 283 /** total number of MultiLinestring Geometries */ 284 int n_mlinestrings; 285 /** total number of MultiPolygon Geometries */ 286 int n_mpolygons; 287 /** total number of GeometryCollection Geometries */ 288 int n_geomcolls; 289 /** total number of NULL Geometries */ 290 int n_geom_null; 291 /** total number of 2D Geometries */ 292 int n_geom_2d; 293 /** total number of 3D Geometries */ 294 int n_geom_3d; 295 /** total number of 4D Geometries */ 296 int n_geom_4d; 297 /** Geometry Type cast function */ 298 char cast_type[64]; 299 /** Geometry Dims cast function */ 300 char cast_dims[64]; 301 } geojson_parser; 302 303 /** 304 pointer to Parser 305 */ 306 typedef geojson_parser *geojson_parser_ptr; 307 308 /** 309 an object wrapping a Key-Value pair 310 */ 311 typedef struct geojson_keyval_str 312 { 313 /** pointer to the Key string */ 314 char *key; 315 /** pointer to the Value string */ 316 char *value; 317 /** FALSE for quoted Text strings */ 318 int numvalue; 319 /** pointer to next item [linked list] */ 320 struct geojson_keyval_str *next; 321 } geojson_keyval; 322 323 /** 324 pointer to KeyValue 325 */ 326 typedef geojson_keyval *geojson_keyval_ptr; 327 328 /** 329 an object wrapping a stack entry 330 */ 331 typedef struct geojson_stack_entry_str 332 { 333 /** pointer to an Entry object */ 334 geojson_entry_ptr obj; 335 /** linked list of KeyValues - pointer to first item */ 336 geojson_keyval_ptr first; 337 /** linked list of KeyValues - pointer to last item */ 338 geojson_keyval_ptr last; 339 } geojson_stack_entry; 340 341 /** 342 pointer to Stakc Entry 343 */ 344 typedef geojson_stack_entry *geojson_stack_entry_ptr; 345 346 /** 347 an object wrapping a GeoJSON stack 348 */ 349 typedef struct geojson_stack 350 { 351 /* a stack for parsing nested GeoJSON objects */ 352 /** current stack level */ 353 int level; 354 /** the stack levels array */ 355 geojson_stack_entry entries[GEOJSON_STACK]; 356 /** the Key parsing buffer */ 357 char key[GEOJSON_MAX]; 358 /** current Key index - last inserted byte */ 359 int key_idx; 360 /** the Value parsing buffer - quote delimited strings */ 361 char value[GEOJSON_MAX]; 362 /** current Value index - last inserted byte */ 363 int value_idx; 364 /** the Values parsing buffer - numeric values */ 365 char numvalue[GEOJSON_MAX]; 366 /** current numeric Value index - last inserted byte */ 367 int numvalue_idx; 368 } geojson_stack; 369 370 /** 371 pointer to Stack 372 */ 373 typedef geojson_stack *geojson_stack_ptr; 374 375 376 /* function prototypes */ 377 378 /** 379 Creates a new GeoJSON parser object 380 381 \param in an open FILE supposed to contain the GeoJSON text to be parsed 382 383 \return the pointer to newly created object 384 385 \sa geojson_destroy_parser, geojson_parser_init 386 387 \note you are responsible to destroy (before or after) any allocated 388 GeoJSON parser object. 389 */ 390 SPATIALITE_DECLARE geojson_parser_ptr geojson_create_parser (FILE * in); 391 392 /** 393 Destroys a GeoJSON parser object 394 395 \param p pointer to object to be destroyed 396 397 \sa geojson_create_parser 398 */ 399 SPATIALITE_DECLARE void geojson_destroy_parser (geojson_parser_ptr p); 400 401 /** 402 Fully initializes a GeoJSON parser object 403 404 \param parser pointer to a GeoJSON parser object 405 \param error_message: will point to a diagnostic error message 406 in case of failure, otherwise NULL 407 408 \return 1 on success. 0 on failure (invalid GeoJSON text). 409 410 \sa geojson_create_parser, geojson_check_features 411 412 \note you are expected to free before or later an eventual error 413 message by calling sqlite3_free() 414 */ 415 SPATIALITE_DECLARE int geojson_parser_init (geojson_parser_ptr parser, 416 char **error_message); 417 418 /** 419 Checks a fully initialized GeoJSON parser object for containing valid Features 420 421 \param parser pointer to a GeoJSON parser object 422 \param error_message: will point to a diagnostic error message 423 in case of failure, otherwise NULL 424 425 \return 1 on success. 0 on failure (invalid GeoJSON text). 426 427 \sa geojson_parser_init, geojson_create_features_index 428 429 \note you are expected to free before or later an eventual error 430 message by calling sqlite3_free() 431 */ 432 SPATIALITE_DECLARE int geojson_check_features (geojson_parser_ptr parser, 433 char **error_message); 434 435 /** 436 Creates the Features Index on a GeoJSON parser object 437 438 \param parser pointer to a GeoJSON parser object 439 \param error_message: will point to a diagnostic error message 440 in case of failure, otherwise NULL 441 442 \return 1 on success. 0 on failure (invalid GeoJSON text). 443 444 \sa geojson_check_features 445 446 \note you are expected to free before or later an eventual error 447 message by calling sqlite3_free() 448 */ 449 SPATIALITE_DECLARE int geojson_create_features_index (geojson_parser_ptr 450 parser, 451 char **error_message); 452 453 /** 454 Will return the SQL CREATE TABLE statement 455 456 \param parser pointer to a GeoJSON parser object 457 \param table name of the SQL table to be created 458 \param colname_case one between GAIA_DBF_COLNAME_LOWERCASE, 459 GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE. 460 461 \return the SQL CREATE TABLE statement as a text string; NULL on failure 462 463 \sa geojson_check_features, geojson_sql_add_geometry, geojson_sql_create_rtree 464 geojson_insert_into 465 466 \note you are expected to free the SQL string returned by this 467 function by calling sqlite3_free() when it's no longer useful. 468 */ 469 SPATIALITE_DECLARE char *geojson_sql_create_table (geojson_parser_ptr 470 parser, 471 const char *table, 472 int colname_case); 473 474 /** 475 Will return the SQL AddGeometryColumn() statement 476 477 \param parser pointer to a GeoJSON parser object 478 \param table name of the SQL table being created 479 \param geom_col name of the Geometry column 480 \param colname_case one between GAIA_DBF_COLNAME_LOWERCASE, 481 GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE. 482 \param srid the corresponding SRID value 483 484 \return the AddGeometryColumn() SQL string; NULL on failure 485 486 \sa geojson_check_features, geojson_sql_create_table, geojson_sql_create_rtree 487 geojson_insert_into 488 489 \note you are expected to free the SQL string returned by this 490 function by calling sqlite3_free() when it's no longer useful. 491 */ 492 SPATIALITE_DECLARE char *geojson_sql_add_geometry (geojson_parser_ptr 493 parser, 494 const char *table, 495 const char *geom_col, 496 int colname_case, 497 int srid); 498 499 /** 500 Will return the SQL CreateSpatialIndex() statement 501 502 \param table name of the SQL table being created 503 \param geom_col name of the Geometry column 504 \param colname_case one between GAIA_DBF_COLNAME_LOWERCASE, 505 GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE. 506 507 \return the CreateSpatialIndex() SQL string; NULL on failure 508 509 \sa geojson_check_features, geojson_sql_create_table, geojson_sql_add_geometry, 510 geojson_insert_into 511 512 \note you are expected to free the SQL string returned by this 513 function by calling sqlite3_free() when it's no longer useful. 514 */ 515 SPATIALITE_DECLARE char *geojson_sql_create_rtree (const char *table, 516 const char *geom_col, 517 int colname_case); 518 519 /** 520 Will return the SQL INSERT INTO statement 521 522 \param parser pointer to a GeoJSON parser object 523 \param table name of the SQL table being created 524 \param geom_col name of the Geometry column 525 526 \return the INSERT INTO SQL string; NULL on failure 527 528 \sa geojson_check_features, geojson_sql_create_table, geojson_add_geometry, 529 geojson_sql_create_rtree 530 531 \note you are expected to free the SQL string returned by this 532 function by calling sqlite3_free() when it's no longer useful. 533 */ 534 SPATIALITE_DECLARE char *geojson_sql_insert_into (geojson_parser_ptr 535 parser, 536 const char *table); 537 538 /** 539 Will fully initialize a Feature with all Property and Geometry values 540 541 \param parser pointer to a GeoJSON parser object 542 \param ft pointer the some GeoJson Feature object into the Parser 543 \param error_message: will point to a diagnostic error message 544 in case of failure, otherwise NULL 545 546 \return 1 on success. 0 on failure (invalid GeoJSON Feature). 547 548 \sa geojson_create_features_index, geojson_reset_feature, 549 geojson_get_property_by_name 550 551 \note you are expected to free all Values returned by this function by 552 calling geojson_reset_feature() when they are no longer useful. 553 And you are expected also to free before or later an eventual error 554 message by calling sqlite3_free() 555 */ 556 SPATIALITE_DECLARE int geojson_init_feature (geojson_parser_ptr parser, 557 geojson_feature_ptr ft, 558 char **error_message); 559 560 /** 561 Will reset a Feature by freeing all Property and Geometry Values 562 563 \param ft pointer the some GeoJson Feature object into the Parser 564 565 \sa geojson_create_features_index, geojson_init_feature, 566 geojson_get_property_by_name 567 */ 568 SPATIALITE_DECLARE void geojson_reset_feature (geojson_feature_ptr ft); 569 570 /** 571 Will return the pointer to a given Property within a Feature 572 573 \param ft pointer the some GeoJson Feature object 574 \param name the name of some specific Property 575 576 \sa geojson_create_features_index, geojson_init_feature, 577 geojson_reset_feature 578 */ 579 SPATIALITE_DECLARE geojson_property_ptr 580 geojson_get_property_by_name (geojson_feature_ptr ft, const char *name); 581 582 #ifdef __cplusplus 583 } 584 #endif 585 586 #endif /* _GEOJSON_H */ 587