File: spatial_handler.h

package info (click to toggle)
mysql-workbench 6.3.8%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 113,932 kB
  • ctags: 87,814
  • sloc: ansic: 955,521; cpp: 427,465; python: 59,728; yacc: 59,129; xml: 54,204; sql: 7,091; objc: 965; makefile: 638; sh: 613; java: 237; perl: 30; ruby: 6; php: 1
file content (256 lines) | stat: -rw-r--r-- 7,861 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/*
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#ifndef SPATIAL_HANDLER_H_
#define SPATIAL_HANDLER_H_

#include <gdal/ogrsf_frmts.h>
#include <gdal/ogr_api.h>
#include <gdal/gdal_pam.h>
#include <gdal/memdataset.h>
#include <gdal/gdal_alg.h>
#include <gdal/gdal.h>
#include <deque>
#include "base/geometry.h"
#include "wbpublic_public_interface.h"

#include "mdc.h"
/* Spatial Object Model

 Feature - corresponds to the value of a single geometry column of a row in a resultset
 Identified by the layer (resultset) and row_id and may contain one or more attributes, which are the rest
 of the columns of the resultset.

 Layer - corresponds to a single resutset or data source to be displayed.
 Can be toggled to be shown or not.
 Contains a list of features that are part of that layer.
 Should allow identifying the feature that is located at a specific coordinate.
 */

namespace spatial
{

  struct WBPUBLICBACKEND_PUBLIC_FUNC ProjectionView
  {
    int width;
    int height;
    double MaxLat;
    double MaxLon;
    double MinLat;
    double MinLon;
    friend bool operator== (const ProjectionView &v1, const ProjectionView &v2);
    friend bool operator!= (const ProjectionView &v1, const ProjectionView &v2);
  };

  class WBPUBLICBACKEND_PUBLIC_FUNC Envelope
  {
  public:
    Envelope();
    Envelope(double left, double top, double right, double bottom);
    bool converted;
    base::Point top_left;
    base::Point bottom_right;
    friend bool operator == (const Envelope &env1, const Envelope &env2);
    friend bool operator != (const Envelope &env1, const Envelope &env2);
    bool is_init();
    bool within(const base::Point &p) const;
  };

  bool operator== (const ProjectionView &v1, const ProjectionView &v2);
  bool operator!= (const ProjectionView &v1, const ProjectionView &v2);
  bool operator== (const Envelope &env1, const Envelope &env2);
  bool operator!= (const Envelope &env1, const Envelope &env2);

  enum ProjectionType
  {
    ProjMercator = 1, ProjEquirectangular = 2, ProjRobinson = 3, ProjBonne = 4, ProjGeodetic = 5
  };

  enum ShapeType
  {
    ShapeUnknown, ShapePoint, ShapeLineString, ShapeLinearRing, ShapePolygon
  };

  std::string shape_description(ShapeType shp);


  enum AxisType
  {
    AxisLat = 1, AxisLon = 2
  };

  class WBPUBLICBACKEND_PUBLIC_FUNC ShapeContainer
  {

  protected:
    double distance_linearring(const base::Point &p) const;
    double distance_line(const std::vector<base::Point> &point_list, const base::Point &p) const;
    double distance_polygon(const base::Point &p) const;
    double distance_point(const base::Point &p) const;
  public:
    ShapeContainer();
    ShapeType type;
    std::vector<base::Point> points;
    Envelope bounding_box;
    double distance(const base::Point &p) const;
  };

  class WBPUBLICBACKEND_PUBLIC_FUNC Projection
  {
  protected:
    OGRSpatialReference _mercator_srs;
    OGRSpatialReference _equirectangular_srs;
    OGRSpatialReference _robinson_srs;
    OGRSpatialReference _geodetic_srs;
    OGRSpatialReference _bonne_srs;

  public:
    static Projection& get_instance();
    bool check_libproj_availability();
    OGRSpatialReference* get_projection(ProjectionType);
  private:
    Projection();
    Projection(Projection const&);
    void operator=(Projection const&);

  };


  class WBPUBLICBACKEND_PUBLIC_FUNC Importer
  {
    OGRGeometry *_geometry;
    bool _interrupt;
    void extract_points(OGRGeometry *shape, std::deque<ShapeContainer> &shapes_container);
  public:
    Importer();
    ~Importer();
    int import_from_mysql(const std::string &data);
    int import_from_wkt(std::string data);
    void get_points(std::deque<ShapeContainer> &shapes_container);
    void get_envelope(Envelope &env);
    void interrupt();

    std::string as_wkt();
    std::string as_kml();
    std::string as_json();
    std::string as_gml();

    OGRGeometry *steal_data();
  };

  class WBPUBLICBACKEND_PUBLIC_FUNC Converter
  {
    base::RecMutex _projection_protector;
    double _adf_projection[6];
    double _inv_projection[6];
    OGRCoordinateTransformation *_geo_to_proj;
    OGRCoordinateTransformation *_proj_to_geo;
    OGRSpatialReference *_source_srs;
    OGRSpatialReference *_target_srs;
    ProjectionView _view;
    bool _interrupt;
  public:
    Converter(ProjectionView view, OGRSpatialReference *src_srs, OGRSpatialReference *dst_srs);
    ~Converter();
    void change_projection(OGRSpatialReference *src_srs = NULL, OGRSpatialReference *dst_srs = NULL);
    void change_projection(ProjectionView view, OGRSpatialReference *src_srs = NULL, OGRSpatialReference *dst_srs = NULL);
    void from_projected(double lat, double lon, int &x, int &y);
    void to_projected(int x, int y, double &lat, double &lon);

    bool to_latlon(int x, int y, double &lat, double &lon);
    bool from_latlon(double lat, double lon, int &x, int &y);

    bool from_latlon_to_proj(double &lat, double &lon);
    bool from_proj_to_latlon(double &lat, double &lon);
    static std::string dec_to_dms(double angle, AxisType axis, int precision);
    void transform_points(std::deque<ShapeContainer> &shapes_container);
    void transform_envelope(spatial::Envelope &env);
    void interrupt();
  };


  class Layer;

  class WBPUBLICBACKEND_PUBLIC_FUNC Feature
  {
    Layer *_owner;
    int _row_id;
    Importer _geometry;
    std::deque<ShapeContainer> _shapes;
    spatial::Envelope _env_screen;
  public:
    Feature(Layer *layer, int row_id, const std::string &data, bool wkt);
    ~Feature();

    void interrupt();
    void get_envelope(spatial::Envelope &env, const bool &screen_coords = false);
    void render(spatial::Converter *converter);
    void repaint(mdc::CairoCtx &cr, float scale, const base::Rect &clip_area, base::Color fill_color=base::Color::Invalid());

    int row_id() const { return _row_id; }
    double distance(const base::Point &p, const double &allowed_distance = 4.0);
  };

  typedef int LayerId;
  WBPUBLICBACKEND_PUBLIC_FUNC LayerId new_layer_id();

  class WBPUBLICBACKEND_PUBLIC_FUNC Layer
  {
    friend class Feature;

  protected:
    std::deque<Feature*> _features;

    LayerId _layer_id;
    base::Color _color;
    float _render_progress;
    bool _show;
    bool _interrupt;
    spatial::Envelope _spatial_envelope;
    bool _fill_polygons;

  public:
    Layer(LayerId layer_id, base::Color color);
    virtual ~Layer();

    virtual void load_data() {}

    void interrupt();

    bool hidden();
    LayerId layer_id();

    void set_show(bool flag);

    size_t size() { return _features.size(); }

    base::Color color() { return _color; }
    bool fill() { return _fill_polygons; }

    void add_feature(int row_id, const std::string &geom_data, bool wkt);
    virtual void render(spatial::Converter *converter);
    spatial::Feature *feature_closest(const base::Point &p, const double &allowed_distance = 4.0);
    void set_fill_polygons(bool fill);
    bool get_fill_polygons();
    virtual void repaint(mdc::CairoCtx &cr, float scale, const base::Rect &clip_area);
    float query_render_progress();
    spatial::Envelope get_envelope();
  };
};
#endif /* SPATIAL_HANDLER_H_ */