cmSelectByPolygon and cmSelection


cmSelectByPolygon - I have got this working where I can put a polygon around a whole lot of points and then get the data for these points. I was just wondering if there is a way to just loop through the selected points, instead of looping through all the points in the shapefile and testing if it is selected.
For i = 0 To sf.NumShapes - 1
If sf.ShapeSelected(i) = True Then
------Get data from shape
I originally tried to loop through using sf.NumSelected, but the shape index references the shapes in the shapefile and not the selected shapes.
Is there something similar to smSelection and then using SelectByShapeFile and then setting parameter ‘selected only’ to true.
If shpAccidents.SelectByShapefile(shpAreas, tkSpatialRelation.srIntersects, True, selectedShapes) = True Then

cmSelection - I have managed to get all points within a polygon shape by using cmSelection and the above code, but I am struggling to get the points on or very near a line shape. I have tried the following

  1. Putting a buffer around the line to try and get points that are just off the line
    Set sfBuffer = sf.BufferByDistance(100, 1, True, True)
    If shpAccidents.SelectByShapefile(sfBuffer, tkSpatialRelation.srIntersects, True, selectedShapes) = True Then —
  2. If shpAccidents.GetRelatedShapes2(sf.Shape(i), srIntersects, selectedShapes) = True Then —
  3. I thought of using SelectShapes by using extents with the line shape, but I am not sure if this is the correct way to do this.

I would appreciate any input on what is the best way to do this. In MapObjects, I put a buffer around the line and used this to search for any points within this buffer


Colleen Crawford

Hi colleen,

i’m not shure, if i can give you the best answer to your question, but at least one, that worked for me:

Your SelectByShapefile-Method has a parameter [result], in your case named “selectedShapes”, and this gets the indices of the to be selected records of your shapefile:

Here an example for a select-By-BoundingBox, that also has a [result]-Parameter,
here named “varResult”, - declared as:

Dim varResult as variant

'Remove any existing selection in your shapefile

'Get the shapes that are completely contained in the bounding box in the result array
If sfTemp.SelectShapes(extTemp, 0#, MapWinGIS.SelectMode.INTERSECTION, varResult) Then

    If IsArray(varResult) Then
        lngResult_Start = LBound(varResult)
        lngResult_End = UBound(varResult)
        For lngResult_Counter = lngResult_Start To lngResult_End
           'Here is the line, where you actually make your features selected
          'only needed if you want to see that selected set in your map
           'to just access one of the selected shapes use:  sfTemp.Shape(varResult(lngResult_Counter))
            sfTemp.ShapeSelected(varResult(lngResult_Counter)) = True
    End If
End If


So with the indices contained in that result-array you can limit your search in your shapefile.


Just to add to what Stefan had to say, in answer to the first part of your question; unfortunately, there is no other way to get the ‘selected’ shapes (those selected with the cmSelection tools). Even when calling NumSelected, internally, the library iterates the entire list and counts the ‘selected’ shapes.

I’ve always wondered why the Identify tool returns the ISelectionList object, but the Selection tool does not. Maybe I’ll make that an enhancement someday.

Also, I think that buffering the line shape is the right way to go to get the point features within the buffer distance. You might consider buffering just the line in question, returning a polygon; and using the polygon in a GetRelatedShapes2 call. The trick sometimes is setting the best buffer size to accomplish your purposes. (Hint: the second parameter of the Buffer call is best set to 16).

Hope that helps.

Thanks for the answers. I am doing the buffer as you suggested as follows

Set shapeBuffer = sf.Shape(i).Buffer(100, 16) - I also tried 10 000,16 to make a huge buffer
If shpAccidents.GetRelatedShapes2(shapeBuffer, tkSpatialRelation.srOverlaps, selectedShapes) = True Then — - Have tried overlaps, intersects, contains

Still returning false
I think the error has something to do with projection, as I get the following error - Latitude or Longitude exceeded limits when I load the accidents
I have noticed that the X/Y Coords that are displayed on the map change when I load the accidents and other layers. I think I may have caused this as it seems to only be the OGR Layers where I used the x/y coords to create a geometry shape in sql. I used this code
USE AccidentSuite

Update LocationInfo Set LocnPtShape = geometry::STPointFromText(‘POINT(’+ str([x_Coord]) + ’ ’ + str([y_Coord]) + ‘)’, 32735)

I found in some other info that I had that our srid is 32735

Our projection info is as follows


When I display the GeoProjection.ProjectName for the Accidents shape file I get WGS 84/UTM zone 355

I don’t really understand all of this but am surprised how I can find the accident shapes within a polygon, but the Buffer Line finds no accident points. Also the accident points are appearing on the Roads where I expect them.

Please could you let me know if you can figure out what is going on.


Colleen Crawford

Maybe you can share some records or especially the affected ones with this forum. Without the data it’s mostly guesswork.
I would guess, that the projections/srs of the two affected shapefiles do not match. To find features in one layer with a feature from another, they need to be in the same crs.
So maybe a simple:

set myNewLineShapeFileVar = myLineShapeFileVar.Reproject(myPointShapeFileVar.Geoprojection, lngReprojectedFeatures)

and then take the new myNewLineShapeFileVar to create the buffer for selecting points.

It should also work the other way around.
But as i wrote, it’s only guesswork.


I am not sure how I would get records to you as they are on an SQL table.

I have managed to sort the projection problem out, I think, with the following

Map1.Projection = tkMapProjection.PROJECTION_NONE
Map1.GeoProjection = shpOpEntity.GeoProjection.Clone
Map1.GrabProjectionFromData = False ’ As soon as I set this to True the projection did not change as required

’ these are important for mismatched projections
Dim gs As GlobalSettings
Set gs = New GlobalSettings
gs.AllowProjectionMismatch = True
gs.ReprojectLayersOnAdding = True

However, the GetSelectedShape2 still returns no points

Set shapeBuffer = sf.Shape(i).Buffer(10, 16)
If shpAccidents.GetRelatedShapes2(shapeBuffer, tkSpatialRelation.srIntersects, selectedShapes) = True Then ----

However if I do the following it does return points

Set ext = shapeBuffer.extents
If shpAccidents.SelectShapes(ext, 0, SelectMode.INTERSECTION, selectedShapes) = True Then ----

I think the extents sets a rectangle so when the road runs diagonally, it gets points on a whole lot of other roads, when I want the points only on the selected Road.


Colleen Crawford

Hi Colleen,

It’s about the data, that you are processing, not the display of the data in the map.
To compare a buffer object with points from a layer, the buffer object itself must be in the same projection/crs as the target objects.
So reproject the data of one shapefile into the same geoprojection as the other one, then create the buffer and then do the intersection.