1 #ifndef GEONAMES_H 2 #define GEONAMES_H 3 4 5 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <stdint.h> 9 #include <stdbool.h> 10 #include <string.h> 11 12 #include "collections.h" 13 #include "features.h" 14 #include "string_utils.h" 15 16 typedef enum { 17 GEONAMES_COUNTRY = 0, 18 GEONAMES_ADMIN1 = 1, 19 GEONAMES_ADMIN2 = 2, 20 GEONAMES_ADMIN3 = 3, 21 GEONAMES_ADMIN4 = 4, 22 GEONAMES_ADMIN_OTHER = 5, 23 GEONAMES_LOCALITY = 6, 24 GEONAMES_NEIGHBORHOOD = 7, 25 NUM_BOUNDARY_TYPES 26 } boundary_type_t; 27 28 #define GEONAMES_ADDRESS_COMPONENT_COUNTRY (1 << 0) 29 #define GEONAMES_ADDRESS_COMPONENT_ADMIN1 (1 << 1) 30 #define GEONAMES_ADDRESS_COMPONENT_ADMIN2 (1 << 2) 31 #define GEONAMES_ADDRESS_COMPONENT_ADMIN3 (1 << 3) 32 #define GEONAMES_ADDRESS_COMPONENT_ADMIN4 (1 << 4) 33 #define GEONAMES_ADDRESS_COMPONENT_ADMIN_OTHER (1 << 5) 34 #define GEONAMES_ADDRESS_COMPONENT_LOCALITY (1 << 6) 35 #define GEONAMES_ADDRESS_COMPONENT_NEIGHBORHOOD (1 << 7) 36 #define GEONAMES_ADDRESS_COMPONENT_POSTCODE (1 << 8) 37 38 typedef struct geoname { 39 uint32_t geonames_id; 40 char_array *name; 41 char_array *canonical; 42 boundary_type_t type; 43 char_array *iso_language; 44 bool has_wikipedia_entry; 45 bool is_preferred_name; 46 bool is_short_name; 47 bool is_colloquial; 48 bool is_historical; 49 uint32_t population; 50 double latitude; 51 double longitude; 52 char_array *feature_code; 53 char_array *country_code; 54 uint32_t country_geonames_id; 55 char_array *admin1_code; 56 uint32_t admin1_geonames_id; 57 char_array *admin2_code; 58 uint32_t admin2_geonames_id; 59 char_array *admin3_code; 60 uint32_t admin3_geonames_id; 61 char_array *admin4_code; 62 uint32_t admin4_geonames_id; 63 } geoname_t; 64 65 /* We want to reuse objects here, so only call 66 * geoname_create once or twice and populate the same 67 * object repeatedly with geoname_deserialize. 68 * This helps avoid making too many malloc/free calls 69 */ 70 geoname_t *geoname_new(void); 71 bool geoname_deserialize(geoname_t *self, char_array *str); 72 bool geoname_serialize(geoname_t *self, char_array *str); 73 void geoname_print(geoname_t *self); 74 void geoname_clear(geoname_t *self); 75 void geoname_destroy(geoname_t *self); 76 77 typedef struct gn_postal_code { 78 char_array *postal_code; 79 char_array *country_code; 80 uint32_t country_geonames_id; 81 bool have_lat_lon; 82 double latitude; 83 double longitude; 84 uint8_t accuracy; 85 bool have_containing_geoname; 86 char_array *containing_geoname; 87 uint32_t containing_geonames_id; 88 uint32_array *admin1_ids; 89 uint32_array *admin2_ids; 90 uint32_array *admin3_ids; 91 } gn_postal_code_t; 92 93 gn_postal_code_t *gn_postal_code_new(void); 94 bool gn_postal_code_deserialize(gn_postal_code_t *self, char_array *str); 95 bool gn_postal_code_serialize(gn_postal_code_t *self, char_array *str); 96 void gn_postal_code_print(gn_postal_code_t *self); 97 void gn_postal_code_clear(gn_postal_code_t *self); 98 void gn_postal_code_destroy(gn_postal_code_t *self); 99 100 typedef enum { 101 GEONAMES_PLACE, 102 GEONAMES_POSTAL_CODE 103 } gn_type; 104 105 typedef struct geonames_generic { 106 gn_type type; 107 union { 108 geoname_t *geoname; 109 gn_postal_code_t *postal_code; 110 }; 111 } geonames_generic_t; 112 113 VECTOR_INIT(gn_generic_array, geonames_generic_t); 114 115 bool geonames_generic_serialize(geonames_generic_t *gn, char_array *str); 116 bool geonames_generic_deserialize(gn_type *type, geoname_t *geoname, gn_postal_code_t *postal_code, char_array *str); 117 118 119 120 #endif 121