Version: 0.6.0
displayop.h
1 /******************************************************************************
2  * Project: wxGIS (GIS Catalog)
3  * Purpose: display transformation. Transform from world to screen coordinates and vice versa
4  * Author: Dmitry Baryshnikov (aka Bishop), polimax@mail.ru
5  ******************************************************************************
6 * Copyright (C) 2009,2011,2013 Dmitry Baryshnikov
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  ****************************************************************************/
21 #pragma once
22 
23 #include "wxgis/display/display.h"
24 
25 #include <wx/xml/xml.h>
26 
27 class WXDLLIMPEXP_FWD_GIS_DSP wxGISColor;
28 
29 WXDLLIMPEXP_GIS_DSP void SetColorValue(wxXmlNode* pNode, const wxString &sAttrName, const wxGISColor &oColor);
30 WXDLLIMPEXP_GIS_DSP wxGISColor GetColorValue(const wxXmlNode* pNode, const wxString &sAttrName, const wxGISColor &oDefaultColor);
31 
32 WXDLLIMPEXP_GIS_DSP void RotateEnvelope(OGREnvelope &Env, double dAngle, double dX, double dY);
33 WXDLLIMPEXP_GIS_DSP void ClipGeometryByEnvelope(OGRRawPoint* pOGRRawPoints, int *pnPointCount, const OGREnvelope &Env, bool shapeOpen);
34 
35 //Sutherland-Hodgman Polygon Clipping
36 inline bool IsInsideEnvelope(const OGRRawPoint &pt, wxGISEnumPointPosition nPos, const OGREnvelope &Env)
37 {
38  switch(nPos)
39  {
40  case enumGISPtPosLeft://XMin
41  return (pt.x > Env.MinX);
42  case enumGISPtPosRight://XMax
43  return (pt.x < Env.MaxX);
44  case enumGISPtPosBottom://YMin
45  return (pt.y > Env.MinY);
46  case enumGISPtPosTop://YMax
47  return (pt.y < Env.MaxY);
48  }
49  return false;
50 }
51 
52 inline OGRRawPoint SolveIntersection(const OGRRawPoint &pt1, const OGRRawPoint &pt2, wxGISEnumPointPosition nPos, const OGREnvelope &Env)
53 {
54  OGRRawPoint out;
55  double r_n = EPSILON, r_d = EPSILON;
56 
57  switch ( nPos )
58  {
59  case enumGISPtPosRight: // x = MAX_X boundary
60  r_n = -( pt1.x - Env.MaxX ) * ( Env.MaxY - Env.MinY );
61  r_d = ( pt2.x - pt1.x ) * ( Env.MaxY - Env.MinY );
62  break;
63  case enumGISPtPosLeft: // x = MIN_X boundary
64  r_n = -( pt1.x - Env.MinX ) * ( Env.MaxY - Env.MinY );
65  r_d = ( pt2.x - pt1.x ) * ( Env.MaxY - Env.MinY );
66  break;
67  case enumGISPtPosTop: // y = MAX_Y boundary
68  r_n = ( pt1.y - Env.MaxY ) * ( Env.MaxX - Env.MinX );
69  r_d = -( pt2.y - pt1.y ) * ( Env.MaxX - Env.MinX );
70  break;
71  case enumGISPtPosBottom: // y = MIN_Y boundary
72  r_n = ( pt1.y - Env.MinY ) * ( Env.MaxX - Env.MinX );
73  r_d = -( pt2.y - pt1.y ) * ( Env.MaxX - Env.MinX );
74  break;
75  }
76 
77  if ( fabs( r_d ) > EPSILON && fabs( r_n ) > EPSILON )
78  { // they cross
79  double r = r_n / r_d;
80  out.x = pt1.x + r * ( pt2.x - pt1.x );
81  out.y = pt1.y + r * ( pt2.y - pt1.y );
82  }
83  else
84  {
85  // Should never get here, but if we do for some reason, cause a
86  // clunk because something else is wrong if we do.
87  wxASSERT( fabs( r_d ) > EPSILON && fabs( r_n ) > EPSILON );
88  }
89 
90  return out;
91 }
92 
93 inline void TrimFeatureToBoundary(OGRRawPoint* pOGRRawPointsIn, int nPointCountIn, OGRRawPoint** pOGRRawPointsOut, int *pnPointCountOut, wxGISEnumPointPosition nPos, const OGREnvelope &Env, bool shapeOpen )
94 {
95  // The shapeOpen parameter selects whether this function treats the
96  // shape as open or closed. False is appropriate for polygons and
97  // true for polylines.
98 
99  unsigned int i1 = nPointCountIn - 1; // start with last point
100 
101  // and compare to the first point initially.
102  for ( int i2 = 0; i2 < nPointCountIn; ++i2 )
103  { // look at each edge of the polygon in turn
104  if ( IsInsideEnvelope( pOGRRawPointsIn[i2], nPos, Env ) ) // end point of edge is inside boundary
105  {
106  if ( IsInsideEnvelope( pOGRRawPointsIn[i1], nPos, Env) )
107  (*pOGRRawPointsOut)[(*pnPointCountOut)++] = pOGRRawPointsIn[i2];
108  else
109  {
110  // edge crosses into the boundary, so trim back to the boundary, and
111  // store both ends of the new edge
112  if ( !( i2 == 0 && shapeOpen ) )
113  (*pOGRRawPointsOut)[(*pnPointCountOut)++] = SolveIntersection( pOGRRawPointsIn[i1], pOGRRawPointsIn[i2], nPos, Env );
114  (*pOGRRawPointsOut)[(*pnPointCountOut)++] = pOGRRawPointsIn[i2];
115  }
116  }
117  else // end point of edge is outside boundary
118  {
119  // start point is in boundary, so need to trim back
120  if ( IsInsideEnvelope( pOGRRawPointsIn[i1], nPos, Env) )
121  {
122  if ( !( i2 == 0 && shapeOpen ) )
123  (*pOGRRawPointsOut)[(*pnPointCountOut)++] = SolveIntersection( pOGRRawPointsIn[i1], pOGRRawPointsIn[i2], nPos, Env );
124  }
125  }
126  i1 = i2;
127  }
128 }
129 
130 //DisplayTransformation – This object defines how real-world coordinates are mapped to a output device. Three rectangles define the transformation.
131 //The Bounds specifies the full extent in real-world coordinates. The VisibleBounds specifies what extent is currently visible.
132 //And the DeviceFrame specifies where the VisibleBounds appears on the output device. Since the aspect ratio of the DeviceFrame may not always match the aspect ratio of the specified VisibleBounds, the transformation calculates the actual visible bounds that fits the DeviceFrame. This is called the FittedBounds and is in real-world coordinates. All coordinates can be rotated about the center of the visible bounds by simply setting the transformationÂ’s Rotation property.
133 
134 //class wxGISDisplayTransformation :
135 // public IDisplayTransformation
136 //{
137 //public:
138 // wxGISDisplayTransformation(void);
139 // virtual ~wxGISDisplayTransformation(void);
140 // virtual void Reset(void);
141 // virtual void SetDeviceFrame(wxRect rc);
142 // virtual wxRect GetDeviceFrame(void);
143 // virtual bool IsBoundsSet(void);
144 // virtual void SetBounds(OGREnvelope bounds);
145 // virtual OGREnvelope GetBounds(void);
146 // virtual OGREnvelope GetVisibleBounds(void);
147 // virtual double GetRatio(void);
148 // virtual double GetScaleRatio(void);
149 // virtual void SetSpatialReference(OGRSpatialReference* pSpatialReference);
150 // virtual OGRSpatialReference* GetSpatialReference(void);
151 // virtual wxPoint* TransformCoordWorld2DC(OGRRawPoint* pPoints, size_t nPointCount);
152 // virtual void TransformCoordWorld2DC(OGRRawPoint* pPoints, size_t nPointCount, wxPoint* pResult);
153 // virtual OGRRawPoint* TransformCoordDC2World(wxPoint* pPoints, size_t nPointCount);
154 // virtual void SetPPI(wxSize new_res);
155 // virtual OGREnvelope TransformRect(wxRect rect);
156 //protected:
157 // // World2DC
158 // double xWorld2DC(double x);
159 // double yWorld2DC(double y);
160 // // DC2World
161 // double xDC2World(int x);
162 // double yDC2World(int y);
163 //protected:
164 // double m_World2DC, m_DC2World, m_DCXDelta, m_DCYDelta, m_WorldXDelta, m_WorldYDelta;
165 // wxRect m_DeviceFrameRect;
166 // OGREnvelope m_Bounds;
167 // OGRSpatialReference* m_pSpatialReference;
168 // bool m_bIsBoundsSet;
169 // wxSize m_ppi;
170 //};
Definition: color.h:34