You are on page 1of 85

1of85

DevelopersCorner

Harold(Ted)DunsfordJr.
MarkVanOrden
JiKadlec

October2009

2of85
TableofContents
TableofContents ______________________________________________________________2
1. DevelopersCorner __________________________________________________3
1.1. GeometryCheatSheet___________________________________________4
1.1.1. OverlayOperations:________________________________________________________ 8
1.2. Exercise1:AssembleaMapProject _______________________________10
1.2.1. Step1:StartaNewC#Application____________________________________________ 10
1.2.2. Step2:AddMapWindowComponents________________________________________ 11
1.2.3. Step3:AddMenuandStatusStrips___________________________________________ 13
1.2.4. Step4:AddtheMap_______________________________________________________ 15
1.2.5. Step5:AddtheLegendandToolbox__________________________________________ 16
1.2.6. Step6:LinkItAllTogether__________________________________________________ 18
1.3. Exercise2:SimplifyAustraliaDataLayers __________________________21
1.3.1. Step1:DownloadData_____________________________________________________ 21
1.3.2. Step2:CalculatePolygonAreas______________________________________________ 21
1.3.3. Step3:ComputeCentroids _________________________________________________ 23
1.3.4. Step4:SubsamplebyAttributes_____________________________________________ 24
1.3.5. Step5:ExportLayertoaFile ________________________________________________ 25
1.3.6. Step6:RepeatwithRoadsLayer _____________________________________________ 25
1.3.7. Step7:SelectPoliticalBoundsbyClicking______________________________________ 26
1.3.8. Step8:ApplyLabeling _____________________________________________________ 27
1.4. ProgrammaticPointSymbology __________________________________29
1.4.1. AddaPointLayer_________________________________________________________ 29
1.4.2. SimpleSymbols___________________________________________________________ 32
1.4.3. CharacterSymbols ________________________________________________________ 33
1.4.4. ImageSymbols ___________________________________________________________ 37
1.4.5. PointCategories__________________________________________________________ 40
1.4.6. CompoundSymbols _______________________________________________________ 44
1.5. ProgrammaticLineSymbology ___________________________________46
1.5.1. AddingLineLayers ________________________________________________________ 46
1.5.2. OutlinedSymbols_________________________________________________________ 47
1.5.3. UniqueValues____________________________________________________________ 48
1.5.4. CustomCategories________________________________________________________ 49
1.5.5. CompoundLines__________________________________________________________ 50
1.5.6. LineDecorations__________________________________________________________ 53
1.6. ProgrammaticPolygonSymbology________________________________54
1.6.1. AddPolygonLayers _______________________________________________________ 54
1.6.2. SimplePatterns___________________________________________________________ 55
1.6.3. Gradients _______________________________________________________________ 56
1.6.4. IndividualGradients_______________________________________________________ 57
1.6.5. MultiColoredGradients____________________________________________________ 58
1.6.6. CustomPolygonCategories_________________________________________________ 60
1.6.7. CompoundPatterns_______________________________________________________ 61
1.7. ProgrammaticLabels ___________________________________________62
1.7.1. FieldNameExpressions ____________________________________________________ 63
3of85
1.7.2. MultiLineLabels _________________________________________________________ 64
1.7.3. TranslucentLabels ________________________________________________________ 65
1.8. ProgrammaticRasterSymbology _________________________________66
1.8.1. DownloadData___________________________________________________________ 67
1.8.2. AddaRasterLayer ________________________________________________________ 69
1.8.3. ControlCategoryRange____________________________________________________ 73
1.8.4. ShadedRelief ____________________________________________________________ 74
1.8.5. PredefinedSchemes_______________________________________________________ 75
1.8.6. EditRasterValues_________________________________________________________ 76
1.8.7. QuantileBreaks __________________________________________________________ 78
1.9. MapWindow4ConversionTips___________________________________80
1.9.1. Point___________________________________________________________________ 80
1.9.2. Extents _________________________________________________________________ 80
1.9.3. Shape __________________________________________________________________ 81
1.9.4. Shapefile________________________________________________________________ 82
1.9.5. Grid____________________________________________________________________ 83
1.9.6. GridHeader______________________________________________________________ 84
1.9.7. Image __________________________________________________________________ 84
1.10. ExtensionMethods ____________________________________________85

1. DevelopersCorner
This section gives a bit of an overview of geometric relationships, which are important for
understanding some of the vector analysis options, and then gives some workable exercises to
demonstratethecurrentcapabilitiesofMapWindow6.0.Thisshouldbethoughtofasakindof
developers preview, and not necessarily a comprehensive developers guide, which will be
made available before the MapWindow conference in Orlando in 2010. This part of the
documentcoversusingMapWindowcomponents,stitchingtogetheraworkingGISbydragging
the important components from the toolbox in visual studio, and then gives a detailed
description of how to programmatically add layers and work with symbology or complex
symbolicschemes.
Ahugefocusforthe.NetversionofMapWindowistoputmuchmorecontrolintothehandsof
developers. Byprovidingeverythingintheformof.Netcomponents,itmakesitfarsimplerto
pick and choose what sections of the framework you want to work with. If the map is all you
need, you dont need to bother adding the legend or our custom status strip or the toolstrip.
However, those components are provided for you so that it you can stitch together a working
GISwithoutwritingasinglelineofcode.
4of85
1.1. GeometryCheatSheet
In addition to organizing coordinates for drawing, the geometry classes provide a basic
framework for testing topological relationships. These are spatial relationships that are
principally concerned with testing how to shapes come together, for instance whether two
shapesintersect,overlap,orsimplytouch.Theserelationshipswillnotchangeevenifthespace
is subjected to continuous deformations. Examples include stretching or warping, but not
tearingorgluing.
Theteststocomparetwoseparatefeatureslookattheinterior,boundary,andexteriorofboth
features that are being compared. The various combinations form a matrix illustrated in the
figurebelow.Itshouldbeapparentthatnotonlyaretheintersectionspossible,buteachregion
willhaveadifferentdimensionality.Apointisrepresentedasa0dimensionalobject,alineby1
dimension and an area by 2. If the test is not specific to what dimension, it can represent any
dimensionasTrue.Likewise,ifitisrequiredthatthesetisempty,thenFalseisused.
Interior Boundary Exterior
Interior
Boundary
Exterior

Figure1:IntersectionMatrix
Graphically,weareillustratingtheintersectionmatrixfortwopolygons.Sometestscan
berepresentedbyasinglesuchmatrix,orasingletest.Othersrequireacombinationofseveral
testsinordertofullyevaluatetherelationship.Whenthematrixisrepresentedinstringform,
the values are simply listed in sequence as you would read the values from the top left row,
throughthetoprowandthenrepeatingforthemiddleandbottomrows.Thefollowingareall
possiblevaluesinthematrix:
T:Valuemustbetruenonemptybutsupportsanydimensions>=0
F:Valuemustbefalseemptydimensions<0
*:Dontcarewhatthevalueis
5of85
0:Exactlyzerodimensions
1:Exactly1dimension
2:Exactly2dimensions
The following is a visual representation of the test or tests required in each case. A red X
indicatesthatthetestinthoseboundariesmustbefalse.Acoloredvaluerequiresthatthetest
betrue,butdoesntspecifyadimension.Agrayvalueindicatesthatthetestdoesntcareabout
thevalueofthatcell.
Contains:
o Every point of the other geometry is a point of this geometry, and the
interiorsofthetwogeometrieshaveatleastonepointincommon.
o T*****FF*
o
I B E
I
B
E

CoveredBy:
o Everypointofthisgeometryisapointoftheothergeometry.
o T*F**F***,*TF**F***,**T*F***or**F*TF***
o
I B E
I
B
E
,
I B E
I
B
E
,
I B E
I
B
E
,or
I B E
I
B
E

Covers:
o Everypointoftheothergeometryisapointofthisgeometry.
o T*****FF*or*T****FF*or****T*FF*
o
I B E
I
B
E
,
I B E
I
B
E
,or
I B E
I
B
E

6of85

Crosses:
o Geometrieshavesomebutnotallinteriorpointsincommon.
o T*T*****(forPoint/Line,Point/Area,Line/Area)
o
I B E
I
B
E

o T*****T**(forLine/Point,Line/Area,Area/Line)
o
I B E
I
B
E

o 0********(forLine/LineSituations)
o
I B E
I
B
E
0

Disjoint:
o Thetwogeometrieshavenopointincommon.
o FF*FF****
o
I B E
I
B
E

Intersects:NOTDisjoint
o Thetwogeometrieshaveatleastonepointincommon.

7of85
Overlaps:
o Thegeometrieshavesomebutnotallpointsincommon,theyhavethe
same dimension, and the intersection of the interiors of the two
geometrieshasthesamedimensionasthegeometriesthemselves.
o T*T***T**(forPoint/PointorArea/Area)
o
I B E
I
B
E

o 1*T***T**(forLine/Line)
o
I B E
I
B
E
1

Touches:
o The two geometries have at least one point in common but their
interiorsdonotintersect.
o FT*******,F**T*****,orF***T****
o
I B E
I
B
E
,
I B E
I
B
E
,or
I B E
I
B
E

Within:
o Every point of this geometry is a point of the other geometry and the
interiorsofthetwogeometrieshaveatleastonepointincommon.
o T*F**F***
o
I B E
I
B
E

8of85
1.1.1. OverlayOperations:
Being able to test the existing relationships between geometries is extremely useful for doing
analysis,butmanytimesyouneedtoalterthegeometriesthemselves.Frequentlyyouwantto
useothergeometriestoaccomplishthis.Considerthecaseofaclippingoperation.Inthefigure
below, the rivers extend beyond the boundaries of the state of Texas. Using an overlay
operationisexactlythekindofoperationthathelpswiththiskindofcalculation.Thesearenot
limitedtospecificscenarioslikepolygontopolygon.Insteadthesameterminologyappliestoall
thegeometriesusingthefollowingdefinitions.

Figure2:BeforeandAfterClippingRiverstoTexas

Difference:
o ComputesaGeometryrepresentingthepointsmakingupthisgeometry
thatdonotmakeuptheothergeometry.
o

9of85
Intersection:
o Computes a geometry representing the points shared by this geometry
andtheothergeometry.
o
SymetricDifference:
o Computesageometryrepresentingthepointsinthisgeometrythatare
notpresentintheothergeometry,andthepointsintheothergeometry
thatarenotinthisgeometry.
o
Union:
o Computes a geometry representing all the points in this geometry and
theothergeometry.
o

10of85

1.2. Exercise1:AssembleaMapProject

Putting together a GIS project has never been easier. Even a novice developer can take
advantage of our readybuilt mapping controls, dragging and dropping them onto a solution.
Becausethecomponentsarelargelyindependent,theycanberearrangedindifferentlayouts,
or used separately. Furthermore, the extensive use of interfaces for the controls allows a
control like the map control to be used interchangeably with alternate controls that act like a
legend.
In this first exercise, we will take the assembly step by step. If you have never worked with
anything besides the built in .Net controls, this exercise will be useful because it will
demonstratehowtoaddtheMapWindowcomponentstoyourvisualstudiodevelopertoolbox.
It will also show the basic way that the most fundamental map controls can be added to the
map.

1.2.1. Step1:StartaNewC#Application
Thefirststepoftheexerciseistocreateabrandnewapplication.Ratherthanworkingwithan
existing application, the goal here is to show that getting from a blank project to a fully
operational GIS takes only a few minutes in order to add the components and link them
together.Inaddition,noprogrammingcodeisrequired.Togettonewprojectdialoginvisual
studio, simply navigate to File, New, and choose Project from the context menu. This will
displaytheNewProjectdialogdisplayedinfigure1.

Figure3:NewProjectDialog
11of85
Change the name and path to something appropriate. In this case, we chose Build_A_Map
andC:\dev\DotSpatialDev\Tutorial\Components\Ex1.Makesure thattheProject type isVisual
C#andWindows.EnsurethattheTemplateissettoWindowsFormsApplication.ThenclickOK.
1.2.2. Step2:AddMapWindowComponents
The first step in any project is to ensure that you have loaded all of the designer controls and
components into the MapWindow toolbar. As this tutorial was created in the alpha stage of
development you will notice that not all of the controls have unique representative icons or
otherhelpfulinstructions.Thereisalsoalargeassortmentofextracontrolsthatwereusedfor
designing MapWindow 6.0 that we may choose to remove from the toolbox for the public
release.Howeverthebasictechniquewillremainthesame.First,wewanttocreateanewtab
to store the MapWindow tools. You can do this by right clicking on the toolbox and selecting
theAddTaboptionfromthecontextmenu.

Figure4:AddMapWindowTab

This will allow you to edit the name of the tab. We chose to name the tab MapWindow so
that we could easily keep the controls from the MapWindow library together. Once you have
added a MapWindow tab, you will want to right click in the blank space below that tab and
selectChooseItemsfromthecontextmenu.
12of85

Figure5:ChooseItems
Thechooseitemsoptionlaunchesanewdialogwhichwillallowyoutoselectfromvariouspre
loaded .Net controls as well as some COM controls. However, we are going to use a third
option,andbrowsefortheDotSpatial.Desktop.dllfile.

Figure6:Browse

This, in turn, launches a file browser, and you will have to navigate to wherever the
DotSpatial.Desktop.dll file is found on your local machine. On this machine it was in the
C:\Dev_II\dotspatial\Releasefolder.

13of85

Figure7:SelectDotSpatial.dll

Onceyouhavechosenthisdocument,itwill
cause a large number of tools to be added
toyourtoolbox,asisillustratedinthefigure
totheright.

Figure8:MapWindowTools

1.2.3. Step3:AddMenuandStatusStrips
Addinga.NetMenuStripisafastwaytogiveaccesstoaveryversatilenumberoftools,options,
or other capabilities. This is not inany way required by the MapWindow GIS components, but
ratherissimplyaconvenientstartingpointforanewapplication.TheMenuStripisfoundunder
the All Windows Forms tab in the toolbox. Simply drag the MenuStrip listed there onto the
mainform.

14of85

Figure9:DragaMenuStrip

Next we will switch back to the MapWindow controls and add two controls that are directly
associated with the MapWindow components. The first is the SpatialToolStrip, which lists
severalbasicGISfunctionslikeaddingdatalayers,switchingbetweenzoomandpanmode,and
zoomingtothefullextent.ThesecondistheSpatialStatusStrip.

Figure10:AddStatusandToolStrips

15of85
1.2.4. Step4:AddtheMap
Now that the peripheral controls have been added, we can start adding the controls that will
workwithinthecentralpartofthemapproject.Inordertocleanlydivideup thescreenareas
with a minimum of custom programming, we will take advantage of a .Net SplitContainer
control.Thiswilldividethecontentintotwoseparatepanelsthataresizeablebytheuser.

Figure11:AddaSplitContainerControl

Figure12:AddaMap

16of85
Once the separate panels exist, we can add the map to the project. When adding the map, it
will likely be the wrong size for the panel that we created. In order to allowthe user to resize
the map so that it always is the right size for the panel, change the Dock property to Fill.
Thiscanbedonebychoosingthecentralrectangleinthedropdowneditorthatappearsinthe
propertygridwhenyouclickonthedownarrow.
1.2.5. Step5:AddtheLegendandToolbox
Because the Legend and Toolbox can both exist in support of the map, and it is not critical to
havebothofthesetoolsvisibleatthesametime,forthisprojectwewilltakeadvantageofthe
.NetTabcontroltohelpreusethesamespacemoreeffectively.Becausethesecomponentsare
interchangeable,theTab controlisnotnecessary,andsecondsplitpanel,fixedpanels,oreven
thirdpartydockingpanelsareallacceptablealternativesthatwillnotaffecttheproperbehavior
ofthemap,legendortoolbox.

Figure13:AddaTabControl

Inthisinstanceweaddedthetabcontroltotheleftpanel,andchangedthetextonthetwotabs
toreadLegendandToolbox.Thiscanbedonethroughthepropertygridthatappearswhenyou
activatethetabcontrolbyclickingonitafterithasbeenaddedtothemainform.

17of85

Figure14:AddLegend
Adding the legend follows similar rules to adding the map. You can simply drag this on top of
thetabcontrolwhentheLegendtabisselected.Thiswillautomaticallytellthedesignerthat
the legend control will only appear when the Legend tab is selected. Like the map, the legend
shouldhaveitsdockpropertysettofillinordertotakeadvantageofthesplittercontrolsability
toresizethelayout.

Figure15:AddaToolbox
Althoughwearenotgoingtoenablethetoolboxinthisexercise,itwouldbeagoodideatoadd
one. This will enable us to directly use our current project as the starting point for the next
exercise. To add the toolbox, simply switch the tab control to the Toolbox tab. Then, drag
anddroptheToolManager.Likethelegendandthemap,youwillwanttosetthedocktofull.
Once you have done this, select back to the Legend tab so that when the application starts it
defaultstoshowingthelegend,ratherthanthetoolbox.

18of85
1.2.6. Step6:LinkItAllTogether

We could technically run the project right


away, but it would not appear to do
anything.Theadddatabutton,forinstance
mighthappilyopenafiledialog,butnothing
would happen when it was finished. In
order for the status strip to show updates
from the map, and in order for the legend
to show the layers from the map, we need
to link things together. The map has a
property for the Legend and
ProgressHandler. Set these to legend1 and
mwStatusStrip1respectively.

Figure16:LinkMap

Figure17:LinkToolStrip
19of85

The next step is to link the tool strip to the map. This can be done by simply activating the
mwToolStrip, choosing the Map property and selecting map1. In order for the application to
understand what to do with the data, a system reference to the DotSpatial.Data.dll must be
made. This .dll is located in the same file as the DotSpatial.Desktop.dll that was reference to
access the GIS controls. Now that the project is connected together, we can start our project
andrunitonsometestdata.
Thefirstthingtodoistogetsomedata.Foroursample,almostanydatainshapefileformat
willdo,butinthespiritofimprovingonlinedataawareness,thisbookfeaturesmanyonlinedata
sourcesthatshouldprovideuptodateGISdata.
HelpTip
Sometimeslinkscanbecomebrokenoroutofdate.
Incaseslikethis,itisoftenusefultolookatthefirst
partoftheaddressandthensearchfordata
manually.Example:insteadof
http://www.census.gov/geo/cob/bdy/co/co00shp/c
o99_d00_shp.zip ,
youcoulduse
http://www.census.gov
?

Therawdatainthiscaseisstoredintheformofazipfile.Mostmodernoperatingsystemscan
unzip files automatically, but in the event that you need an unzip utility, a free, open source
utility called 7zip is available for download from http://www.7zip.org. Once you have
downloaded and extracted the shapefiles, you will see a .shp, a .shx and a .dbf file all with the
samenamebeforetheextension.ThisisthebasicfileformatknownasanESRIshapefile,andis
acommonlyusedformatforGISanalysisbecauseitisportableandhasanopenstandardandso
iswidelycompatiblebetweendifferentGISsoftwarevendors.

20of85

Figure18:CensusData

The figure above illustrates the view of the continental United States. Because the data also
includescountiesinHawaii,AlaskaandPuertoRico,itwillbenecessarytozoomalittletozeea
viewliketheoneabove.ThemapstartsautomaticallyinthePanmode.Inthismode,youcan
clickonthemapwithyourleftmousebuttonanddragthemapinadirectiontohaveitupdate
the view. You can also use the mouse wheel to zoom in or out of the scene. The basic
operationfollowstheoperationoftheUserssectionforMapWindow6.0,andsoyoucangeta
muchmoredetailedpictureofwhatispossiblewithyourmap.
21of85

1.3. Exercise2:SimplifyAustraliaDataLayers
1.3.1. Step1:DownloadData
Forthisexercise,weneedsomethematicvectorlayersthatrepresentmorethanjustpolygons.
In honor of the Sydney Free and Open Source Software for Geospatial (FOSS4G) 2009
Conference, for which this document is being written, I am downloading some basic Australian
datasets. Sometimes basic GIS data is offered on sites for free in the hopes of promoting the
datawithgreaterdetail.
http://www.usgsquads.com/prod_digital_international_vector_maps.htm
Forthisexercise,wedownloadedtheAUSCities,AUSLakes,AUSPolitical,AUSPopulatedAreas,
andAUSMajorTransportationshapefiles.Thesefilesarestoredinzipformat,soyouwillhave
to unzip them first (see exercise 1). I found that the cities shapefile in this example was
misleading because it does not contain any of the major populated city areas. Instead, before
wedoanyprogrammaticsymbolizing,wecangetbetterpointsthatareabetterrepresentation
of the cities from the polygons that are populated areas. To do this, you can use the
MapWindow6.0applicationtoconvertthepopulatedareaspolygonsintocities.
1.3.2. Step2:CalculatePolygonAreas

Figure19:AddData
After clicking the green plus to open a file dialog, browse for the
australia_populated_areas.shpshapefileyoujustdownloadedandextracted.Whenitopens,
you should see the polygons that represent large city areas, mostly at the outer limits of
Australia.Sincethepolygonsaresmallcomparedtothesizeoftheentirecontinent,wecansee
thatthecityregionsareinfactpolygonsbyzoomingintotheSydneyarea.
22of85

Figure20:SydneyPolygon

We will eventually like to be able to distinguish the largest cities. Because the downloaded
polygons dont contain any information about the population or area, we will use the area
calculationtooltocalculateareasforeachofthepolygons.Theunitsoftheareawillbelargely
meaningless because the linear units are in decimal degrees, but the values will be useful for
separating the larger cities from the small ones. To see the toolbox, simply change the tab to
theToolboxtab.

Figure21:CalculateAreas

HelpTip
Sincethisexercisewasconstructedusingapre
releaseversion,laterversionsmightnothavethe
samelayout.Viewingthetoolboxmightbean
optionmadeavailablethroughtheViewmenu,soif
thetoolboxtabisnotobvious,checktheviewmenu
foranoptionforaddingthetoolboxtab.
?

Theresultingshapefilehastobereaddedtothemap.Inthiscase,anewfieldhasbeenadded
to the resulting shapefile that shows the area. While this is not as useful as population for
selectinglargecities,itatleastshouldgiveusanothertooltoworkwith.
23of85

Figure22:NewlyAddedAreas

1.3.3. Step3:ComputeCentroids
Nowthatwehaveawaytoatleastorderthecitiesbywayofareas,wecannowcreate
asimplecitieslayerfromtheexistingpolygons.Wecandothisbyusingthecentroidtool.

Figure23:CalculateCentroid
Theshapefilecreatedbycalculatingthecentroidswillnowbeagoodrepresentationofthecity
locationsforbuiltupareas,andinaddition,itwillgiveusanapproximatemeasureofthesizeof
thebuiltupareausingtheareaattribute.
24of85

Figure24:TooManyCities
1.3.4. Step4:SubsamplebyAttributes
As can be seen from the figure above, there are a few too many cities visible to make a good
map. In order to build a cities shapefile with just the largest cities, we can add the newly
createdcitiesshapefiletothemap.Wecanthenusetheselectbyattributesability,andinthis
casechoose[Area]>.01asthecriteria.

Figure25:Area>.01
25of85

Figure26:CreateLayer
Inordertocreateanewlayerwiththefeatureswehaveselected,wecanrightclickonthecities
layerinthelegend.ByhighlightingtheSelectiontabinthecontextmenu,wegaintheability
tocreatealayerfromtheselectedfeatures.Thiswillcreateanewinmemoryshapefilethatis
notyetassociatedwithatruedatalayer.
1.3.5. Step5:ExportLayertoaFile

Figure27:ExportLayer
Exporting the layer will save this newly created city layer with just the cities with the largest
areas.
1.3.6. Step6:RepeatwithRoadsLayer
Becausetheroadsshapefileisactuallyquitelarge,wemightwanttolimitthatshapefileaswell.
26of85

Figure28:PrimaryRoads
1.3.7. Step7:SelectPoliticalBoundsbyClicking

Figure29:SelectMajorAreas

Selecting by attributes is not the only way to narrow down the features that you want to use.
First, make sure that the layer you want to interact with is selected in the legend. This will
preventcontentfromotherlayersfrombeingselectedatthesametime.Nextyoucanactivate
the selection tool by using the button in the toolstrip indicated in the figure above. Holding
down the [Shift] key allows you to select multiple layers at one time. Once you have selected
the major polygons, create a new layer the same way by using the create layer from selection
option in the legend. Finally, export the data to create a simplified continental shapefile. This
willmakelabelingexerciseseasierbecausetheresultwillnotbeclutteredbylabelingthesmall
islandsaroundAustralia.

27of85

Figure30:ActivateLabeling

1.3.8. Step8:ApplyLabeling

Figure31:ApplyLabels

28of85

Figure32:AppliedLabels

29of85
1.4. ProgrammaticPointSymbology
Unliketheprevioussection,wherewewereassumingthatthereaderwouldperformeachstep,
in this section, we will explore the most basic features of the extremely powerful symbology
toolkit provided by DotSpatial, but listed under completely independent objectives. These are
subdivided into 5 basic categories: Points, Lines, Polygons, Labels, and Rasters. A
comprehensive set of cascading forms launched from the Legend provide a built in system so
that users can get started editing symbology right away using the built in components.
However, this section is not about mastering the buttons on the dialogs. Rather, this section
makes the assumption that you are either writing a plugin, or else are building your own GIS
softwareusingourcomponents.Insuchacase,youmightwanttobeabletoautomaticallyadd
certaindatasets,andcontrolthesymbologyautomatically,behindthescenes.
In previous versions of MapWindow, setting the color of the seventh point in the shapefile to
redwasextremelysimple,butthetradeoffwasthatanythingmorecomplexwasnotinherently
supported in the base program. Instead, developers would have to write their own code to
make symbolize the layer based on attributes. MapWindow 6 introduces thematic symbol
classesthatonthesurfaceappeartobemuchmorecomplicated.However,wewillshowthat
accessorshavebeenprovidedtostillalloweasyaccesstothesimpleststeps,butalsoprovidea
basicstructurethatmakessymbolizingbyattributesmuchsimplerthaninpreviousversions.
Tobegin thisexercise,wewillneed thedatasetscreatedaspartofexercise2.Wewillalsobe
workingwithacopyofthevisualstudioprojectthatwecreatedinexercise1,tohammerinthe
pointthatyoudonotneedtobeworkingwiththeMapWindow6executable,butrathercanbe
workingdirectlywiththecomponentsinanewproject.Thefirststepistoexploreaddingdata
tothemapprogrammatically.
1.4.1. AddaPointLayer
AddAPointLayerToTheMap
Objective:

Feat ur eSet f s = new Feat ur eSet ( ) ;


f s. Open( @" [ Your Fol der ] \ Ex3\ Dat a\ Ci t i esWi t hAr eas. shp" ) ;
I MapFeat ur eLayer myLayer = map1. Layer s. Add( f s) ;
Thethreelinesofcodeaboveareallthatisneededtoprogrammticallyaddthecitieswithareas
shapefile to the map. The first line creates an external FeatureSet class. This is useful for
openingandworkingwithshapefiles.Thesecondlinereadsthecontentfromthevectorportion
oftheshapefileintomemory.The@symboltellsC#thatthelineshouldbereadliterally,and
wont use the \ character as an escape sequence. You can substitute [YourFolder] with the
folder containing these exercises on your computer. Finally, the last line adds the data to the
map,andreturnsalayerhandlethatcanbeusedtocontrolthesymbology.Icanaddthelines
30of85
ofcodeaboveinthemainformbyoverridingtheOnShownmethod.Thatway,whentheform
is shown for the first time, it launches the map. The FeatureSet variable gives us access to all
theinformationstoreddirectlyintheshapefile,butorganizedintofeatureclasses.

Figure33:FeatureSetandFeatures

Thesimplifiedclassdiagramsfromabovegiveanideaofwhatkindsofinformationyoucanfind
directly on the FeatureSet class, or in one of the individual Features. The DataTable property
returnsastandard.NetSystem.Data.DataTable,filledwithalloftheattributeinformation.This
tableisalsousedbytheSelectByAttributeexpression.TheEnvelopeisthegeographicbounding
boxfortheentiresetoffeatures.TheFeaturespropertyisthelistoffeaturesthemselves.This
is enumerable, so you can cycle through the list and inspect each of the members. The
FeatureTypesimplytellswhetherornottheFeatureSetcontainspoints,linesorpolygons.
TheothersignificantvectordataclassshownhereistheFeature.TheBasicGeometryclasslists
allofthevertices,organizedaccordingtoOGCgeometricstructures,suchasPoints,LineStrings,
Polygons, and MultiGeometries of the various types. Because we were interested in making
extensible data providers, we did not require these basic geometric classes to support all the
mathematical overlay and relate operations that can be found in the various topology suites.
Instead,theroleoftheBasicGeometryistoprovidethedataonlyinterface.
31of85
We did not overlook the possibility of wanting to perform, say, an intersect operation
with another feature. Instead of building the method directly into the feature class, we have
instead build extension methods so that from a programmatic viewpoint, it will look like any
IFeaturewillbeabletoperformIntersectioncalculations.

Figure34:ExtensionMethod

Typingaperiodafteraclassin.Netwilldisplayanautomaticlistofoptions.Continuingtotype
normallyfiltersthislistofoptions,sothatyoucanveryrapidlynarrowthedisplayeditemsand
reducethechanceforspellingmistakes.Italsogivesyouaninstantbrowsewindowtoexplore
the options on a particular class. This autocompletion tool is referred to as Microsoft
Intellisense. The exact appearance of this function will depend on the version of visual studio,
as well as whether or not you have any extensions like ReSharper loaded. If XML comments
have been generated for the project, (which they have been for MapWindow 6.0) you will not
only see the methods, properties and events available, but you will also see help for each of
thesemethodsthatextendstotheright.
Methodsareidentifiedbyhavingapurplebox.Extensionmethodsarerepresentedbyapurple
box with a blue arrow to the right of that box. Instead of having the programming code built
intotheclass,thecodeisactuallyseparate,inanexternalstaticmethod.Usingthistechnology,
it becomes easy to associate a behavior like Intersects directly with the feature, but without
everyexternaldataproviderhavingtorewritetheintersectioncodeitself.

32of85
1.4.2. SimpleSymbols
MakeYellowStars
Objective:

pr i vat e voi d MakeYel l owSt ar s( I MapFeat ur eLayer myLayer )


{
myLayer . Symbol i zer = new Poi nt Symbol i zer ( Col or . Yel l ow, Poi nt Shapes. St ar , 16) ;
}
Because we know in advance that we are working with points, we dont have to work directly
withtheexistingclasses,orusecasting.Wecansimplyusetheconstructor.IfwepassmyLayer
from the earlier code into the method above, we will automatically create the outpoint shown
inthefollowingimage.

Figure35:YellowStar
Onethingthatyoumightnoticeisthatthebordersofthestarsarehardtoseebecauseweonly
specifiedonecolor,andthatcolorwasthefillcolor.Inordertogivethestarsblackoutlines,we
needtocallaslightlydifferentmethod.

myLayer . Symbol i zer = new Poi nt Symbol i zer ( Col or . Yel l ow, Poi nt Shapes. St ar , 16) ;
myLayer . Symbol i zer . Set Out l i ne( Col or . Bl ack, 1) ;

33of85

Figure36:YellowStarswithOutlines
You will notice that the layer does not control these characteristics directly. Instead, it uses a
classcalledaSymbolizer.Symbolizerscontainallofthedescriptivecharacteristicsnecessaryto
draw something. They have a few simple accessors that allow us to work with the simple
situations like the one listed above. In this situation, we are not worried about a scheme, or
complex symbols that have multiple layers. A method like SetOutline may or may not work as
expectedineverycase,sincesometypesofsymbolsdonotevensupportoutlines.However,if
we inspect the parameters that we can control above, we already have the basic symbology
optionsthatwereprovidedinpreviousversionsofMapWindow.
1.4.3. CharacterSymbols
UseCharacterSymbols
Objective:

In addition to the basic symbols, MapWindow 6.0 also provides access to using characters asa
symbol. This is a very powerful system since character glyphs are vectors, and therefore
scalable. They look good even when printing to a large region at high resolution. It is also
incrediblyversatile.Notonlycanyouusepreexistingsymbolfonts(likewingdings)thatareon
yourcomputer,thereareopensourcefontsthatprovideGISsymbols.Onehelpfulsitethathas
lots of GIS symbol fonts that can be downloaded for free is found here:
http://www.mapsymbols.com/symbols2.html. For this exercise, we are downloading and
unzipping the military true type fonts from the site. Downloading and unzipping the file
produces a file with the extension .ttf, which is a true type font. The next step is to find the
FontsoptionintheControlPanel.
34of85

Figure37:FontsinControlPanel

Clickingonthisfolderwillopenthefoldershowingallofthecurrentlyinstalledtruetypefonts.
Right click anywhere in this folder that is not directly on one of the existing fonts, and you will
expose the context menu shown in the following figure. Choose Install New Font. You will
havetobrowsetoyourrecentlydownloadedandunzipped.ttffile.Inthiscaseweareusingthe
Military.ttffile.

Figure38:RightClicktoInstallNewFont

35of85
We can verify that the new font is available directly by running MapWindow 6.0, or our newly
create program, adding a point layer, and then symbolizing with character symbols. To use
charactersymbols,doubleclickonthesymbolinthelegend.ThiswillopenthePointSymbolizer
Dialog. There is a Combobox named Symbol Type which enables the user to choose a new
symboltype.Inthiscase,wewanttochooseCharacter.

Figure39:SwitchToCharacters

Figure40:ChooseMilitary

Onceyouselectmilitary,theiconslistedbelowinthecharacterselectiondropdownshouldbe
replaced with the new military symbols that we have just downloaded. Because many GIS
36of85
systemsusetruetypefonts,itispossibleforMapWindowtoshowfonttypesfromprecreated
professional font sets. Having verified that we have successfully enabled the software to use
thenewmilitaryfonttype,wewillnowattempttouseoneofthesesymbolsprogrammatically.
Todrawplanes,wewillchoosethecharacterM,whichdrawsacharacterofaplane,andspecify
the use of the Military font name. We can also specify that they will be blue and will have a
pointsizeof16.

myLayer . Symbol i zer = new Poi nt Symbol i zer ( ' M' , " Mi l i t ar y" , Col or . Bl ue, 16) ;

Figure41:MilitaryPlaneCharacters
Asasidenote,theMilitaryfontisslightlyabnormalinthatithasahugeamountofwhitespace
at the bottom of each glyph. Attempting to center the font vertically will cause problems
becauseofallthewhitespace.Asaresult,anaddedlineofcodecatchesthispossibilityanduses
thewidthforcenteringinstead.Sincethesesymbolsmaynotbeexactlysquare,thismayplace
the military symbols slightly off center. However, more professionally created symbols will be
centeredcorrectlysincetheywillhavearealisticheightvaluethatcanbeusedforcentering.It
is also possible to create custom glyphs for use as point symbols using various font editor
software packages. A good commercial example is Font Creator, which has a 30 day free trial
and can be purchased for about $100 here: http://www.highlogic.com/download.html. In the
spiritofopensource,however,therearealsoopensourceoptionsavailablesuchasFontForge:
http://fontforge.sourceforge.net/ and Font Editor: http://fonteditor.org/ both of which are
completelyfree.
37of85
1.4.4. ImageSymbols
UseImageSymbols
Objective:

Sometimes,itsimplyisntpossibletoworkwithfonts,however,andanimageispreferable.In
suchacase,youcanusealmostanykindofimage.Rememberthatifyouhavelotsofpoints,it
isbettertobeworkingwithsmallerimages.Asanexample,youcandownloadthiswikimedia
tigericontoworkwith:
http://upload.wikimedia.org/wikipedia/commons/thumb/f/f5/Tiger_Icon.svg/48px
Tiger_Icon.svg.png

To use this symbol programmatically, first download the image to a file. Once you have saved
the image file, you reference it using either standard file loading methods for images, or else
you can embed the file as a resource to be used. We will look at embedding the image as a
resource.First,fromsolutionexplorer,addaresourcefilenamedImages.

Figure42:AddaNewItem

38of85

Figure43:Images.resxResource

Choose Resources File from the available Templates, then name the resource file Images, and
click Add. From solution explorer, simply double click the newly added Images resource file to
openit.Addingitthefirsttimeshouldautomaticallyopentheresourcefileasatab.Underthe
AddResourceoptioninthetoobarjustbelowtheImages.resxtab,chooseAddExistingFile

Figure44:AddanExistingFile

Thensimplybrowsetothefilewejustdownloaded,andaddittotheresourcefile.Tomakeit
easiertofind,wecanrenamethefileTiger.
39of85

Figure45:RenametoTiger

Now,wecanprogrammaticallyreferencethisimageanytimeusingtheImages.Tigerreference.
Be sure to build the project after adding the image to the resource file, or else the Intellisense
willnotshowtheTigerimageyet.Addingtheimagetoaresourcefilesetsuptheframeworkfor
thefollowinglineofcodewherewewillspecifytousetheTigerimageforthepointsymbology:

myLayer . Symbol i zer = new Poi nt Symbol i zer ( I mages. Ti ger , 48) ;

Figure46:TigerImages
40of85
1.4.5. PointCategories
UsePointSymbolCategories
Objective:

For the next topic, I will introduce the concept of casting. In many cases, methods or
propertiesaresharedbetweenmanydifferenttypesofclasses.Whenthatistrue,theinterface
may provide the shared base class, instead of the class type that is actually being used. For
instance, if you are working with points, the Symbolizer that is being used should be a
PointSymbolizer.ThishasasharedbaseclasswiththeFeatureSymbolizer.

Figure47:SymbolizerClassDiagram

Toillustrateinheritance,theclassdiagramaboveshowsthethreemainfeaturesymbolizers,one
for points, one for lines, and one for polygons. What is most important here is that there are
some characteristics that will be shared. Properties, methods and events on the
FeatureSymbolizer class will also appear on each of the specialized classes. Meanwhile, each
individual type has a collection of classes that actually do the drawing, but these classes are
differentdependingontheclass.Inthesameway,wecansetupcategories,butitworksmuch
more easily if we know what kind of feature layer we are working with. When working with
categories,schemes,andsoon,knowingthatweareworkingwithapointlayeristhedifference
41of85
betweenhavingtocasteverysingleobjecteverytime,andonlyhavingtocastthefeaturelayer
once.
WewillbesymbolizingbasedontheAreafield.Theareaswerecalculatedfromthepolygonsin
exercise 2, so we can be assured that the cities with areas shapefile that we are adding has an
Area field, and looking at the table below, we can see that a reasonable cutoff for picking the
largestcitiesmightbe.01squaredecimaldegrees.

Figure48:LargeAreaCities
Thesourcecodethatwearegoingtousehasseveralpartstoit.First,wearegoingtocastthe
layertoaMapPointLayersothatweknowweareworkingwithpointdata.Afterthat,wecreate
two separate categories, using filter expressions to separate what is drawn by each category.
Finally, we add the new scheme as the layers symbology. When the map is drawn, it will
automaticallyshowthedifferentschemetypesinthelegendusingwhateverwespecifyhereas
thelegendtext.
I MapPoi nt Layer myPoi nt Layer = myLayer as I MapPoi nt Layer ;
i f ( myPoi nt Layer == nul l ) r et ur n;
Poi nt Scheme myScheme = new Poi nt Scheme( ) ;
myScheme. Cat egor i es. Cl ear ( ) ;
Poi nt Cat egor y smal l Si ze = new Poi nt Cat egor y( Col or . Bl ue, Poi nt Shapes. Rect angl e, 4) ;
smal l Si ze. Fi l t er Expr essi on = " [ Ar ea] < . 01" ;
smal l Si ze. LegendText = " Smal l Ci t i es" ;
myScheme. AddCat egor y( smal l Si ze) ;
Poi nt Cat egor y l ar geSi ze = new Poi nt Cat egor y( Col or . Yel l ow, Poi nt Shapes. St ar , 16) ;
l ar geSi ze. Fi l t er Expr essi on = " [ Ar ea] >= . 01" ;
l ar geSi ze. LegendText = " Lar ge Ci t i es" ;
l ar geSi ze. Symbol i zer . Set Out l i ne( Col or . Bl ack, 1) ;
myScheme. AddCat egor y( l ar geSi ze) ;
myPoi nt Layer . Symbol ogy = myScheme;

42of85

Figure49:CityCategoriesbyArea

The square brackets in the filter expression are optional, but recommended to help clarify
fieldnamesintheexpression.Whatis significanthereisthatwe didnothave towritecodeto
actually loop through all of the city shapes, test the area attribute programmatically, and then
assignasymbolschemebasedonthecharacter.Instead,wesimplyallowthebuiltinexpression
parsingtotakeoverandhandlethedrawingforus.Thisallowsforprogrammerstoworkwith
theobjectsinawaythatdirectlymimicshowusersworkwiththesymbologycontrols.Andjust
likethelayerdialogcontrolsallowyoutospecifyschemes;thoseschemescanalsobecontrolled
programmatically.

I MapPoi nt Layer myPoi nt Layer = myLayer as I MapPoi nt Layer ;
i f ( myPoi nt Layer == nul l ) r et ur n;
Poi nt Scheme myScheme = new Poi nt Scheme( ) ;
myScheme. Cat egor i es. Cl ear ( ) ;
myScheme. Edi t or Set t i ngs. Cl assi f i cat i onType = Cl assi f i cat i onTypes. Quant i t i es;
myScheme. Edi t or Set t i ngs. I nt er val Met hod = I nt er val Met hods. Quant i l e;
myScheme. Edi t or Set t i ngs. I nt er val SnapMet hod = I nt er val SnapMet hods. Roundi ng;
myScheme. Edi t or Set t i ngs. I nt er val Roundi ngDi gi t s = 5;
myScheme. Edi t or Set t i ngs. Templ at eSymbol i zer =
new Poi nt Symbol i zer ( Col or . Yel l ow, Poi nt Shapes. St ar , 16) ;
myScheme. Edi t or Set t i ngs. Fi el dName = " Ar ea" ;
myScheme. Cr eat eCat egor i es( myLayer . Dat aSet . Dat aTabl e) ;
myPoi nt Layer . Symbol ogy = myScheme;
43of85

Figure50:QuantileAreaCategories

TherearealargenumberofsettingsthatcanbecontrolleddirectlyusingthePointScheme. In
thisillustrationtheclassificationtypeisquantities,butthiscanalsobeUniqueValuesorcustom.
The categories can always be edited programmatically after they are created, but this simply
controls what will happen when the CreateCategories method is ultimately called. As of the
Sydneyalpharelease(Oct.2009)noteveryIntervalMethodissupported,butQuantileandEqual
Interval are both supported. The interval snap methods include none, rounding, significant
figures,andsnappingtothenearestvalue.Thesecanhelptheappearanceofthecategoriesin
the legend, but it can also cause trouble. In this particular case, we have to set the rounding
digitstoafairlyhighnumber(5)orelsemanycategoriessimplyshowarangeof00andhave
no members. With Significant figures, the IntervalRoundingDigits controls the number of
significant figures instead. One property is deceptive in its power. The TemplateSymbolizer
property allows you to control the basic appearance of the categories for any property that is
notbeingcontrolledbyeitherthesizeorcolorramping.Forexample,ifwewantedtoaddblack
borders to the stars above, we would simply add that to the template symbolizer. In this case
we chose to make them appear as stars and controlled them to have equal sizes since
UseSizeRangedefaultstofalse,butUseColorRangedefaultstotrue.
44of85

Figure51:AvailableFeatureEditorSettings

Thesettingsshownintheexerciseaboverepresentasmalltasteoftheschemeoptionsthatare
programmatically available. You can also control the color range, whether or not the colors
should be ramped or randomly created, a normalization field, an exclusion expression to
eliminateoutliersandinthecaseofpolygons,aconsistentlyappliedgradient.
1.4.6. CompoundSymbols
YellowstarsinaBlueCircle
Objective:


One of the new additions to how symbols work is that you are no longer restricted to
representing things using a single symbol. Complex symbols can be created, simply by adding
symbols to the Symbolizer.Symbols list. There are three basic kinds of symbols, Simple,
Character and Image based. These have some common characteristics, like the Angle, Offset
andSize,whicharestoredonthebaseclass.Inthederivedclasses,thecharacteristicsthatare
specific to the subclass control those aspects of symbology. For creating new symbols, the
Subclass can be used. For working with individual symbols in the collection, you may need to
testwhattypeofsymbolyouareworkingwithbeforeyouwillbeabletocontrolitsproperties.
45of85

Figure52:PointSymbolClassDiagram

Theclassdiagramaboveshowstheorganizationoftheindividualsymbols.
Poi nt Symbol i zer myPoi nt Symbol i zer =
new Poi nt Symbol i zer ( Col or . Bl ue, Poi nt Shapes. El l i pse, 16) ;
myPoi nt Symbol i zer . Symbol s. Add(
new Si mpl eSymbol ( Col or . Yel l ow, Poi nt Shapes. St ar , 10) ) ;
myLayer . Symbol i zer = myPoi nt Symbol i zer ;

Figure53:BlueCircleswithYellowStars

46of85
1.5. ProgrammaticLineSymbology
1.5.1. AddingLineLayers
AddLineLayer
Objective:

Linelayersoperateaccordingtothesamerulesaspointsforthemostpart,exceptthatinstead
ofindividualsymbols,wecanhaveindividualstrokes.Thedefaultsymbologyistohaveasingle
linelayerofarandomcolorthatisonepixelwide.

Feat ur eSet f s = new Feat ur eSet ( ) ;
f s. Open( @" [ Your Fol der ] \ Ex3\ Dat a\ Maj or Roads. shp" ) ;
I MapFeat ur eLayer myLayer = map1. Layer s. Add( f s) ;

Figure54:AddLineLayer

SimpleLinesymbols
BrownRoads
Objective:

pr i vat e voi d Br ownRoads( I MapFeat ur eLayer myLayer )


{
myLayer . Symbol i zer = new Li neSymbol i zer ( Col or . Br own, 1) ;
}

47of85

Figure55:BrownLines
1.5.2. OutlinedSymbols
YellowRoadswithBlackOutlines
Objective:

The line symbology is similar to the point symbology in that it also shares certain shortcut
methods like SetOutline. The distinction is that unlike the simple symbol, strokes cannot
comepreequippedwithanoutline.Instead,theappearanceofanoutlineiscreatedbymaking
twopasseswithtwoseparatestrokes.Thefirststrokeiswider,andblack.Thesecondstrokeis
narrowerandyellow.Theresultisasetoflinesthatappeartobeconnected.Inordertogeta
cleanlookat theintersections,alltheblacklinesaredrawnfirst. Then,all theyellowlines are
drawn.Thisway,theintersectionsappeartohavecontinuouspathsofyellow,ratherthanevery
individualshapebeingterminatedbyacurvingblackoutline.

Li neSymbol i zer r oad = new Li neSymbol i zer ( Col or . Yel l ow, 5) ;
r oad. Set Out l i ne( Col or . Bl ack, 1) ;
myLayer . Symbol i zer = r oad;

48of85

Figure56:YellowRoadswithOutlines

1.5.3. UniqueValues

RoadsColoredbyUniqueTileID
Objective:

One of the more useful abilities is to be able to programmatically apply symbology by unique
values, without having to worry about what those values are or negotiate the actual color in
each case. Simply specify a classification type of UniqueValues and a classification field, and
MapWindowdoestherest.Inthiscase,thedefaulteditorsettingswillcreateahuerampwitha
saturation and lightness in the range from .7 to .8. The editor settings can be used to control
the acceptable range using the Start and End color. There is a Boolean property called
HueSatLight. If this is true, then the ramp is created by adjusting the hue, saturation and
lightnessbetweenthestartandendcolors.Ifthisisfalse,thenthered,blueandgreenvalues
arerampedinstead.Inbothcases,alpha(transparency)isrampedthesameway.

49of85
Li neScheme myScheme = new Li neScheme( ) ;
myScheme. Edi t or Set t i ngs. Cl assi f i cat i onType = Cl assi f i cat i onTypes. Uni queVal ues;
myScheme. Edi t or Set t i ngs. Fi el dName = " t i l e_i d" ;
myScheme. Cr eat eCat egor i es( myLayer . Dat aSet . Dat aTabl e) ;
myLayer . Symbol ogy = myScheme;

Figure57:RoadswithUniqueValues

1.5.4. CustomCategories
CustomRoadCategories
Objective:

Inthepreviousexample,thelegendshowsacollapsiblefieldnameinordertoclarifythe
meaningofthevaluesappearingforeachcategory.Thiscanalsobeaccomplishedmanuallyby
controlling the AppearsInLegend property on the scheme. If this is false, the categories will
appeardirectlybelowthelayer.Whenitistrue,youcancontrolthetextinthelegendusingthe
scheme itself. Showing this principal in action, in this sample we will show the code that will
programmatically set up two categories, and also have them appear under a scheme in the
legend.
Li neScheme myScheme = new Li neScheme( ) ;
myScheme. Cat egor i es. Cl ear ( ) ;
Li neCat egor y l ow = new Li neCat egor y( Col or . Bl ue, 2) ;
l ow. Fi l t er Expr essi on = " [ t i l e_i d] < 36" ;
l ow. LegendText = " Low" ;
Li neCat egor y hi gh = new Li neCat egor y( Col or . Red, Col or . Bl ack, 6, DashSt yl e. Sol i d,
Li neCap. Tr i angl e) ;
hi gh. Fi l t er Expr essi on = " [ t i l e_i d] >= 36" ;
50of85
hi gh. LegendText = " Hi gh" ;
myScheme. Appear sI nLegend = t r ue;
myScheme. LegendText = " Ti l e I D" ;
myScheme. Cat egor i es. Add( l ow) ;
myScheme. Cat egor i es. Add( hi gh) ;
myLayer . Symbol ogy = myScheme;

Figure58:CustomLineCategories

1.5.5. CompoundLines
LineswithMultipleStrokes
Objective:

Each individual LineSymbolizer is made up of at least one, but potentially several strokes
overlapping each other. The two main forms of strokes that are supported natively by
MapWindow are Simple Strokes and Cartographic Strokes. Cartographic strokes have a few
more options that allow for custom dash configurations as well as specifying line decorations.
Decorationsarebasicallyjustpointsymbolsthatcanappearattheendofthestroke,orevenly
arrangedalongthelengthofthestroke.
51of85

Figure59:StrokeClassHierarchy

In this example, we will take advantage of several powerful symbology options. We will use
cartographicstrokesinordertocreatetwoverydifferenttypeoflinestyles.Inthefirstcase,we
will create brown railroad ties. Using the standard Dot option for a simple cartographic line
would not work because the dots created are proportional to the line width. However, with a
custom dash pattern, it is possible to set the lines so that the dashes are thinner than the line
widthitself.Thetwonumbersusedinthedashpatterndonotrepresentoffsets,butratherthe
lengths of the dash and nondash elements that alternate. This is convenient, since for our
repeatingties,wereallyonlyneedtospecifytwonumbers.
The second layer of the symbol will be dark gray rails. In this case, the dash pattern is
continuous, so we will not need to change it. However, the rails dont persist the whole way
across the line the way the ties do. Instead, we want to have two thin lines that appear along
thepathwidth.Todothis,wetakeadvantageofaCompoundArray.Withthecompoundarray,
youareexpressingtheactualoffsetsforthestartandendpositionsalongthecompoundarray,
where0istheleftofthelineand1istheright.Insomecases,linesthataretwothinmaynot
getdrawnatall,sotrytoensurethatthewidthofthelinesrepresentedintheCompoundarray
workouttobejustslightlylargerthan1toensurethatthelinesultimatelygetdrawn.
Inthecodebelow,thestartandendcapsarealsospecified.Bydefaultthesearesettoround,
whichwillendupproducinggraycirclesateachoftheintersections.Byspecifyingthattheend
capsshouldbeflat,noextensionwillbeaddedtoendsofthelines.Roundedcapslookthebest
52of85
for solid lines because it creates a kind of rounded, buffered look to roads that are wider than
onepixel.

Li neSymbol i zer mySymbol i zer = new Li neSymbol i zer ( ) ;


mySymbol i zer . St r okes. Cl ear ( ) ;
Car t ogr aphi cSt r oke t i es = new Car t ogr aphi cSt r oke( Col or . Br own) ;
t i es. DashPat t er n = new f l oat [ ] {1/ 6f , 2/ 6f };
t i es. Wi dt h = 6;
t i es. EndCap = Li neCap. Fl at ;
t i es. St ar t Cap = Li neCap. Fl at ;
Car t ogr aphi cSt r oke r ai l s = new Car t ogr aphi cSt r oke( Col or . Dar kGr ay) ;
r ai l s. CompoundAr r ay = new f l oat [ ] {. 15f , . 3f , . 6f , . 75f };
r ai l s. Wi dt h = 6;
r ai l s. EndCap = Li neCap. Fl at ;
r ai l s. St ar t Cap = Li neCap. Fl at ;
mySymbol i zer . St r okes. Add( t i es) ;
mySymbol i zer . St r okes. Add( r ai l s) ;
myLayer . Symbol i zer = mySymbol i zer ;

Figure60:MultiStrokeRailRoads

53of85
1.5.6. LineDecorations
LinesDecoratedbyStars
Objective:

One of the new features with this generation of MapWindow is the ability to add point
decorations to lines. Each decoration has one symbolizer and can operate with several
positioning options. Each stroke can support multiple decorations, so there is a great deal of
customizable patterns available. The decorations can also be given an offset so that the
decorationcanappearononesideofthelineoranother.Inthiscase,wewillbeaddingyellow
starstoablueline.
Li neDecor at i on st ar = new Li neDecor at i on( ) ;
st ar . Symbol = new Poi nt Symbol i zer ( Col or . Yel l ow, Poi nt Shapes. St ar , 16) ;
st ar . Symbol . Set Out l i ne( Col or . Bl ack, 1) ;
st ar . NumSymbol s = 1;
Car t ogr aphi cSt r oke bl ueSt r oke = new Car t ogr aphi cSt r oke( Col or . Bl ue) ;
bl ueSt r oke. Decor at i ons. Add( st ar ) ;
Li neSymbol i zer st ar Li ne = new Li neSymbol i zer ( ) ;
st ar Li ne. St r okes. Cl ear ( ) ;
st ar Li ne. St r okes. Add( bl ueSt r oke) ;
myLayer . Symbol i zer = st ar Li ne;


Figure61:LineswithStarDecorations
54of85
1.6. ProgrammaticPolygonSymbology
1.6.1. AddPolygonLayers
AddaPolygonLayertotheMap
Objective:

Polygon layers are another representation of vector content where there is an area being
surrounded byaboundary.Polygonscanhaveany numberofholes,whicharerepresentedas
innerringsthatshouldnotbefilled.However,inordertorepresentashapelikeHawaii,which
hasseveralislands,asasingleshape,youwoulduseaMultiPolygoninstead.AMultiPolygonis
still considered to be a geometry and will respond to all of the geometry methods, like
Intersects. We can add the polygon shapefile the same way that we added the point or line
shapefiles.
Polygonsymbolizersareslightlydifferentfromtheothertwosymbolizersbecauseinthecaseof
polygons,wehavetodescribeboththebordersandtheinterior.Sincethebordersarebasically
just lines, rather than replicating all the symbology options as part of the polygon symbolizer
directly,eachpolygonsymbolizerreferencesalinesymbolizerinordertodescribetheborders.
This is a similar strategy to reusing the PointSymbolizer in order to describe the decorations
thatcanappearonlines.

Feat ur eSet f s = new Feat ur eSet ( ) ;


f s. Open( @" [ Your f ol der ] \ Ex3\ Dat a\ Maj or Boundar i es. shp" ) ;
I MapFeat ur eLayer myLayer = map1. Layer s. Add( f s) ;


Figure62:AddMajorBoundaries
55of85
1.6.2. SimplePatterns
SpecifyBluePolygons
Objective:

The simplest task with polygons is to set the fill color for those polygons. You will see
that specifying only an interior fill creates a continuous appearance, since the normal
boundariesareadjacentandallthesamecolor.

pr i vat e voi d Bl uePol ygons( I MapFeat ur eLayer myLayer )
{
Pol ygonSymbol i zer l i ght bl ue = new Pol ygonSymbol i zer ( Col or . Li ght Bl ue) ;
myLayer . Symbol i zer = l i ght bl ue;
}

Figure63:BlueFillOnly

Figure64:WithBlueBorder
56of85
Pol ygonSymbol i zer l i ght bl ue = new Pol ygonSymbol i zer ( Col or . Li ght Bl ue) ;
l i ght bl ue. Out l i neSymbol i zer = new Li neSymbol i zer ( Col or . Bl ue, 1) ;
myLayer . Symbol i zer = l i ght bl ue;

1.6.3. Gradients

FullLayerGradient
Objective:

Oneofthemoreelegantsymbologyoptionsistoapplyagradient.Thesecanvaryintypefrom
linear, to circular to rectangular, with the most frequently used type of gradient by far being
linear. If you want to apply a continuous gradient across the entire layer, you can use the
default category and simply specify the symbolizer. Unlike the previous example where we
directly set up the outline symbolizer, in this example we are taking advantage of the shared
methodSetOutlinewhichdoesthesamething.Forpoints,thismethodcontrolsthesymbols
themselves. For lines, this adds a slightly larger stroke beneath the existing strokes. For
polygons,thiscontrolsthelinesymbolizerthatisusedtodrawtheoutline.Thegradientangleis
specifiedindegrees,movingcounterclockwisefromthepositivexaxis.

Pol ygonSymbol i zer bl ueGr adi ent =


new Pol ygonSymbol i zer ( Col or . Li ght SkyBl ue, Col or . Dar kBl ue, 45, Gr adi ent Types. Li near ) ;
bl ueGr adi ent . Set Out l i ne( Col or . Yel l ow, 1) ;
myLayer . Symbol i zer = bl ueGr adi ent ;

57of85

Figure65:ContinuousBlueGradient

1.6.4. IndividualGradients

ShapeSpecificGradients
Objective:

Anotherpossiblesymbologyistocreatethegradientssothattheyareshapespecific.Thisisnot
reallyrecommendedinthecaseoflargenumbersofpolygonsbecausethedrawinggetslinearly
slower for each specific drawing call. You can draw thousands of polygons with one call by
having only one symbolic class to describe all the polygons. In the case of a few hundred
classes, this distinction is not really noticeable. To rapidly create different categories, we can
take advantage of the nam field which is different for each of the major shapes that we
selectedaspartofexercise1inordertocreatethebasicpolygonshapefile.
58of85

Figure66:MajorBoundariesFields

Pol ygonSymbol i zer bl ueGr adi ent =
new Pol ygonSymbol i zer ( Col or . Li ght SkyBl ue, Col or . Dar kBl ue, - 45, Gr adi ent Types. Li near ) ;
bl ueGr adi ent . Set Out l i ne( Col or . Yel l ow, 1) ;
Pol ygonScheme myScheme = new Pol ygonScheme( ) ;
myScheme. Edi t or Set t i ngs. Templ at eSymbol i zer = bl ueGr adi ent ;
myScheme. Edi t or Set t i ngs. UseCol or Range = f al se;
myScheme. Edi t or Set t i ngs. Cl assi f i cat i onType = Cl assi f i cat i onTypes. Uni queVal ues;
myScheme. Edi t or Set t i ngs. Fi el dName = " nam" ;
myScheme. Cr eat eCat egor i es( myLayer . Dat aSet . Dat aTabl e) ;
myLayer . Symbol ogy = myScheme;

Figure67:IndividualGradients
1.6.5. MultiColoredGradients

59of85
CoolColorswithGradient
Objective:

Onethingthatmayseemlessthanobviousisthatinthepreviousexercisewespecifiedthatthe
UseGradient property should be false. This does not prevent the template symbolizer from
havingagradient.Instead,itprevents thesymbolizerfromoverridingtheoriginal,presumably
simpler,templatewitha gradientsymbol.The gradientsymbolwillbecalculatedusingacolor
fromthecolorrange,butthenwillmaketheupperleftalittlelighterandthelowerrightalittle
darker. That way, you can have the same subtle gradient applied, but still use different colors
foreachcategory.Toboot,thedefaultpolygonsymbolizerhasaborderthatisthesamehue,
butslightlydarker,whichtendstocreateaniceoutlinecolor.
Pol ygonScheme myScheme = new Pol ygonScheme( ) ;
myScheme. Edi t or Set t i ngs. St ar t Col or = Col or . Li ght Gr een;
myScheme. Edi t or Set t i ngs. EndCol or = Col or . Li ght Bl ue;
myScheme. Edi t or Set t i ngs. Cl assi f i cat i onType =
Cl assi f i cat i onTypes. Uni queVal ues;
myScheme. Edi t or Set t i ngs. Fi el dName = " nam" ;
myScheme. Edi t or Set t i ngs. UseGr adi ent = t r ue;
myScheme. Cr eat eCat egor i es( myLayer . Dat aSet . Dat aTabl e) ;
myLayer . Symbol ogy = myScheme;

Figure68:UniqueCoolColorsWithGradient

60of85
1.6.6. CustomPolygonCategories
CustomPolygonCategories
Objective:

An important terminology difference here that we have been using is the difference between
Symbolizer and Symbology. With Symbology, we are always referring to a scheme, which can
have many categories. With a Symbolizer, we are talking about controlling how those shapes
are drawn for one category. By default, all the feature layers start with a scheme that has
exactlyonecategory,whichhasasymbolizerwithexactlyonedrawingelement(symbol,lineor
pattern).TheSymbolizerpropertyonalayerisashortcuttothetopmostcategory.Ifyouhave
severalcategories,itmaybebettertocontrolthesymbolizersexplicitlythantousetheshortcut.
Labelshavebeenaddedtothelayerbelowinordertoillustratethatthetwopinkshapesarein
fact shapes that start with N. The actual labeling code will be illustrated under a separate
sectionunderlabeling.
Pol ygonScheme scheme = new Pol ygonScheme( ) ;
Pol ygonCat egor y queensl and = new Pol ygonCat egor y( Col or . Li ght Bl ue, Col or . Dar kBl ue, 1) ;
queensl and. Fi l t er Expr essi on = " [ nam] = ' Queensl and' " ;
queensl and. LegendText = " Queensl and" ;
Pol ygonCat egor y nWor ds = new Pol ygonCat egor y( Col or . Pi nk, Col or . Dar kRed, 1) ;
nWor ds. Fi l t er Expr essi on = " [ nam] Li ke ' N*' " ;
nWor ds. LegendText = " N - Wor ds" ;
scheme. Cl ear Cat egor i es( ) ;
scheme. AddCat egor y( queensl and) ;
scheme. AddCat egor y( nWor ds) ;
myLayer . ShowLabel s = t r ue;
myLayer . Symbol ogy = scheme;

Figure69:CustomCategories
61of85

1.6.7. CompoundPatterns

MultiLayerPatterns
Objective:

Like the other previous symbolizers, polygon symbolizers can be built out of overlapping
drawing elements. In this case they are referred to as patterns. The main patterns currently
supportedaresimple,gradient,pictureandhatchpatterns.Simplepatternsareasolidfillcolor,
whilegradientpatternscanworkwithgradientssetupasanarrayofcolorsorganizedinfloating
pointpositionsfrom0to1.Theanglecontrolsthedirectionoflinearandrectangulargradients.
Hatch patterns can be built from an enumeration of hatch styles. Picture patterns allow for
scalingandrotatingaselectedpicturefromafile.

Figure70:PatternClassDiagram

Onethinginparticulartonoteaboutthisnextexampleisthatinallthepreviousexampleswith
multiple patterns, we simply cleared out the default pattern that was automatically created as
partofthesymbolizer.Whenweaddanewpattern,thenewpatterngetsdrawnontopofthe
previouspatterns,sothelastpatternaddedhasthehighestdrawingpriority.Inthecodebelow,
thenewpatternhasitsbackgroundcolorsettotransparent,yetintheimagebelowweseethat
thecoloringisredstripesagainstabluebackground.Thepatternbelowtheredstripepatternis
thedefaultpattern,andwillberandomlygeneratedasadifferentcoloreachtime.
62of85

Pol ygonSymbol i zer mySymbol i zer = new Pol ygonSymbol i zer ( ) ;
mySymbol i zer . Pat t er ns. Add(
new Hat chPat t er n( Hat chSt yl e. Wi deDownwar dDi agonal , Col or . Red, Col or . Tr anspar ent ) ) ;
myLayer . Symbol i zer = mySymbol i zer ;

Figure71:Hatchpatterns

1.7. ProgrammaticLabels
Labels
Objective:

Forthefirstexamplewithlabels,wewillshowaddingyourowntextinawaysothatthesame
text gets added to all the features. This uses the default settings, and you can see from the
default settings that there is no background, and each label has the left side aligned with the
centerpointbydefault.

I MapLabel Layer l abel Layer = new MapLabel Layer ( ) ;
l abel Layer . Symbol ogy. Cat egor i es[ 0] . Expr essi on = " Test " ;
myLayer . ShowLabel s = t r ue;
myLayer . Label Layer = l abel Layer ;

63of85

Figure72:AddingTestlabels

1.7.1. FieldNameExpressions
FieldNameLabels
Objective:

The field name in this case describes the name of the territory. In order for the name field to
appearinthelabeltext,wesimplyencloseitinsquarebrackets. Thisputstogetheraversatile
scenario where you can build complex expressions with various field names. You can also use
escapecharacterstocreatemultilinelabels.
I MapLabel Layer l abel Layer = new MapLabel Layer ( ) ;
I Label Cat egor y cat egor y = l abel Layer . Symbol ogy. Cat egor i es[ 0] ;
cat egor y. Expr essi on = " [ nam] " ;
cat egor y. Symbol i zer . Or i ent at i on = Cont ent Al i gnment . Mi ddl eCent er ;
myLayer . ShowLabel s = t r ue;
myLayer . Label Layer = l abel Layer ;

64of85

Figure73:FieldNameLabels

1.7.2. MultiLineLabels
MultiLineLabels
Objective:

Creating multiline labels is simple, since all you have to do is use the standard .Net newline
character, which in C# is added using the /n, while in visual basic you would combine the two
strings with a vbNewLine element between them. The relative position of the multiple lines is
controlled by the Alignment property on the label Symbolizer. In order to minimize confusion,
the labels follow the same organization with a scheme, categories and symbolizers. A filter
expressionalsoallowsustocontrolwhichlabelsareadded.
I MapLabel Layer l abel Layer = new MapLabel Layer ( ) ;
I Label Cat egor y cat egor y = l abel Layer . Symbol ogy. Cat egor i es[ 0] ;
cat egor y. Expr essi on = " [ nam] \ nI D: [ Cnt _nam] " ;
cat egor y. Fi l t er Expr essi on = " [ nam] Li ke ' N*' " ;
cat egor y. Symbol i zer . BackCol or Enabl ed = t r ue;
65of85
cat egor y. Symbol i zer . Bor der Vi si bl e = t r ue;
cat egor y. Symbol i zer . Or i ent at i on = Cont ent Al i gnment . Mi ddl eCent er ;
cat egor y. Symbol i zer . Al i gnment = St r i ngAl i gnment . Cent er ;
myLayer . ShowLabel s = t r ue;
myLayer . Label Layer = l abel Layer ;

Figure74:MultiLineLabels

Multiple label categories can be created and added to the scheme in the same way that the
featuresets were able to add different categories. The labels also allow for the font to be
controlled,aswellasthetextcolor,backgroundcolorandopacityofeither.

1.7.3. TranslucentLabels
TranslucentLabels
Objective:

The background color in this case has been set to transparent by specifying an alpha value of
something less than 255 when setting the BackColor. Frequently, there are opacity properties
available in addition to the actual color, but that is just there for serialization purposes and is
simply a shortcut to the alpha channel of the color structure. This example also illustrates the
useofthecompoundconjunctionORinthefilterexpression.Otherpowerfultermsthatcan
be used are AND and NOT as well as the combined expression Is Null which is case
insensitiveandcanidentifynullvaluesseparatelyfromemptystringsforinstance.Noticethatis
66of85
not = null which doesnt work with .Net DataTables. For the negative you could use NOT
[nam]isnull.

I MapLabel Layer l abel Layer = new MapLabel Layer ( ) ;
I Label Cat egor y cat egor y = l abel Layer . Symbol ogy. Cat egor i es[ 0] ;
cat egor y. Expr essi on = " [ nam] \ nI D: [ Cnt _nam] " ;
cat egor y. Fi l t er Expr essi on = " [ nam] = ' Tasmani a' OR [ nam] = ' Queensl and' " ;
cat egor y. Symbol i zer . BackCol or Enabl ed = t r ue;
cat egor y. Symbol i zer . BackCol or = Col or . Fr omAr gb( 128, Col or . Li ght Bl ue) ;
cat egor y. Symbol i zer . Bor der Vi si bl e = t r ue;
cat egor y. Symbol i zer . Font St yl e = Font St yl e. Bol d;
cat egor y. Symbol i zer . Font Col or = Col or . Dar kRed;
cat egor y. Symbol i zer . Or i ent at i on = Cont ent Al i gnment . Mi ddl eCent er ;
cat egor y. Symbol i zer . Al i gnment = St r i ngAl i gnment . Cent er ;
myLayer . ShowLabel s = t r ue;
myLayer . Label Layer = l abel Layer ;

Figure75:TranslucentLabels

1.8. ProgrammaticRasterSymbology

67of85
1.8.1. DownloadData
DownloadaRasterLayer
Objective:

Inadditiontothevectordatathatwehavebeenlookingatsofar,MapWindowalsosupportsa
numberofrasterformats.Rastersareconsidereddistinctfromimagesforusinthatthevisual
representation that we see is derived from the values much in the way that we derive the
polygon images from the actual data. With rasters, you typically have a rectangular
arrangement of values that are organized in rows and columns. For datasets that dont have
completesampling,aNoDatavalueallowstherastertoonlyrepresentaportionofthetotal
area.
Because of the existence of extensible data format providers, there is no way to tell just how
many formats MapWindow will support at the time you are reading this. We have created a
plugin that is exclusive to the windows platform using Frank Warmerdans GDAL libraries and
C#linkagefiles.ThepluginexposesmanyoftherasterandimagetypessupportedbyGDALto
MapWindow 6, or any project that adds our ApplicationManager component. While the
situation may change before the beta release, for the Sidney Alpha, only one grid format is
supportednatively(thatiswithoutusingGDAL)andthatisabgdformat.Thisisnotaproblem
for independent developers because of our clever system that enables you to add a single
ApplicationManager to the project and empower your own project with all the data format
extensionsthatworkwithMapWindow6.However,sincethatwontbecoveredatthisstageof
thetutorials,wewillusetheMapWindow6applicationtoconvertarasterfiletotheformatwe
need.AgoodproviderofGISdataistheUSGS.Theyprovidemanyformsofdatafromaround
the world, but in this case we are interested in an elevation dataset. A useful web utility for
browsingthewebiscalledEarthExplorer.http://edcsns17.cr.usgs.gov/EarthExplorer/

68of85

Figure76:EarthExplorer

If the link above doesnt work, you can try searching for USGS and looking for links that allow
youtosearchfrodatabyregion.Themapapplicationisaneasytousesystemthatprovidesa1,
2, 3 Data download experience that is to be envied. Unfortunately, the system is also under
heavydemand,soyouwillhavetobeconservativewithyourrequestsfromthissite.
To get data, simply zoom into a region of interest and you will see that they have lots of
interesting data sets. For this demo, I activated the SRTM data format, which gives us digital
elevationinformation.Youwillhavetobearegistereduserinordertodownloaddatafromthis
site,andnotallthedataisfree.Inthiscase,IdownloadedaBILfileforthisdemonstration,but
other formats are available, including DTED. Both formats are supported by MapWindow by
usingGDAL.Thedownloadedfilewillbezipped,soyouwillhavetounzipthefilebeforeyoucan
open it with MapWindow 6. Before we can work with the data programmatically, we will use
MapWindow6tochangethedataformattobgd.ThisisactuallyassimpleasopeningtheBIL,
rightclickingonthelegendandchoosingexportdata.Dontworryifthecoloringlooksstrange.
Itisusualforthenodatavaluestodistortthecoloringuntiltheycanbeproperlyexcludedfrom
thesymbology.Fornow,weareonlyconcernedwithconvertingtheformattoan*.bgdfile.

69of85

Figure77:ExportData

Figure78:SaveasBgd

You will see lots of other formats available, and these are the write formats that have been
exposedbytheGDALplugin,plusanyformatsthataresupportedforrastersbyotherproviders.
Youwillnoticethat*.bgdisattheendofthelist,andthatistheproviderthatwewillbeusing
fortherestofthedemonstration.Savethedownloadedfileasabgdfile.
1.8.2. AddaRasterLayer
AddARasterLayer
Objective:

70of85
Rast er r = new Rast er ( ) ;
r . Open( @" [ Your Fol der ] \ Ex3\ Dat a\ DEM\ El evat i on. bgd" ) ;
I MapRast er Layer myLayer = map1. Layer s. Add( r ) ;

Onethingthatshouldbefairlyobviousrightawayisthatwhilesimilartothepreviousexamples,
a raster is a completely different data object. Instead of working with features and
concentrating on ideas like geometries, rasters give you direct access to the numerical data
stored in grid form. Inheritance at different levels is certainly used, but most of that occurs
under the hood. The Raster class gives you a friendly user interface that works regardless of
whatkindofdriversareopperatingunderthehood.Theprimarybenefittoyouisthatwriting
thecodebecomesalotsimplerbecauseyoudontneedtoworryaboutwhatkindofrasteryou
areworkingwith.

Figure79:DefaultRaster
Onefairlyobviousdrawbackwiththesymbologyaboveisthatitisalmostcertainlybeingthrown
off by an unexpected nodata value. We can use the symbolizer interface for rasters in either
MapWindow6.0oryournewprojectbydoubleclickingnexttotheelevationlayerinthelegend.
Thiswilllaunchadialogliketheonebelow.
71of85

Figure80:Statistics

We can see right away that of the many sample points that were taken from this image, only
oneortwovaluesinthe extremeupperrangeof32,000and65,000respectivelycanthrowoff
theentiresymbolicrangeforthisraster.Wecanrepairthiseasilybyslidingthesymbolicsliders
downtotheleftendoftheplot.Whatislessobviousuntilyoustartzoominginisthatalmostall
of the values are effectively nodata values of 0 and are showing up on our plot. You can use
the mouse wheel to zoom into and out of histogram, but in this case it will be very difficult to
see what is going on as long as the range includes zero. There is a trick that we can do in
specificallythissituation.Whatwewilldoismanuallyenterarangefrom1to250andfrom250
to 600 in the editable values column in the data grid above the graph. This wont directly
changethegraph.Instead,itwillenableaninnovativefeaturetoworkonthegraph.AZoomTo
Categories option when right clicking the graph allows us to zoom into the range specified by
thecategoriesabove.
72of85

Figure81:ZoomToCategories

Figure82:AfterZoom

We can see from the statistics here, that the large percentage of the points occur between
about 1 and 150, with a sizeable hump up to about 300. We will put the break slider in the
minimum that occurs at around a value of 150, or you can use 150 as the exact range in the
valuescolumnagain.Theresultisthatwecangetamuchmorecleanlysymbolizedrasterwhen
73of85
we are done. The nodata region is still white, but now we can see a much better
representationofthevaluesthatwedohavesincewehaveeliminatedtheoutliners.

Figure83:AfterAdjustments
So in order to set this up programmatically, we would like to first of all edit the range of the
categoriesthatareautomaticallygeneratedwhenaddingthedatalayersothatwehavearange
from1150andfrom150to800.
1.8.3. ControlCategoryRange
ControlCategoryRange
Objective:

The only thing to notice when controlling the range is that you can control the range values
independently from modifying the legend text. In order to update the legend text based on
othersettings,wecanusetheApplyMinMaxsettings.Alternately,wecouldhavesetthelegend
textdirectly,justaswecanfortheothercategories.

pr i vat e voi d Cont r ol Range( I MapRast er Layer myLayer )


{
myLayer . Symbol i zer . Scheme. Cat egor i es[ 0] . Range = new Range( 1, 150) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 0] . Appl yMi nMax( myLayer . Symbol i zer . Edi t or Set t i ngs) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 1] . Range = new Range( 150, 800) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 1] . Appl yMi nMax( myLayer . Symbol i zer . Edi t or Set t i ngs) ;
myLayer . Wr i t eBi t map( ) ;
}
74of85

Figure84:ProgrammaticRestrictRange

1.8.4. ShadedRelief
AddLighting
Objective:

myLayer . Symbol i zer . Scheme. Cat egor i es[ 0] . Range = new Range( 1, 150) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 0] . Appl yMi nMax( myLayer . Symbol i zer . Edi t or Set t i ngs) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 1] . Range = new Range( 150, 800) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 1] . Appl yMi nMax( myLayer . Symbol i zer . Edi t or Set t i ngs) ;
myLayer . Symbol i zer . ShadedRel i ef . El evat i onFact or = 1;
myLayer . Symbol i zer . ShadedRel i ef . I sUsed = t r ue;
myLayer . Wr i t eBi t map( ) ;
75of85

Figure85:WithLighting

1.8.5. PredefinedSchemes

UseGlacierColoring
Objective:


There are several predefined color schemes that can be used. All of the preset schemes
basically use two separate ramps that subdivide the range and apply what is essentially a
coloring theme to the two ranges. Those ranges are easilly adjustable using the range
characteristics on the category, but should be adjusted after the scheme has been chosen, or
elseapplyingthenewschemewilloverwritethepreviousrangechoices.

myLayer . Symbol i zer . Scheme. Appl yScheme( Col or Schemes. Gl aci er s, myLayer . Dat aSet ) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 0] . Range = new Range( 1, 150) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 0] . Appl yMi nMax( myLayer . Symbol i zer . Edi t or Set t i ngs) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 1] . Range = new Range( 150, 800) ;
myLayer . Symbol i zer . Scheme. Cat egor i es[ 1] . Appl yMi nMax( myLayer . Symbol i zer . Edi t or Set t i ngs) ;
myLayer . Symbol i zer . ShadedRel i ef . El evat i onFact or = 1;
myLayer . Symbol i zer . ShadedRel i ef . I sUsed = t r ue;
myLayer . Wr i t eBi t map( ) ;

76of85

Figure86:Glaciers
1.8.6. EditRasterValues
FixRasterValues
Objective:

Previously, we have been using tricks to color the elevation but where we directly ignored the
values that were either nodata values that read 0, or else apparently bad data values that
showed impossible values like 65,000. In this section we will use the raster data class itself in
order to repair the values programmatically. This will only alter the copy that we have in
memoryandwillnotoverwritethevaluestothediskunlesswespecificallyinstructittodoso.
In the example below, we can cycle through all of the values in the raster using the NumRows
andNumColumnspropertiestogiveusanideaofwhattheboundsareontheloops.TheValue
property takes a double index, and will work with whatever the real data type is and convert
thatdatatypeintodoubles.Wecanusethistoquicklycleanupthevaluesontherasterbefore
weevercreatealayer.Wecanalsoassignthenodatavalueontherastersothatitmatchesthe
0 values that cover a large portion of the raster. This will automatically eliminate it from the
statisticalcalculationssothatourdefaultsymbologyshouldlookbetter.







77of85
Rast er r = new Rast er ( ) ;
r . Open( @" C: \ dev\ MapWi ndow6Dev\ Tut or i al \ Component s\ Ex3\ Dat a\ DEM\ El evat i on. bgd" ) ;
r . NoDat aVal ue = 0;
f or ( i nt r ow = 0; r ow < r . NumRows; r ow++)
{
f or ( i nt col = 0; col < r . NumCol umns; col ++)
{
i f ( r . Val ue[ r ow, col ] > 600) r . Val ue[ r ow, col ] = 600;
}
}
I MapRast er Layer myLayer = map1. Layer s. Add( r ) ;

Figure87:DefaultSymbologyofFixedRaster

Thislooksalotbetter,andifwedoubleclickontheelevationlayer,wecantakealookatwhat
the statistical plot automatically shows. In the next figure, we can see that the default range
showsvaluesfrom1to600,anddoesnotincludeinthestatisticalsummarythevaluesthatwe
have now labeled as nodata values. Assigning the nodata value can be risky because there
maybevaluesthatwereusingtheoldnodatavalue.Thiscaneasilybefixedbycyclingthrough
therasterinthesamewayandadjustingvaluessothattheyworkwiththegivenstatistics.

78of85

Figure88:AfterFixingRaster

1.8.7. QuantileBreaks
QuantileBreakValues
Objective:

JustliketheFeatureSets,RasterscanusetheEditorSettingspropertyinordertocustomizehow
tobuildschemes,ratherthanhavingtospecifytheschemesdirectly.Thisiswhereourprevious
edits to fix the raster values become more important. If we had tried to apply quantile breaks
before,insteadofcoloringtherasterappropriately,wewouldhavehadallbutoneoftheranges
read00.Now,wegetareasonablerange.

myLayer . Symbol i zer . Edi t or Set t i ngs. I nt er val Met hod = I nt er val Met hods. Quant i l e;
myLayer . Symbol i zer . Edi t or Set t i ngs. NumBr eaks = 5;
myLayer . Symbol i zer . Scheme. Cr eat eCat egor i es( myLayer . Dat aSet ) ;
myLayer . Symbol i zer . ShadedRel i ef . El evat i onFact or = 1;
myLayer . Symbol i zer . ShadedRel i ef . I sUsed = t r ue;
myLayer . Wr i t eBi t map( ) ;

79of85

Figure89:QuantileBreaks

Figure90:RasterSymbologyClasses

80of85
1.9. MapWindow4ConversionTips
In this section, we assume that you might be a developer with some preexisting experience
with MapWindow 4. Because the underlying object libraries are very different, it might be
confusingforaMapWindow4developertogetstartedworkingwiththeobjectsinMapWindow
6.Themostchallengingideasinvolvetheintroductionofinheritanceandextensibleinterfaces.
1.9.1. Point
MapWinGIS.Point
Class:

The Point class was formerly a class that provided rapid access to X, Y and Z values.
ThisclasshasbeenreplacedbytheCoordinateclass.APoint,asdefinedbytheOGC
Simple Feature Specification, has geometry methods like Intersects, and is
independently available in MapWindow 6, but has many more capabilities that just
storingacoordinatelocation.Therefore,thecoordinateclasshastakenoverasthe
classtouse.

1.9.2. Extents
MapWinGIS.Extents
Class:

TheExtentsclassinMapWindow4wasaboundingboxthatdefinedatwoorthree
dimensional region. The new class introduces a Minimum and a Maximum
coordinate,whichhastheX,YandZvaluesforthelowerandupperboundsineach
case. This also provides accessors for controlling the X, Y, Height and Width
properties,whicharecalculatedfromtheMinimumandMaximumcoordinates.

81of85
1.9.3. Shape

The Shape class in MapWindow 4 was a generic feature and provided


basic access to the coordinates, and gave the geographic extents for that shape.
In the old model, the only connectivity between a shape and the attributes was
that they would both have the same index. In the new version, a Feature has a
DataRow,whichprovidesdirectaccesstotheattributesspecifictothisfeature.It
also has the Envelope, which describes the bounds, and you can directly access
the coordinates. Because some features are complex, like multipolygons, the
BasicGeometryisprovided,whichorganizesthecoordinatesaccordingtotheOGC
definitionslikePolygons,LineStrings,orPoints.

MapWinGIS.Shape
Class:
82of85
1.9.4. Shapefile

MapWinGIS.Shapefile
Class:

InMapWindow4,therewasanassumptionthattherewas
only going to ever be one supported vector format, and
that format was the shapefile. In MapWindow 6.0, the
introduction of extensible data providers implies that
many different data sources will be possible. Therefore,
the name FeatureSet seemed more appropriate.
FeatureSet classes contain accessors to the Envelope, a
DataTable of attributes, as well as a cached array of
vertices. The ShapeIndices class is a special shortcut to
allow for effective use of the vertices class, and is
currentlybeingusedtospeeduprenderingoperations.A
Reproject method is also available on the FeatureSet,
which will change the inmemory coordinates without
changingtheoriginalfile.
Regardless of whether you are working with an image,
raster, or featureSet, they derive from the same basic
class, called a DataSet. The DataSet provides simple
information like the Name, and Projection information
that are shared across formats. Selection is supported
here, but it should be understood that there is a
disconnect between the featureset and the layer being
drawn. Layers control how a particular DataSet is
symbolizedanddrawninthemap.However,theabilityto
discoverthefeaturesthatarewithinanenvelope,orelsethathaveattributesthatmatchanSQL
queryissupportedandusedattheleveloftheFeatureSet.
The FeatureSet is interesting because it acts as both a base class, meaning that a
PolygonShapefile ultimately inherits from FeatureSet, but it also acts as a wrapper class. In
other words, when the user programmatically creates a new FeatureSet, there is no way to
knowwhatkindsofclasseswillbenecessaryinordertoaccessthedataona file,orpossiblya
database or web service. Therefore, we provide the FeatureSet as a kind of wrapper for an
internalIFeatureSet.WhentheOpenmethodiscalled,internally,theFeatureSetclassrequests
anewIFeatureSetfromthedefaultDataManager.Anyrequestsforfeaturesorotherproperties
aresimplypassedtotheinternalfeatureset.

83of85

1.9.5. Grid
MapWinGIS.Grid
Class:

The grid class was a wrapper class that could internally represent an integer,
float,short,orevendoublegrid.Themaingoalofthegridclasswastobeableto
cyclethroughtherowsandcolumnsofarasterdatafileandgetorsetthevarious
numericvalues.
The new representation is called a Raster. Unlike the MapWindow Grid, Rasters
can have multiple bands, with each band also being a Raster. The vast set of
propertiestotheleftmayseemintimidating,butrealistically,thereareonlyafew
properties that are critical. The first is the Value property. This is where the
actualvaluesarestored.Toaccessthevalueonrow7andcolumn6,youwould
simply access double val = myRaster.Value[7, 6]. Regardless of what the source
data is stored as, the value accessed here will be converted into double values.
Thismakesiteasiertowritecode,becauseyoudonthavetohandleeachofthe
separatepossibilitiesindependently.
TheothercriticalvaluesareNumRowsandNumColumns.Thesearenecessaryso
that you know how to cycle through the values form the Value property. The
finalbitofinformationthatisespeciallyimportantistheBoundsproperty.Many
of the properties to the left are actually just shortcut accessors to the
RasterBounds property. This is where the information is kept that stores the
geospatialpartoftherastercontent.WiththeBoundsproperty,youcancontrol
the position of a raster in space. The NoDataValue is also useful, as it can help
changehowstatisticsarecalculated.

84of85
1.9.6. GridHeader
MapWinGIS.GridHeader
Class:

The Header was an important part of the grid. It defined the spatial
locationslikethelowerleftXandlowerleftYcoordinatesaswellasdefininga
cell size. One of the limitations of the MapWindow 4 grids was that they did
notsupportskewterms.In MapWindow6.0,theskewisfullysupportedand
uses AffineCoefficients as the source of most of the other properties.
However, in order to define the boundaries themselves, it is not enough to
simplyhavetheaffinecoefficients,whicheffectivelydescribethecellsizeand
skewrelationshipsaswellasthepositionoftheupperleftcell.Youalsoneed
the number of rows and columns in order to get a valid rectangle that can
enclosetheentireraster.TheEnvelopeisarectangularformthatcompletely
containstheraster.

1.9.7. Image

MapWinGIS.Image
Class:

The Image class was specifically designed for working


with images, and was not really designed for data
analysis. The new ImageData class supports a Values
methodsimilartothevaluesofaraster,butisactuallyan
arrayofbytevalues.Theformatoftheimagewillchange
how those byte values are organized. The Stride
property is the number of bytes in a given row. This is
not always strictly related to the number of columns as
some image formats use algorithms that may require
slightly more columns than have actual data. The
BytesPerPixel gives an idea of whether you are working
withaGrayValue,RGBorARGBimage.Withimages,the
geospatial location and sizing is controlled via a
WorldFile.
85of85
1.10. ExtensionMethods
Rasters
Extensions

Notallofthemethodsaresupporteddirectlyonaraster.Manyuseful
methods are actually supported in the form of Extension Methods. For the
raster, this includes useful methods that can alter the raster bounds, like
Translate, or Scale, or Rotate. But other useful abilities like CreateHillShade
actually use the raster values themselves in order to calculate a floating point
valuethathelpstocontroltheshadedreliefaspectofanyimagethatiscreated
fromaraster.OthermethodslikeGetRandomValues,andGetNearestValueare
helpful for doing analysis, but one of the most critical methods is CellToProj
andProjToCell,whichallowsthedevelopertoeasilygobackandforthbetween
geospatialcoordinatesandtherowandcolumnindicies.

Feature
Extensions

TheFeature,andinfactanyclassthatimplementstheIFeatureinterfacewillbe
extendedwiththegeometrymethodsthataresocriticaltovectorcalculations.
These not only include the overlay operations like Intersection, Union and
SymmetricDifference, but all the tests that you might want to use like touches
orwithin.SomeofthebonusmethodsaremethodslikeArea,whichcalculates
theareasofpolygons.AnotherisCentroid,whichcalculatesthecenterofmass
forgeometries.ConvexHullcanbeusedtosimplifyageometryinthesameway
thatyouwouldsimplifysomethingbywrappingitwithanelasticband.Itdraws
straight lines past concave sections, and follows around with the convex
portions. The Distance tool finds the minimum distance between two
geometries, and the IsWithinDistance simply changes the Distance calculation
totestitagainstathreshold.

You might also like