PDA

View Full Version : Highlight multiple pushpins inside shape



Brian
08-10-2011, 02:28 PM
MP2009 (but could upgrade to 2010/2011 if either provides the feature described below)

I have a VBA (MS Access) application that sends addresses to the map as pushpins. The user then draws a shape around a group of pushpins, right-clicks the shape, clicks Add Pushpins as Stops, then routes the points. The updated stop order is then used to update the stop order in a table in my database.

This works fine for the portion of my application that actually requires routing; however, another portion of my application is there just to allow the user to group items (no stop numbers required). There is no pressing reason to even create waypoints except that I cannot find any other way to identify which points are inside the shape. Is there a way to identify or highlight all pushpins inside a shape without going through the gyrations of adding irrelevant stops?

Mattys Consulting
08-10-2011, 07:18 PM
This code is taken from the help file ...
I am modifying it here for your question:


Sub QueryRecordsInShapeAtCenterOfMap()
Dim objApp As New MapPoint.Application
Dim objMap As MapPoint.Map
Dim objDataSet As MapPoint.DataSet
Dim objRecords As MapPoint.Recordset
Dim objshape As MapPoint.Shape

Dim lngCount As Long

'Set up application and objects to use
objApp.Visible = True
objApp.UserControl = True
Set objMap = objApp.ActiveMap
Set objshape = objMap.Shapes.AddShape( _
geoShapeOval, objMap.Location, 2000, 1000)
lngCount = 0

Set objDataSet = objMap.DataSets(1)
'Find records in shape
objshape.Select
Set objRecords = objDataSet.QueryShape(objshape)
objRecords.MoveFirst
Do While Not objRecords.EOF
lngCount = lngCount + 1
If objRecords(lngCount).IsMatched Then
objRecords(lngCount).PushPin.Symbol = 25
End If
objRecords.MoveNext
Loop
MsgBox "Number of records in shape: " & lngCount
End Sub

I think that's it! :gunsmilie:

Brian
08-11-2011, 11:14 AM
Thank you for your response. I considered going with VBA similar to this but was hoping first to find a graphical, on-the-map, user-interactive method for getting the highlights done.

I already know how to query a shape for the pushpins within it and even highlight all of them--programmatically. But these are user-drawn shapes, not code-generated shapes. With multiple shapes on the screen, each containing pushpins, how can the user indicate which of the shapes it to be included in the current operation?

My existing code works OK, but the extra overhead (and thus processing time) of working with waypoints instead of pushpins is unnecessary for an operation where the order of points is irrelevant.

Eric Frost
08-11-2011, 11:46 AM
Hi Brian,

You could have the user draw the shape.

Then the user could make sure the shape is selected, and then click a button in your application (whether it's a MapPoint add-in or Excel macro or whatever).

Then your macro could loop through and change the symbol for all the pushpins within the polygon and/or move them to a new dataset.

Moving them to a new dataset also gives you the benefit of having them as a separate layer in the Legend which can be hidden, copy/pasted to other maps, etc.

hope this helps!

Eric

Mattys Consulting
08-11-2011, 11:46 AM
Is your topic actually 'highlight multiple pins in multiple shapes at the same time' then?
Use your existing routines with a form and listboxes having multiple selection or checkboxes.
Then you can allow user-selection of shapes in the first listbox and user-selection of pins in the second listbox.
Make it a COM Addin.

Eric Frost
08-11-2011, 11:51 AM
With multiple shapes on the screen, each containing pushpins, how can the user indicate which of the shapes is to be included in the current operation?

Only one polygon can be selected at a time, but you could maybe loop over and do all polygons on the map?

Otherwise, one way to indicate which ones are to be processed is maybe have the user make the lines red or something, then your code could test for that.

Eric

Brian
08-11-2011, 02:17 PM
Mattys Consulting: Is there then a way to identify visually on the map which shape is identified as which in a programmatic enumeration of the shapes collection? That is, how would the user know which shape he is selecting from a list box? the help file says this, "Shape names are used for automation only". I can see no property of the Shape object that can be displayed on the map to discriminate between shapes. I thought of using the Text propery; however, that requries the shape to be a rectangle, and the typical shape used in this application is a freehand closed shape.

Currently, the user interface is as simple as I think possible: the user draws one or more shapes, right-clicks one, then clicks Add Pushpins as Stops. He can draw as many shapes as he wants and keep adding Pushpins as stops. When done, he clicks a single button click in my application to update all associated records in my DB and remove all currently-selected points from the map so that he can continue to update batches of remaining points.

The only problem is some of the processing overhead in having to use waypoints as a stepping stone to getting points selected when I could just update all highlighted points if there were a simple single step to getting all points highlighted inside a shape by user interaction on the map (e.g. Highlight All Pushpins Within This Shape when right-clicking a shape).

Just for the record in case someone else is trying to do the same thing (and pardon my verbosity here), below is a synopsis of the process I currently use when routing:


The user selects all or some subset of records to send to MapPoint. There may be 2000 pushpins or more.
The user draws any kind of shape around any subset of pushpins.
The user right-clicks the shape, then Add Pushpins as Stops.
The user continues drawing more shapes and adding the pushpins inside as stops. He may also add a single pushpin outside a shape as a stop.
When he has selected all points to be affected by the data operation, he optimizes, then clicks a single button in my application.
My application now does this:


Loops through the waypoints collection, comparing the location of each waypoint to the location of each pushpin. The pushpin is highlighted for each match, since it is the pushpin, not the waypoint, that contains the information correlating it to the field in my DB.
Loops through all highlighted pushpins, updating the DB for each point.
Loops through the shapes collection to determine which shapes contain highlighted pushpins, then deletes those shapes.
Deletes all waypoints.
Loops through the pushpins collection, deleting any whose Highlighted property is True.
Notifies the user how many points are left on the map to be assigned in the next batch. If there are no points left on the map, closes the map automatically.
This all works perfectly for grouping and routing stops from a single map instance. My current question was in regard to the fact that, because the optimization & stop order in #5 above is not necessary when grouping without ordering, much of the code looping through the records is unnecessary. Still, we are talking about perhaps 15 seconds here, much less than might be required of the user to navigate back and forth between my application and mappoint to do one shape at a time.

Eric: Yes...I could just have the regrouping portion of my application infer that all points inside all shapes are to be affected; however, that is a departure from the routing portion of my code and may confuse users.

I guess my main point has been reduced to this: I wish there was a feature in MapPoint that would allow me to select pushpins in a shape (by highlighting them) the same way I can assign waypoints. Maybe in some future release; still, if I am the only developer that has ever wished for it, I am not likely to get much consideration from the MS developers...:balloon2:

Mattys Consulting
08-11-2011, 02:36 PM
"Mattys Consulting: Is there then a way to identify visually on the map which shape is identified as which in a programmatic enumeration of the shapes collection?"

The current selection will have the "grab-handles."

Dim oShp As MapPoint.Shape
Dim FlashCount As Integer

For each oShp in oMap.Shapes
oShp.Select
OldColor = oShp.Fill.ForeColor
OldZorder = oShp.ZOrderPosition
oShp.ZOrder geoBringToFront
For FlashCount = 1 To 5
oShp.Fill.ForeColor = mpWhite
Sleep 30
oShp.Fill.ForeColor = OldColor
Next
Next

Eric Frost
08-11-2011, 03:38 PM
Also, there's a Name property of the shapes that is not actually exposed in the regular interface, but you could code something to let people access it. This is also accomplished by the free Shape Name Utility from Richard Marsden (Mapping-Tools.com), google it.

Eric

Brian
08-12-2011, 12:44 PM
Based on your input, I opted to change my approach for this grouping function and just use the content of (i.e. pushpins within) the shapes themselves rather than attempt to highlight pushpins within shapes. Since it is a grouping function only, not a routing function, there is no pressing need to set waypoints or even highlight pushpins. I simply include all points inside all shapes on the map as the current set of selected pushpins and by looping through the recordset of pushpins within each shape can easily notify the user how many points are selected.

Thank you all.

Eric Frost
08-12-2011, 09:07 PM
Great! Let us know if you have any other thoughts or ideas pertaining to this!

Eric