Skip to content

Commit 49a6167

Browse files
committed
Merge branch 'release/v5.0.1'
2 parents 65d56c4 + 4dc67a1 commit 49a6167

27 files changed

+443
-205
lines changed

docs/AxInterop.MapWinGIS/AxMap.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2873,12 +2873,22 @@ public double GeodesicLength(Shape polyline)
28732873

28742874
/// <summary>
28752875
/// This event is fired when the user finishes dragging a selection box in the map control.
2876-
/// The map property SendSelectBoxFinal must be set to True for this event to be fired.
2876+
/// The map property SendSelectBoxFinal must be set to True for this event to be fired.
28772877
/// </summary>
28782878
/// <param name="left">The left boundary of the selection box in pixel coordinates.</param>
28792879
/// <param name="right">The right boundary of the selection box in pixel coordinates.</param>
28802880
/// <param name="bottom">The bottom boundary of the selection box in pixel coordinates.</param>
28812881
/// <param name="top">The top boundary of the selection box in pixel coordinates.</param>
2882+
/// <remarks>
2883+
/// Prior to version 5.0, there was ambiguity as to whether or not this event was fired
2884+
/// in all circumstances. In the case of the cmZoomIn tool, this event was always fired.
2885+
/// But in the case of the cmSelection tool, it was only fired in the case when no shapes
2886+
/// were actually 'selected'. If any shapes were 'selected', the SelectionChanged event
2887+
/// was fired, but the SelectBoxFinal was not. As of version 5.0, the SelectBoxFinal event
2888+
/// will always be fired after dragging a rectangle, whether or not any shapes were actually
2889+
/// 'selected'.
2890+
/// </remarks>
2891+
/// \new500 Modified in version 5.0
28822892
public event _DMapEvents_SelectBoxFinalEventHandler SelectBoxFinal;
28832893

28842894
/// <summary>

docs/Interop.MapWinGIS/Related Pages/Version history.cs

Lines changed: 157 additions & 134 deletions
Large diffs are not rendered by default.

docs/MapWinGIS.doxyfile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ ALIASES = "new48=\xrefitem newpage48 \"New API 4.8\" \"New API 4.
245245
"new493=\xrefitem newpage493 \"New API 4.9.3\" \"New API 4.9.3\"" \
246246
"new494=\xrefitem newpage494 \"New API 4.9.4\" \"New API 4.9.4\"" \
247247
"new495=\xrefitem newpage495 \"New API 4.9.5\" \"New API 4.9.5\"" \
248-
"new500=\xrefitem newpage500 \"New API 5.0.0\" \"New API 5.0.0\"" \
249-
"removed493=\xrefitem removed493 \"Removed in 4.9.3\" \"Removed in 4.9.3\""
248+
"removed493=\xrefitem removed493 \"Removed in 4.9.3\" \"Removed in 4.9.3\"" \
249+
"new500=\xrefitem newpage500 \"New API 5.0.0\" \"New API 5.0.0\""
250250

251251
# This tag can be used to specify a number of word-keyword mappings (TCL only).
252252
# A mapping has the form "name=value". For example adding "class=itcl::class"
@@ -2475,19 +2475,19 @@ DOT_TRANSPARENT = NO
24752475
# The default value is: NO.
24762476
# This tag requires that the tag HAVE_DOT is set to YES.
24772477

2478-
DOT_MULTI_TARGETS = YES
2478+
DOT_MULTI_TARGETS = NO
24792479

24802480
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
24812481
# explaining the meaning of the various boxes and arrows in the dot generated
24822482
# graphs.
24832483
# The default value is: YES.
24842484
# This tag requires that the tag HAVE_DOT is set to YES.
24852485

2486-
GENERATE_LEGEND = YES
2486+
GENERATE_LEGEND = NO
24872487

24882488
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
24892489
# files that are used to generate the various graphs.
24902490
# The default value is: YES.
24912491
# This tag requires that the tag HAVE_DOT is set to YES.
24922492

2493-
DOT_CLEANUP = YES
2493+
DOT_CLEANUP = NO

src/COM classes/ShapeEditor.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,22 @@ STDMETHODIMP CShapeEditor::put_SnapBehavior(tkLayerSelection newVal)
782782
return S_OK;
783783
}
784784

785+
// *******************************************************
786+
// get_SnapMode()
787+
// *******************************************************
788+
STDMETHODIMP CShapeEditor::get_SnapMode(tkSnapMode* pVal)
789+
{
790+
AFX_MANAGE_STATE(AfxGetStaticModuleState());
791+
*pVal = _snapMode;
792+
return S_OK;
793+
}
794+
STDMETHODIMP CShapeEditor::put_SnapMode(tkSnapMode newVal)
795+
{
796+
AFX_MANAGE_STATE(AfxGetStaticModuleState());
797+
_snapMode = newVal;
798+
return S_OK;
799+
}
800+
785801
// *******************************************************
786802
// EditorState
787803
// *******************************************************

src/COM classes/ShapeEditor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class ATL_NO_VTABLE CShapeEditor :
2727
_highlightShapes = lsAllLayers;
2828
_snapTolerance = 10;
2929
_snapBehavior = lsAllLayers;
30+
_snapMode = smVerticesAndLines;
3031
_state = esNone;
3132
_mapCallback = NULL;
3233
_isSubjectShape = false;
@@ -113,6 +114,8 @@ class ATL_NO_VTABLE CShapeEditor :
113114
STDMETHOD(put_HighlightVertices)(tkLayerSelection newVal);
114115
STDMETHOD(get_SnapBehavior)(tkLayerSelection* pVal);
115116
STDMETHOD(put_SnapBehavior)(tkLayerSelection newVal);
117+
STDMETHOD(get_SnapMode)(tkSnapMode* pVal);
118+
STDMETHOD(put_SnapMode)(tkSnapMode newVal);
116119
STDMETHOD(get_EditorState)(tkEditorState* pVal);
117120
STDMETHOD(put_EditorState)(tkEditorState newVal);
118121
STDMETHOD(StartEdit)(LONG LayerHandle, LONG ShapeIndex, VARIANT_BOOL* retVal);
@@ -154,6 +157,7 @@ class ATL_NO_VTABLE CShapeEditor :
154157
ICallback * _globalCallback;
155158
VARIANT_BOOL _visible;
156159
tkLayerSelection _highlightShapes;
160+
tkSnapMode _snapMode;
157161
double _snapTolerance;
158162
tkLayerSelection _snapBehavior;
159163
EditorBase* _activeShape;

src/COM classes/Shapefile.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3174,6 +3174,41 @@ STDMETHODIMP CShapefile::GetClosestVertex(double x, double y, double maxDistance
31743174
return S_OK;
31753175
}
31763176

3177+
// *****************************************************************
3178+
// GetClosestSnapPosition()
3179+
// *****************************************************************
3180+
STDMETHODIMP CShapefile::GetClosestSnapPosition(double x, double y, double maxDistance,
3181+
long* shapeIndex, double* fx, double* fy, double* distance, VARIANT_BOOL* retVal)
3182+
{
3183+
AFX_MANAGE_STATE(AfxGetStaticModuleState());
3184+
3185+
*retVal = VARIANT_FALSE;
3186+
*shapeIndex = -1;
3187+
3188+
bool result = false;
3189+
if (maxDistance <= 0.0)
3190+
{
3191+
// search through all shapefile
3192+
std::vector<long> ids;
3193+
for (size_t i = 0; i < _shapeData.size(); i++)
3194+
{
3195+
ids.push_back(i);
3196+
}
3197+
result = ShapefileHelper::GetClosestSnapPosition(this, x, y, maxDistance, ids, shapeIndex, *fx, *fy, *distance);
3198+
}
3199+
else
3200+
{
3201+
std::vector<long> ids;
3202+
Extent box(x - maxDistance, x + maxDistance, y - maxDistance, y + maxDistance);
3203+
if (this->SelectShapesCore(box, 0.0, SelectMode::INTERSECTION, ids, false))
3204+
{
3205+
result = ShapefileHelper::GetClosestSnapPosition(this, x, y, maxDistance, ids, shapeIndex, *fx, *fy, *distance);
3206+
}
3207+
}
3208+
*retVal = result ? VARIANT_TRUE : VARIANT_FALSE;
3209+
return S_OK;
3210+
}
3211+
31773212
// *****************************************************************
31783213
// HasInvalidShapes()
31793214
// *****************************************************************

src/COM classes/Shapefile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ class ATL_NO_VTABLE CShapefile :
213213
STDMETHOD(EditAddShape)(IShape* shape, long* shapeIndex);
214214
STDMETHOD(EditAddField)(BSTR name, FieldType type, int precision, int width, long* fieldIndex);
215215
STDMETHOD(GetClosestVertex)(double x, double y, double maxDistance, long* shapeIndex, long* pointIndex, double* distance, VARIANT_BOOL* retVal);
216+
STDMETHOD(GetClosestSnapPosition)(double x, double y, double maxDistance, long* shapeIndex, double* fx, double* fy, double* distance, VARIANT_BOOL* retVal);
216217
STDMETHOD(get_ShapeCategory2)(long ShapeIndex, BSTR* categoryName);
217218
STDMETHOD(put_ShapeCategory2)(long ShapeIndex, BSTR categoryName);
218219
STDMETHOD(get_ShapeCategory3)(long ShapeIndex, IShapefileCategory** category);

src/COM classes/Shapefile_Selection.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,10 @@ bool CShapefile::SelectShapesCore(Extent& extents, double Tolerance, SelectMode
175175
shapeVal = i;
176176
}
177177

178-
IShape* shape = _shapeData[shapeVal]->shape;
179-
// convert querying shape to GEOS
178+
// get current shape
179+
CComPtr<IShape> shape = nullptr;
180+
get_Shape(shapeVal, &shape);
181+
// convert querying shape to GEOS
180182
GEOSGeom geosShape = GeosConverter::ShapeToGeom(shape);
181183
// check for containment
182184
if (GeosHelper::Contains(geosShape, geosPoint))
@@ -255,9 +257,10 @@ bool CShapefile::SelectShapesCore(Extent& extents, double Tolerance, SelectMode
255257

256258
if( shpType2D == SHP_POLYLINE && SelectMode == INTERSECTION)
257259
{
258-
// get current shape
259-
IShape* shape = _shapeData[shapeVal]->shape;
260-
// convert shape to GEOS
260+
// get current shape
261+
CComPtr<IShape> shape = nullptr;
262+
get_Shape(shapeVal, &shape);
263+
// convert shape to GEOS
261264
GEOSGeom geos = GeosConverter::ShapeToGeom(shape);
262265
// see if shape intersects polygon extent
263266
if (GeosHelper::Intersects(geosExtent, geos))
@@ -271,10 +274,11 @@ bool CShapefile::SelectShapesCore(Extent& extents, double Tolerance, SelectMode
271274
//}
272275
}
273276
else if( shpType2D == SHP_POLYGON && SelectMode == INTERSECTION)
274-
{
275-
// get current shape
276-
IShape* shape = _shapeData[shapeVal]->shape;
277-
// convert shape to GEOS
277+
{
278+
// get current shape
279+
CComPtr<IShape> shape = nullptr;
280+
get_Shape(shapeVal, &shape);
281+
// convert shape to GEOS
278282
GEOSGeom geos = GeosConverter::ShapeToGeom(shape);
279283
// see if shape intersects polygon extent
280284
if (GeosHelper::Intersects(geosExtent, geos))

src/ComHelpers/ShapefileHelper.cpp

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,78 @@ bool ShapefileHelper::GetClosestPoint(IShapefile* sf, double x, double y, double
382382
shp->Release();
383383
}
384384
}
385-
// dist = minDist;
385+
dist = minDist;
386386
return minDist < maxDistance;
387387
}
388388

389+
// *****************************************************************
390+
// GetClosestSnapPosition()
391+
// *****************************************************************
392+
bool ShapefileHelper::GetClosestSnapPosition(IShapefile* sf, double x, double y, double maxDistance, std::vector<long>& ids,
393+
long* shapeIndex, double& fx, double& fy, double& dist)
394+
{
395+
if (!sf) return false;
396+
397+
VARIANT_BOOL vb;
398+
double minDist = DBL_MAX;
399+
400+
IPoint* pnt = NULL;
401+
IShape* ptShp = NULL;
402+
IShape* resShp = NULL;
403+
404+
for (long id : ids)
405+
{
406+
VARIANT_BOOL visible;
407+
sf->get_ShapeVisible(id, &visible);
408+
if (visible == VARIANT_FALSE) continue;
409+
410+
IShape* shp = NULL;
411+
sf->get_Shape(id, &shp);
412+
413+
if (shp != NULL)
414+
{
415+
// Create point shape
416+
ComHelper::CreateShape(&ptShp);
417+
ptShp->Create(SHP_POINT, &vb);
418+
if (vb != VARIANT_TRUE)
419+
{
420+
shp->Release();
421+
pnt->Release();
422+
continue;
423+
}
424+
425+
// Add point
426+
ComHelper::CreatePoint(&pnt);
427+
pnt->put_X(x);
428+
pnt->put_Y(y);
429+
long position = 0;
430+
ptShp->InsertPoint(pnt, &position, &vb);
431+
pnt->Release();
432+
433+
// Get closest points:
434+
shp->ClosestPoints(ptShp , &resShp);
435+
ptShp->Release();
436+
shp->Release();
437+
438+
if (resShp != NULL) {
439+
// Get the point snapped on geometry
440+
double xPnt, yPnt;
441+
resShp->get_XY(0, &xPnt, &yPnt, &vb);
442+
443+
// Check if this is allowed and/or smaller than the previous found point:
444+
const double distance = sqrt(pow(x - xPnt, 2.0) + pow(y - yPnt, 2.0));
445+
if (distance < minDist && distance < maxDistance) {
446+
fx = xPnt;
447+
fy = yPnt;
448+
minDist = distance;
449+
}
450+
}
451+
}
452+
}
453+
dist = minDist;
454+
return minDist < maxDistance;
455+
}
456+
389457
// ********************************************************************
390458
// PointInPolygon()
391459
// ********************************************************************

src/ComHelpers/ShapefileHelper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class ShapefileHelper
2020
static IShapefile* CloneSelection(IShapefile* sf);
2121
static bool ShapeSelected(IShapefile* sf, int shapeIndex);
2222
static bool GetClosestPoint(IShapefile* sf, double x, double y, double maxDistance, std::vector<long>& ids, long* shapeIndex, long* pointIndex, double& dist);
23+
static bool GetClosestSnapPosition(IShapefile * sf, double x, double y, double maxDistance, std::vector<long>& ids, long * shapeIndex, double& fx, double& fy, double & dist);
2324
static bool PointInPolygon(IShapefile* sf, long ShapeIndex, double x, double y);
2425
static bool BoundsWithinPolygon(IShapefile* sf, int shapeIndex, double b_minX, double b_minY, double b_maxX, double b_maxY);
2526
static bool ShapeTypeIsM(IShapefile* sf);

0 commit comments

Comments
 (0)