Bridge? A common design pattern in GIS Secondary Development

Source: Internet
Author: User
Problem cause

Many simple operations are often required in the second GIS development.Code, To a general scale, to a custom tool (usertools) similar to MapX, or some analysis functions in Supermap object. These functions are implemented inProgramDifferent processes and events, not only every time the writing is troublesome, but also difficult to maintain. In the article "Designing reusable large-granularity GIS components using Visual Basic's event mechanism", the author puts forward the use of the delegate mode (not. and event mechanisms. These functions are designed as an independent user control or class module, this article uses the custom tool of MapX as an example to illustrate this problem.

General Solution

In MapX, you can use custom tools to complete some functions that are not provided by the control itself, such as distance measurement. To customize a tool, you must first call the createcustomtool method of MapX, and then write some processing code in different MapX events to complete this work, such as distance measurement, you can customize a line tool:

Map1.createcustomtool rulertoolid, mitooltypeline, misizeallcursor

Then, write the Variable Distance code in the mousemove event:

If Button = 1 and map1.currenttool = rulertoolid then
Dim X2 as double
Dim Y2 as double
Map1.convertcoord X, Y, X2, Y2, miscreentomap
Sbstatusbar. simpletext = map1.distance (mousedownx1, mousedowny1, X2, Y2)
End if

Finally, write the final distance code in the toolused event:

If toolnum = rulertoolid then
Sbstatusbar. simpletext = ""
Msgbox "distance:" & map1.distance (x1, Y1, X2, Y2)
End if

Design a class module

There is no problem in doing so. The problem is that if there are many business-related map interaction codes, they must also be written here. For example, after you click a fixed point on the map, a dialog box is displayed, enter the corresponding information such as this code, then the code becomes a long if... It is inconvenient to modify and maintain the sequence of elseif statements. The following uses distance measurement as an example to describe how to use the delegate method to separate the code into a class module. The idea is the same as that in the article "Designing reusable large-granularity GIS components using Visual Basic's event mechanism.

First, you need to define the required variables, objects, and events. You need to use withevents to define a MapX object to respond to its events, and then define a connect method to pass the object instance to this object, and perform necessary initialization. The Code is as follows:

Private const m_rulertoolid = 104.
Private withevents m_mapx as mapxlib. Map

Public event polyrulertooldistancechanged (distance as double)
Public event polyrulertoolused (distance as double)

Public property get rulertoolid () as long
Rulertoolid = m_rulertoolid
End Property

Public Function connect (MapX as mapxlib. Map) as Boolean
If MapX is nothing then
Connect = false
Else
Set m_mapx = Mapx
M_mapx.createcustomtool m_rulertoolid, mitooltypeline, misizeallcursor
End if
End Function

Then, when processing specific operations, such as drawing a line, move the mouse to change the current distance and the final distance:

private sub m_mapx_mousemove (button as integer, shift as integer, X as single, y as Single)
If Button = 1 and m_mapx.currenttool = m_rulertoolid then
dim X2 as double
dim Y2 as double
dim DIS as double
m_mapx.convertcoord X, y, X2, Y2, miscreentomap
Dis = m_mapx.distance (m_x1, m_y1, X2, Y2)
raiseevent rulertooldistancechanged (DIS)
end if
end sub

Private sub m_mapx_toolused (byval toolnum as integer, byval X1 as double, byval Y1 as double, byval X2 as double, byval Y2 as double, byval distance as double, byval shift as Boolean, byval CTRL as Boolean, enabledefault as Boolean)
If toolnum = m_rulertoolid then
Raiseevent rulertoolused (m_mapx.distance (x1, Y1, X2, Y2 ))
End if
End sub

Class module usage

This completes the design of a class module of the custom tool. The module uses the following:

Definition: Private withevents rulertool as mapxrulertool

Instantiate in form_load:
Set rulertool = new mapxrulertool
Rulertool. Connect me. Mapx

Handle the event:
Private sub rulertool_rulertooldistancechanged (distance as double)
Frmmain. commandbars. statusbar. idletext = distance
End sub

Private sub rulertool_rulertoolused (distance as double)
Msgbox distance
End sub

Summary

This method is similar to the thinking and bridge modes, but bridge separates implementation, and there are some differences. The event mechanism itself is an observer, so simply put, the use of the delegate mechanism may be more similar, you are welcome to criticize and correct it to improve our design level.

The Code itself uses VB 6, but it should be similar to other versions and languages. In these days, the project is used, so the code in this article uses VB.

Appendix: VB 2005 code and UML diagram

Class UML diagram:

Code:
Public class mapxrulertool

Private const _ rulertoolid as integer = 104.
Private const _ polyrulertoolid as integer = 105

Private withevents _ MapX as axmapxlib. axmap

Private _ X1 as double
Private _ Y1 as double

Public event rulertooldistancechanged (byval distance as double)
Public event rulertoolused (byval distance as double)
Public event polyrulertooldistancechanged (byval distance as double)
Public event polyrulertoolused (byval distance as double)

Public readonly property rulertoolid () as mapxlib. toolconstants
Get
Rulertoolid = ctype (_ rulertoolid, mapxlib. toolconstants)
End get
End Property

Public readonly property polyrulertoolid () as mapxlib. toolconstants
Get
Polyrulertoolid = ctype (_ polyrulertoolid, mapxlib. toolconstants)
End get
End Property

Public Function connect (byval MapX as axmapxlib. axmap) as Boolean
If MapX is nothing then
Connect = false
Else
_ MapX = Mapx
_ MapX. createcustomtool (_ rulertoolid, mapxlib. tooltypeconstants. mitooltypeline ,_
Mapxlib. cursorconstants. misizeallcursor)
_ MapX. createcustomtool (_ polyrulertoolid, mapxlib. tooltypeconstants. mitooltypepoly ,_
Mapxlib. cursorconstants. misizeallcursor)
End if
End Function

private sub _ mapx_mousedownevent (byval sender as object, byval e as axmapxlib. cmapxevents_mousedownevent) handles _ MapX. mousedownevent
If e. button = 1 and _ MapX. currenttool = _ rulertoolid then
'Place the current screen coordinates in mousedownx1 and mousedowny1
'since these points will be used in the map. distance call, they
'must be in map coordinates, not screen coordinates
_ MapX. convertcoord (E. x, E. y, _ X1, _ Y1, mapxlib. conversionconstants. miscreentomap)
end if
end sub

private sub _ mapx_mousemoveevent (byval sender as object, byval e as axmapxlib. cmapxevents_mousemoveevent) handles _ MapX. mousemoveevent
If e. button = 1 and _ MapX. currenttool = _ rulertoolid then
dim X2 as double
dim Y2 as double
dim DIS as double
_ MapX. convertcoord (E. x, E. y, X2, Y2, mapxlib. conversionconstants. miscreentomap)
Dis = _ MapX. distance (_ X1, _ Y1, X2, Y2)
raiseevent rulertooldistancechanged (DIS)
end if
end sub

Private sub _ mapx_polytoolused (byval sender as object, byval e as axmapxlib. cmapxevents_polytoolusedevent) handles _ MapX. polytoolused
If E. toolnum = _ polyrulertoolid then
Dim I as integer
Dim distancesofar as double

Distancesofar = 0.0 #

Dim mpoints as new mapxlib. Points
Mpoints = ctype (E. Points, mapxlib. Points)

'Find the total distance by adding up each of the Line Segment distances
If mpoints. Count> 1 then
For I = 2 to mpoints. Count
Distancesofar = distancesofar ++ _
_ MapX. Distance (mpoints. Item (I). X, mpoints. Item (I). Y ,_
Mpoints. Item (I-1). X, mpoints. Item (I-1). Y)
Next
End if

'Now, we have the total distance along the polyline
'If the user is done with the poly-rstance tool, show this distance
'In a message box. Otherwise, just show it in the status bar.
If E. Flags = mapxlib. polytoolflagconstants. mipolympus toolend then
Raiseevent polyrulertoolused (distancesofar)
Else
Raiseevent polyrulertooldistancechanged (distancesofar)
End if
End if
End sub

Private sub _ mapx_toolused (byval sender as object, byval e as axmapxlib. cmapxevents_toolusedevent) handles _ MapX. toolused
If E. toolnum = _ rulertoolid then
Raiseevent rulertoolused (_ MapX. Distance (E. X1, E. Y1, E. X2, E. Y2 ))
End if
End sub
End Class

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.