You are on page 1of 85

DevelopersCorner

Harold(Ted)DunsfordJr. MarkVanOrden JiKadlec


October2009

1of85

TableofContents
TableofContents ______________________________________________________________2 1. DevelopersCorner __________________________________________________3 1.1. GeometryCheatSheet___________________________________________4
1.1.1. OverlayOperations:________________________________________________________ 8

1.2.
1.2.1. 1.2.2. 1.2.3. 1.2.4. 1.2.5. 1.2.6.

Exercise1:AssembleaMapProject_______________________________10
Step1:StartaNewC#Application ___________________________________________ 10 _ Step2:AddMapWindowComponents________________________________________ 11 Step3:AddMenuandStatusStrips___________________________________________ 13 Step4:AddtheMap_______________________________________________________ 15 Step5:AddtheLegendandToolbox__________________________________________ 16 Step6:LinkItAllTogether__________________________________________________ 18

1.3.
1.3.1. 1.3.2. 1.3.3. 1.3.4. 1.3.5. 1.3.6. 1.3.7. 1.3.8.

Exercise2:SimplifyAustraliaDataLayers __________________________21
Step1:DownloadData_____________________________________________________ 21 Step2:CalculatePolygonAreas______________________________________________ 21 Step3:ComputeCentroids _________________________________________________ 23 Step4:SubsamplebyAttributes_____________________________________________ 24 Step5:ExportLayertoaFile ________________________________________________ 25 Step6:RepeatwithRoadsLayer_____________________________________________ 25 Step7:SelectPoliticalBoundsbyClicking______________________________________ 26 Step8:ApplyLabeling _____________________________________________________ 27

1.4.
1.4.1. 1.4.2. 1.4.3. 1.4.4. 1.4.5. 1.4.6.

ProgrammaticPointSymbology __________________________________29
AddaPointLayer_________________________________________________________ 29 SimpleSymbols___________________________________________________________ 32 CharacterSymbols ________________________________________________________ 33 ImageSymbols___________________________________________________________ 37 PointCategories__________________________________________________________ 40 CompoundSymbols_______________________________________________________ 44

1.5.
1.5.1. 1.5.2. 1.5.3. 1.5.4. 1.5.5. 1.5.6.

ProgrammaticLineSymbology ___________________________________46
AddingLineLayers ________________________________________________________ 46 OutlinedSymbols_________________________________________________________ 47 UniqueValues____________________________________________________________ 48 CustomCategories________________________________________________________ 49 CompoundLines__________________________________________________________ 50 LineDecorations__________________________________________________________ 53

1.6.
1.6.1. 1.6.2. 1.6.3. 1.6.4. 1.6.5. 1.6.6. 1.6.7.

ProgrammaticPolygonSymbology________________________________54
AddPolygonLayers _______________________________________________________ 54 SimplePatterns __________________________________________________________ 55 _ Gradients _______________________________________________________________ 56 IndividualGradients_______________________________________________________ 57 MultiColoredGradients____________________________________________________ 58 CustomPolygonCategories_________________________________________________ 60 CompoundPatterns_______________________________________________________ 61

1.7.
1.7.1.

ProgrammaticLabels___________________________________________62
FieldNameExpressions ____________________________________________________ 63

2of85

1.7.2. 1.7.3.

MultiLineLabels _________________________________________________________ 64 TranslucentLabels ________________________________________________________ 65

1.8.
1.8.1. 1.8.2. 1.8.3. 1.8.4. 1.8.5. 1.8.6. 1.8.7.

ProgrammaticRasterSymbology _________________________________66
DownloadData___________________________________________________________ 67 AddaRasterLayer ________________________________________________________ 69 ControlCategoryRange____________________________________________________ 73 ShadedRelief ____________________________________________________________ 74 PredefinedSchemes_______________________________________________________ 75 EditRasterValues_________________________________________________________ 76 QuantileBreaks __________________________________________________________ 78

1.9.
1.9.1. 1.9.2. 1.9.3. 1.9.4. 1.9.5. 1.9.6. 1.9.7.

MapWindow4ConversionTips___________________________________80
Point___________________________________________________________________ 80 Extents _________________________________________________________________ 80 Shape __________________________________________________________________ 81 Shapefile________________________________________________________________ 82 Grid____________________________________________________________________ 83 GridHeader______________________________________________________________ 84 Image __________________________________________________________________ 84

1.10.

ExtensionMethods ____________________________________________85

1. DevelopersCorner
This section gives a bit of an overview of geometric relationships, which are important for understandingsomeofthevectoranalysisoptions,andthengivessomeworkableexercisesto 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 pickandchoosewhatsectionsoftheframeworkyouwanttoworkwith.Ifthemapisallyou need, you dont need to bother adding the legend or our custom status strip or the toolstrip. However,thosecomponentsareprovidedforyousothatityoucanstitchtogetheraworking GISwithoutwritingasinglelineofcode.

3of85

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 dimensionandanareaby2.Ifthetestisnotspecifictowhatdimension,itcanrepresentany dimensionasTrue.Likewise,ifitisrequiredthatthesetisempty,thenFalseisused.
Interior Interior Boundary Exterior

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

4of85

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 Everypointoftheothergeometryisapointofthisgeometry,andthe interiorsofthetwogeometrieshaveatleastonepointincommon. T*****FF*
I I B E B E

CoveredBy: o o Everypointofthisgeometryisapointoftheothergeometry. T*F**F***,*TF**F***,**T*F***or**F*TF***


I I B E B E

I I B , E

E I B , E

E
I B ,or E

o Covers: o o

Everypointoftheothergeometryisapointofthisgeometry. T*****FF*or*T****FF*or****T*FF*

I I B E

I I B , E

I I B ,or E

5of85

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


I I B E B E

o o

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

o o

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

Disjoint: o o Thetwogeometrieshavenopointincommon. FF*FF****

I I B E

Intersects:NOTDisjoint o Thetwogeometrieshaveatleastonepointincommon.

6of85

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

o o

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

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

I I B , E

E
I B ,or E

o Within: o

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

7of85

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 8of85

Intersection: o Computesageometryrepresentingthepointssharedbythisgeometry andtheothergeometry.

o SymetricDifference: o

Computesageometryrepresentingthepointsinthisgeometrythatare notpresentintheothergeometry,andthepointsintheothergeometry thatarenotinthisgeometry.

o Union: o

Computesageometryrepresentingallthepointsinthisgeometryand theothergeometry.

9of85

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 controllikethemapcontroltobe usedinterchangeablywithalternatecontrolsthatactlikea 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

10of85

Change the name and path to something appropriate. In this case, we chose Build_A_Map andC:\dev\DotSpatialDev\Tutorial\Components\Ex1.MakesurethattheProjecttypeisVisual C#andWindows.EnsurethattheTemplateissettoWindowsFormsApplication.ThenclickOK.

1.2.2. Step2:AddMapWindowComponents
Thefirststepinanyprojectistoensurethatyouhaveloadedallofthedesignercontrolsand 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 tostoretheMapWindowtools.Youcandothisbyrightclickingonthetoolboxandselecting theAddTaboptionfromthecontextmenu.

Figure4:AddMapWindowTab

Thiswillallowyoutoeditthenameofthetab.WechosetonamethetabMapWindowso thatwecouldeasilykeepthecontrolsfromtheMapWindowlibrarytogether.Onceyouhave added a MapWindow tab, you will want to right click in the blank space below that tab and selectChooseItemsfromthecontextmenu.

11of85

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. 12of85


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, orothercapabilities.ThisisnotinanywayrequiredbytheMapWindowGIScomponents,but ratherissimplyaconvenientstartingpointforanewapplication.TheMenuStripisfoundunder the All Windows Forms tab in the toolbox. Simply drag the MenuStrip listed there onto the mainform.

13of85


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

14of85

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

Figure11:AddaSplitContainerControl

Figure12:AddaMap

15of85

Oncetheseparatepanelsexist,wecanaddthemaptotheproject.Whenaddingthemap,it willlikelybethewrongsizeforthepanelthatwecreated.Inordertoallowtheusertoresize 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
Becausethe LegendandToolboxcanbothexistin supportofthemap,anditisnotcriticalto havebothofthesetoolsvisibleatthesametime,forthisprojectwewilltakeadvantageofthe .NetTabcontroltohelpreusethesamespacemoreeffectively.Becausethesecomponentsare interchangeable,theTabcontrolisnotnecessary,andsecondsplitpanel,fixedpanels,oreven thirdpartydockingpanelsareallacceptablealternativesthatwillnotaffecttheproperbehavior ofthemap,legendortoolbox.

Figure13:AddaTabControl

Inthisinstanceweaddedthetabcontroltotheleftpanel,andchangedthetextonthetwotabs toreadLegendandToolbox.Thiscanbedonethroughthepropertygridthatappearswhenyou activatethetabcontrolbyclickingonitafterithasbeenaddedtothemainform.

16of85


Figure14:AddLegend

Addingthelegendfollowssimilarrulestoaddingthemap.Youcansimplydragthisontopof thetabcontrolwhentheLegendtabisselected.Thiswillautomaticallytellthedesignerthat thelegendcontrolwillonlyappearwhentheLegendtabisselected.Likethemap,thelegend 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.

17of85

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 toshowthelayersfromthemap,we need to link things together. The map has a property for the Legend and ProgressHandler.Setthesetolegend1and mwStatusStrip1respectively.
Figure16:LinkMap

Figure17:LinkToolStrip

18of85

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 accesstheGIScontrols.Nowthattheprojectisconnectedtogether,wecanstartourproject 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 downloadedandextractedtheshapefiles,youwillseea.shp,a.shxanda.dbffileallwiththe samenamebeforetheextension.ThisisthebasicfileformatknownasanESRIshapefile,andis acommonlyusedformatforGISanalysisbecauseitisportableandhasanopenstandardandso iswidelycompatiblebetweendifferentGISsoftwarevendors.

19of85


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.

20of85

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,forwhichthisdocumentisbeingwritten,IamdownloadingsomebasicAustralian datasets.SometimesbasicGISdataisofferedonsitesforfreeinthehopesofpromotingthe 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 misleadingbecauseitdoesnotcontainanyofthemajorpopulatedcityareas.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.

21of85

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 separatingthelargercitiesfromthesmallones.Toseethetoolbox,simplychangethetabto theToolboxtab.

HelpTip

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

Figure21:CalculateAreas

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


Figure22:NewlyAddedAreas

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

Figure23:CalculateCentroid

Theshapefilecreatedbycalculatingthecentroidswillnowbeagoodrepresentationofthecity locationsforbuiltupareas,andinaddition,itwillgiveusanapproximatemeasureofthesizeof thebuiltupareausingtheareaattribute.

23of85


Figure24:TooManyCities

1.3.4. Step4:SubsamplebyAttributes
Ascanbeseenfromthefigureabove,thereareafewtoomanycitiesvisibletomakeagood 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

24of85


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.

25of85


Figure28:PrimaryRoads

1.3.7. Step7:SelectPoliticalBoundsbyClicking

Figure29:SelectMajorAreas

Selectingbyattributesisnottheonlywaytonarrowdownthefeaturesthatyouwanttouse. 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 downthe[Shift]keyallowsyoutoselectmultiplelayersatonetime.Onceyouhaveselected themajorpolygons,createanewlayerthesamewaybyusingthecreatelayerfromselection optioninthelegend.Finally,exportthedatatocreateasimplifiedcontinentalshapefile.This willmakelabelingexerciseseasierbecausetheresultwillnotbeclutteredbylabelingthesmall islandsaroundAustralia.

26of85


Figure30:ActivateLabeling

1.3.8. Step8:ApplyLabeling

Figure31:ApplyLabels

27of85


Figure32:AppliedLabels

28of85

1.4.

ProgrammaticPointSymbology

Unliketheprevioussection,wherewewereassumingthatthereaderwouldperformeachstep, in this section, we will explore the most basic features of the extremely powerful symbology toolkitprovidedbyDotSpatial,butlistedundercompletelyindependentobjectives.Theseare 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 makestheassumptionthatyouareeitherwritingaplugin,or elsearebuildingyourownGIS 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. Tobeginthisexercise,wewillneedthedatasetscreatedaspartofexercise2.Wewillalsobe workingwithacopyofthevisualstudioprojectthatwecreatedinexercise1,tohammerinthe pointthatyoudonotneedtobeworkingwiththeMapWindow6executable,butrathercanbe workingdirectlywiththecomponentsinanewproject.Thefirststepistoexploreaddingdata tothemapprogrammatically.

1.4.1. AddaPointLayer

Objective:

AddAPointLayerToTheMap

FeatureSet fs = new FeatureSet(); fs.Open(@"[YourFolder]\Ex3\Data\CitiesWithAreas.shp"); IMapFeatureLayer myLayer = map1.Layers.Add(fs);

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 foldercontainingtheseexercisesonyourcomputer.Finally,thelastlineaddsthedatatothe map,andreturnsalayerhandlethatcanbeusedtocontrolthesymbology.Icanaddthelines 29of85

ofcodeaboveinthemainformbyoverridingtheOnShownmethod.Thatway,whentheform isshownforthefirsttime,itlaunchesthemap.TheFeatureSetvariablegivesusaccesstoall 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.

30of85

We did not overlook the possibility ofwanting 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.Theexactappearanceofthisfunctionwilldependontheversionofvisualstudio, as well as whether or not you have any extensions like ReSharper loaded. If XML comments havebeengeneratedfortheproject,(whichtheyhavebeenforMapWindow6.0)youwillnot only see the methods, properties and events available, but you will also see help for each of thesemethodsthatextendstotheright. Methodsareidentifiedbyhavingapurplebox.Extensionmethodsarerepresentedbyapurple boxwithabluearrowtotherightofthatbox.Insteadofhavingtheprogrammingcodebuilt intotheclass,thecodeisactuallyseparate,inanexternalstaticmethod.Usingthistechnology, it becomes easy to associate a behavior like Intersects directly with the feature, but without everyexternaldataproviderhavingtorewritetheintersectioncodeitself.

31of85

1.4.2. SimpleSymbols

Objective:

MakeYellowStars

private void MakeYellowStars(IMapFeatureLayer myLayer) { myLayer.Symbolizer = new PointSymbolizer(Color.Yellow, PointShapes.Star, 16); }

Becauseweknowinadvancethatweareworkingwithpoints,wedonthavetoworkdirectly withtheexistingclasses,orusecasting.Wecansimplyusetheconstructor.IfwepassmyLayer fromtheearliercodeintothemethodabove,wewillautomaticallycreatetheoutpointshown inthefollowingimage.

Figure35:YellowStar

Onethingthatyoumightnoticeisthatthebordersofthestarsarehardtoseebecauseweonly specifiedonecolor,andthatcolorwasthefillcolor.Inordertogivethestarsblackoutlines,we needtocallaslightlydifferentmethod.


myLayer.Symbolizer = new PointSymbolizer(Color.Yellow, PointShapes.Star, 16); myLayer.Symbolizer.SetOutline(Color.Black, 1);

32of85


Figure36:YellowStarswithOutlines

Youwillnoticethatthelayerdoesnotcontrolthesecharacteristicsdirectly.Instead,itusesa 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 complexsymbolsthathavemultiplelayers.AmethodlikeSetOutlinemayormaynotworkas expectedineverycase,sincesometypesofsymbolsdonotevensupportoutlines.However,if we inspect the parameters that we can control above, we already have the basic symbology optionsthatwereprovidedinpreviousversionsofMapWindow.

1.4.3. CharacterSymbols

Objective:

UseCharacterSymbols

Inadditiontothebasicsymbols,MapWindow6.0alsoprovidesaccesstousingcharactersasa 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.

33of85

Figure37:FontsinControlPanel

Clickingonthisfolderwillopenthefoldershowingallofthecurrentlyinstalledtruetypefonts. Rightclickanywhereinthisfolderthatisnotdirectlyononeoftheexistingfonts,andyouwill expose the context menu shown in the following figure. Choose Install New Font. You will havetobrowsetoyourrecentlydownloadedandunzipped.ttffile.Inthiscaseweareusingthe Military.ttffile.

Figure38:RightClicktoInstallNewFont

34of85

WecanverifythatthenewfontisavailabledirectlybyrunningMapWindow6.0,orournewly create program, adding a point layer, and then symbolizing with character symbols. To use charactersymbols,doubleclickonthesymbolinthelegend.ThiswillopenthePointSymbolizer Dialog.ThereisaComboboxnamedSymbolTypewhichenablestheusertochooseanew symboltype.Inthiscase,wewanttochooseCharacter.

Figure39:SwitchToCharacters

Figure40:ChooseMilitary

Onceyouselectmilitary,theiconslistedbelowinthecharacterselectiondropdownshouldbe replaced with the new military symbols that we have just downloaded. Because many GIS 35of85

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.Symbolizer = new PointSymbolizer('M', "Military", Color.Blue, 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 themilitarysymbolsslightlyoffcenter.However,moreprofessionallycreatedsymbolswillbe centeredcorrectlysincetheywillhavearealisticheightvaluethatcanbeusedforcentering.It is also possible to create custom glyphs for use as point symbols using various font editor softwarepackages.AgoodcommercialexampleisFontCreator,whichhasa30dayfreetrial andcanbepurchasedforabout$100here:http://www.highlogic.com/download.html.Inthe spiritofopensource,however,therearealsoopensourceoptionsavailablesuchasFontForge: http://fontforge.sourceforge.net/ and Font Editor: http://fonteditor.org/ both of which are completelyfree.

36of85

1.4.4. ImageSymbols

Objective:

UseImageSymbols

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 Tousethissymbolprogrammatically,firstdownloadtheimagetoafile.Onceyouhavesaved 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

37of85


Figure43:Images.resxResource

Choose Resources File from the available Templates, then name the resource file Images, and clickAdd.Fromsolutionexplorer,simplydoubleclickthenewlyaddedImagesresourcefileto openit.Addingitthefirsttimeshouldautomaticallyopentheresourcefileasatab.Underthe AddResourceoptioninthetoobarjustbelowtheImages.resxtab,chooseAddExistingFile

Figure44:AddanExistingFile

Thensimplybrowsetothefilewejustdownloaded,andaddittotheresourcefile.Tomakeit easiertofind,wecanrenamethefileTiger.

38of85


Figure45:RenametoTiger

Now,wecanprogrammaticallyreferencethisimageanytimeusingtheImages.Tigerreference. Besuretobuildtheprojectafteraddingtheimagetotheresourcefile,orelsetheIntellisense willnotshowtheTigerimageyet.Addingtheimagetoaresourcefilesetsuptheframeworkfor thefollowinglineofcodewherewewillspecifytousetheTigerimageforthepointsymbology:


myLayer.Symbolizer = new PointSymbolizer(Images.Tiger, 48);

Figure46:TigerImages

39of85

1.4.5. PointCategories

Objective:

UsePointSymbolCategories

Forthenext topic,Iwillintroducetheconceptofcasting.In manycases,methodsor 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 forpoints,oneforlines,andoneforpolygons.Whatismostimportanthereisthatthereare 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 40of85

betweenhavingtocasteverysingleobjecteverytime,andonlyhavingtocastthefeaturelayer once. WewillbesymbolizingbasedontheAreafield.Theareaswerecalculatedfromthepolygonsin exercise2,sowecanbeassuredthatthecitieswithareasshapefilethatweareaddinghasan Areafield,andlookingatthetablebelow,wecanseethatareasonablecutoffforpickingthe 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.
IMapPointLayer myPointLayer = myLayer as IMapPointLayer; if(myPointLayer == null) return; PointScheme myScheme = new PointScheme(); myScheme.Categories.Clear(); PointCategory smallSize = new PointCategory(Color.Blue, PointShapes.Rectangle, 4); smallSize.FilterExpression = "[Area] < .01"; smallSize.LegendText = "Small Cities"; myScheme.AddCategory(smallSize); PointCategory largeSize = new PointCategory(Color.Yellow, PointShapes.Star, 16); largeSize.FilterExpression = "[Area] >= .01"; largeSize.LegendText = "Large Cities"; largeSize.Symbolizer.SetOutline(Color.Black, 1); myScheme.AddCategory(largeSize); myPointLayer.Symbology = myScheme;

41of85


Figure49:CityCategoriesbyArea

The square brackets in the filter expression are optional, but recommended to help clarify fieldnamesintheexpression.Whatissignificanthereisthatwedidnothavetowritecodeto actuallyloopthroughallofthecityshapes,testtheareaattributeprogrammatically,andthen assignasymbolschemebasedonthecharacter.Instead,wesimplyallowthebuiltinexpression parsingtotakeoverandhandlethedrawingforus.Thisallowsforprogrammerstoworkwith theobjectsinawaythatdirectlymimicshowusersworkwiththesymbologycontrols.Andjust likethelayerdialogcontrolsallowyoutospecifyschemes;thoseschemescanalsobecontrolled programmatically.

IMapPointLayer myPointLayer = myLayer as IMapPointLayer; if (myPointLayer == null) return; PointScheme myScheme = new PointScheme(); myScheme.Categories.Clear(); myScheme.EditorSettings.ClassificationType = ClassificationTypes.Quantities; myScheme.EditorSettings.IntervalMethod = IntervalMethods.Quantile; myScheme.EditorSettings.IntervalSnapMethod = IntervalSnapMethods.Rounding; myScheme.EditorSettings.IntervalRoundingDigits = 5; myScheme.EditorSettings.TemplateSymbolizer = new PointSymbolizer(Color.Yellow, PointShapes.Star, 16); myScheme.EditorSettings.FieldName = "Area"; myScheme.CreateCategories(myLayer.DataSet.DataTable); myPointLayer.Symbology = myScheme;

42of85


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 toset 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 propertyallowsyoutocontrolthebasicappearanceofthecategoriesforanypropertythatis notbeingcontrolledbyeitherthesizeorcolorramping.Forexample,ifwewantedtoaddblack borderstothestarsabove,wewouldsimplyaddthattothetemplatesymbolizer.Inthiscase we chose to make them appear as stars and controlled them to have equal sizes since UseSizeRangedefaultstofalse,butUseColorRangedefaultstotrue.

43of85


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

Objective:

YellowstarsinaBlueCircle

One of the new additions to how symbols work is that you are no longer restricted to representingthingsusingasinglesymbol.Complexsymbolscanbecreated,simplybyadding 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 Subclasscanbeused.Forworkingwithindividualsymbolsinthecollection,youmayneedto testwhattypeofsymbolyouareworkingwithbeforeyouwillbeabletocontrolitsproperties.

44of85


Figure52:PointSymbolClassDiagram

Theclassdiagramaboveshowstheorganizationoftheindividualsymbols.
PointSymbolizer myPointSymbolizer = new PointSymbolizer(Color.Blue, PointShapes.Ellipse, 16); myPointSymbolizer.Symbols.Add( new SimpleSymbol(Color.Yellow, PointShapes.Star, 10)); myLayer.Symbolizer = myPointSymbolizer;

Figure53:BlueCircleswithYellowStars

45of85

1.5.

ProgrammaticLineSymbology

1.5.1. AddingLineLayers

Objective:

AddLineLayer

Linelayersoperateaccordingtothesamerulesaspointsforthemostpart,exceptthatinstead ofindividualsymbols,wecanhaveindividualstrokes.Thedefaultsymbologyistohaveasingle linelayerofarandomcolorthatisonepixelwide.

FeatureSet fs = new FeatureSet(); fs.Open(@"[Your Folder]\Ex3\Data\MajorRoads.shp"); IMapFeatureLayer myLayer = map1.Layers.Add(fs);

Figure54:AddLineLayer

SimpleLinesymbols

Objective:

BrownRoads

private void BrownRoads(IMapFeatureLayer myLayer) { myLayer.Symbolizer = new LineSymbolizer(Color.Brown, 1); }

46of85


Figure55:BrownLines

1.5.2. OutlinedSymbols

Objective:

YellowRoadswithBlackOutlines

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 cleanlookattheintersections,alltheblacklinesaredrawnfirst.Then,alltheyellowlinesare drawn.Thisway,theintersectionsappeartohavecontinuouspathsofyellow,ratherthanevery individualshapebeingterminatedbyacurvingblackoutline.

LineSymbolizer road = new LineSymbolizer(Color.Yellow, 5); road.SetOutline(Color.Black, 1); myLayer.Symbolizer = road;

47of85


Figure56:YellowRoadswithOutlines

1.5.3. UniqueValues

Objective:

RoadsColoredbyUniqueTileID

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 saturationandlightnessintherangefrom.7to.8.Theeditorsettingscanbeusedtocontrol 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. 48of85

LineScheme myScheme = new LineScheme(); myScheme.EditorSettings.ClassificationType = ClassificationTypes.UniqueValues; myScheme.EditorSettings.FieldName = "tile_id"; myScheme.CreateCategories(myLayer.DataSet.DataTable); myLayer.Symbology = myScheme;

Figure57:RoadswithUniqueValues

1.5.4. CustomCategories

Objective:

CustomRoadCategories

Inthepreviousexample,thelegendshowsacollapsiblefieldnameinordertoclarifythe meaningofthevaluesappearingforeachcategory.Thiscanalsobeaccomplishedmanuallyby controllingtheAppearsInLegend propertyon the scheme.If thisisfalse,thecategorieswill 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.
LineScheme myScheme = new LineScheme(); myScheme.Categories.Clear(); LineCategory low = new LineCategory(Color.Blue, 2); low.FilterExpression = "[tile_id] < 36"; low.LegendText = "Low"; LineCategory high = new LineCategory(Color.Red, Color.Black, 6, DashStyle.Solid, LineCap.Triangle); high.FilterExpression = "[tile_id] >= 36";

49of85

high.LegendText = "High"; myScheme.AppearsInLegend = true; myScheme.LegendText = "Tile ID"; myScheme.Categories.Add(low); myScheme.Categories.Add(high); myLayer.Symbology = myScheme;

Figure58:CustomLineCategories

1.5.5. CompoundLines

Objective:

LineswithMultipleStrokes

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 wellas specifying line decorations. Decorationsarebasicallyjustpointsymbolsthatcanappearattheendofthestroke,orevenly arrangedalongthelengthofthestroke.

50of85


Figure59:StrokeClassHierarchy

In this example, we will take advantage of several powerful symbology options. We will use cartographicstrokesinordertocreatetwoverydifferenttypeoflinestyles.Inthefirstcase,we willcreatebrownrailroadties.UsingthestandardDotoptionforasimplecartographicline wouldnotworkbecausethedotscreatedareproportionaltothelinewidth.However,witha customdashpattern,itispossibletosetthelinessothatthedashesarethinnerthantheline 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 acrossthelinethewaythetiesdo.Instead,wewanttohavetwothinlinesthatappearalong thepathwidth.Todothis,wetakeadvantageofaCompoundArray.Withthecompoundarray, youareexpressingtheactualoffsetsforthestartandendpositionsalongthecompoundarray, where0istheleftofthelineand1istheright.Insomecases,linesthataretwothinmaynot getdrawnatall,sotrytoensurethatthewidthofthelinesrepresentedintheCompoundarray workouttobejustslightlylargerthan1toensurethatthelinesultimatelygetdrawn. Inthecodebelow,thestartandendcapsarealsospecified.Bydefaultthesearesettoround, whichwillendupproducinggraycirclesateachoftheintersections.Byspecifyingthattheend capsshouldbeflat,noextensionwillbeaddedtoendsofthelines.Roundedcapslookthebest 51of85

forsolidlinesbecauseitcreatesakindofrounded,bufferedlooktoroadsthatarewiderthan onepixel.
LineSymbolizer mySymbolizer = new LineSymbolizer(); mySymbolizer.Strokes.Clear(); CartographicStroke ties = new CartographicStroke(Color.Brown); ties.DashPattern = new float[] {1/6f, 2/6f}; ties.Width = 6; ties.EndCap = LineCap.Flat; ties.StartCap = LineCap.Flat; CartographicStroke rails = new CartographicStroke(Color.DarkGray); rails.CompoundArray = new float[]{.15f,.3f,.6f,.75f}; rails.Width = 6; rails.EndCap = LineCap.Flat; rails.StartCap = LineCap.Flat; mySymbolizer.Strokes.Add(ties); mySymbolizer.Strokes.Add(rails); myLayer.Symbolizer = mySymbolizer;

Figure60:MultiStrokeRailRoads

52of85

1.5.6. LineDecorations

Objective:

LinesDecoratedbyStars

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.
LineDecoration star = new LineDecoration(); star.Symbol = new PointSymbolizer(Color.Yellow, PointShapes.Star, 16); star.Symbol.SetOutline(Color.Black, 1); star.NumSymbols = 1; CartographicStroke blueStroke = new CartographicStroke(Color.Blue); blueStroke.Decorations.Add(star); LineSymbolizer starLine = new LineSymbolizer(); starLine.Strokes.Clear(); starLine.Strokes.Add(blueStroke); myLayer.Symbolizer = starLine;

Figure61:LineswithStarDecorations

53of85

1.6.

ProgrammaticPolygonSymbology

1.6.1. AddPolygonLayers

Objective:

AddaPolygonLayertotheMap

Polygon layers are another representation of vector content where there is an area being surroundedbyaboundary.Polygonscanhaveanynumberofholes,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.
FeatureSet fs = new FeatureSet(); fs.Open(@"[Your folder]\Ex3\Data\MajorBoundaries.shp"); IMapFeatureLayer myLayer = map1.Layers.Add(fs);

Figure62:AddMajorBoundaries

54of85

1.6.2. SimplePatterns

Objective:

SpecifyBluePolygons

Thesimplesttaskwithpolygonsistosetthefillcolorforthosepolygons.Youwillsee that specifying only an interior fill creates a continuous appearance, since the normal boundariesareadjacentandallthesamecolor.

private void BluePolygons(IMapFeatureLayer myLayer) { PolygonSymbolizer lightblue = new PolygonSymbolizer(Color.LightBlue); myLayer.Symbolizer = lightblue; }

Figure63:BlueFillOnly Figure64:WithBlueBorder

55of85

PolygonSymbolizer lightblue = new PolygonSymbolizer(Color.LightBlue); lightblue.OutlineSymbolizer = new LineSymbolizer(Color.Blue, 1); myLayer.Symbolizer = lightblue;

1.6.3. Gradients

Objective:

FullLayerGradient

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.
PolygonSymbolizer blueGradient = new PolygonSymbolizer(Color.LightSkyBlue, Color.DarkBlue, 45, GradientTypes.Linear); blueGradient.SetOutline(Color.Yellow, 1); myLayer.Symbolizer = blueGradient;

56of85


Figure65:ContinuousBlueGradient

1.6.4. IndividualGradients

Objective:

ShapeSpecificGradients

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.

57of85


Figure66:MajorBoundariesFields

PolygonSymbolizer blueGradient = new PolygonSymbolizer(Color.LightSkyBlue, Color.DarkBlue, -45, GradientTypes.Linear); blueGradient.SetOutline(Color.Yellow, 1); PolygonScheme myScheme = new PolygonScheme(); myScheme.EditorSettings.TemplateSymbolizer = blueGradient; myScheme.EditorSettings.UseColorRange = false; myScheme.EditorSettings.ClassificationType = ClassificationTypes.UniqueValues; myScheme.EditorSettings.FieldName = "nam"; myScheme.CreateCategories(myLayer.DataSet.DataTable); myLayer.Symbology = myScheme;

Figure67:IndividualGradients

1.6.5. MultiColoredGradients

58of85

Objective:

CoolColorswithGradient

Onethingthatmayseemlessthanobviousisthatinthepreviousexercisewespecifiedthatthe UseGradient property should be false. This does not prevent the template symbolizer from havingagradient.Instead,itpreventsthesymbolizerfromoverridingtheoriginal,presumably simpler,templatewithagradientsymbol.Thegradientsymbolwillbecalculatedusingacolor fromthecolorrange,butthenwillmaketheupperleftalittlelighterandthelowerrightalittle darker.Thatway,youcanhavethesamesubtlegradientapplied,butstillusedifferentcolors foreachcategory.Toboot,thedefaultpolygonsymbolizerhasaborderthatisthesamehue, butslightlydarker,whichtendstocreateaniceoutlinecolor.
PolygonScheme myScheme = new PolygonScheme(); myScheme.EditorSettings.StartColor = Color.LightGreen; myScheme.EditorSettings.EndColor = Color.LightBlue; myScheme.EditorSettings.ClassificationType = ClassificationTypes.UniqueValues; myScheme.EditorSettings.FieldName = "nam"; myScheme.EditorSettings.UseGradient = true; myScheme.CreateCategories(myLayer.DataSet.DataTable); myLayer.Symbology = myScheme;

Figure68:UniqueCoolColorsWithGradient

59of85

1.6.6. CustomPolygonCategories

Objective:

CustomPolygonCategories

An important terminology difference here that we have been using is the difference between SymbolizerandSymbology.WithSymbology,wearealwaysreferringtoascheme,whichcan 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.
PolygonScheme scheme = new PolygonScheme(); PolygonCategory queensland = new PolygonCategory(Color.LightBlue, Color.DarkBlue, 1); queensland.FilterExpression = "[nam] = 'Queensland'"; queensland.LegendText = "Queensland"; PolygonCategory nWords = new PolygonCategory(Color.Pink, Color.DarkRed, 1); nWords.FilterExpression = "[nam] Like 'N*'"; nWords.LegendText = "N - Words"; scheme.ClearCategories(); scheme.AddCategory(queensland); scheme.AddCategory(nWords); myLayer.ShowLabels = true; myLayer.Symbology = scheme;

Figure69:CustomCategories

60of85

1.6.7. CompoundPatterns

Objective:

MultiLayerPatterns

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 multiplepatterns,wesimplyclearedoutthedefaultpatternthatwasautomaticallycreatedas partofthesymbolizer.Whenweaddanewpattern,thenewpatterngetsdrawnontopofthe previouspatterns,sothelastpatternaddedhasthehighestdrawingpriority.Inthecodebelow, thenewpatternhasitsbackgroundcolorsettotransparent,yetintheimagebelowweseethat thecoloringisredstripesagainstabluebackground.Thepatternbelowtheredstripepatternis thedefaultpattern,andwillberandomlygeneratedasadifferentcoloreachtime. 61of85

PolygonSymbolizer mySymbolizer = new PolygonSymbolizer(); mySymbolizer.Patterns.Add( new HatchPattern(HatchStyle.WideDownwardDiagonal, Color.Red, Color.Transparent)); myLayer.Symbolizer = mySymbolizer;

Figure71:Hatchpatterns

1.7.

ProgrammaticLabels

Objective:

Labels

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.
IMapLabelLayer labelLayer = new MapLabelLayer(); labelLayer.Symbology.Categories[0].Expression = "Test"; myLayer.ShowLabels = true; myLayer.LabelLayer = labelLayer;

62of85


Figure72:AddingTestlabels

1.7.1. FieldNameExpressions

Objective:

FieldNameLabels

Thefieldnameinthiscasedescribesthenameoftheterritory.Inorderforthenamefieldto appearinthelabeltext,wesimplyencloseitinsquarebrackets.Thisputstogetheraversatile scenariowhereyoucanbuildcomplexexpressionswithvariousfieldnames.Youcanalsouse escapecharacterstocreatemultilinelabels.


IMapLabelLayer labelLayer = new MapLabelLayer(); ILabelCategory category = labelLayer.Symbology.Categories[0]; category.Expression = "[nam]"; category.Symbolizer.Orientation = ContentAlignment.MiddleCenter; myLayer.ShowLabels = true; myLayer.LabelLayer = labelLayer;

63of85


Figure73:FieldNameLabels

1.7.2. MultiLineLabels

Objective:

MultiLineLabels

Creating multiline labels is simple, since all you have to do is use the standard .Net newline character,whichinC#isaddedusingthe/n,whileinvisualbasicyouwouldcombinethetwo stringswithavbNewLineelementbetweenthem.Therelativepositionofthemultiplelinesis controlledbytheAlignmentpropertyonthelabelSymbolizer.Inordertominimizeconfusion, the labels follow the same organization with a scheme, categories and symbolizers. A filter expressionalsoallowsustocontrolwhichlabelsareadded.
IMapLabelLayer labelLayer = new MapLabelLayer(); ILabelCategory category = labelLayer.Symbology.Categories[0]; category.Expression = "[nam]\nID: [Cnt_nam]"; category.FilterExpression = "[nam] Like 'N*'"; category.Symbolizer.BackColorEnabled = true;

64of85

category.Symbolizer.BorderVisible = true; category.Symbolizer.Orientation = ContentAlignment.MiddleCenter; category.Symbolizer.Alignment = StringAlignment.Center; myLayer.ShowLabels = true; myLayer.LabelLayer = labelLayer;

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

Objective:

TranslucentLabels

The background color in this case has been set to transparent by specifying an alpha value of somethinglessthan255whensettingtheBackColor.Frequently,thereareopacityproperties available in addition to the actual color, but that is just there for serialization purposes and is simplyashortcuttothealphachannelofthecolorstructure.Thisexamplealsoillustratesthe useofthecompoundconjunctionORinthefilterexpression.Otherpowerfultermsthatcan be used are AND and NOT as well as the combined expression Is Null which is case insensitiveandcanidentifynullvaluesseparatelyfromemptystringsforinstance.Noticethatis 65of85

not = null which doesnt work with .Net DataTables. For the negative you could use NOT [nam]isnull.
IMapLabelLayer labelLayer = new MapLabelLayer(); ILabelCategory category = labelLayer.Symbology.Categories[0]; category.Expression = "[nam]\nID: [Cnt_nam]"; category.FilterExpression = "[nam] = 'Tasmania' OR [nam] = 'Queensland'"; category.Symbolizer.BackColorEnabled = true; category.Symbolizer.BackColor = Color.FromArgb(128, Color.LightBlue); category.Symbolizer.BorderVisible = true; category.Symbolizer.FontStyle = FontStyle.Bold; category.Symbolizer.FontColor = Color.DarkRed; category.Symbolizer.Orientation = ContentAlignment.MiddleCenter; category.Symbolizer.Alignment = StringAlignment.Center; myLayer.ShowLabels = true; myLayer.LabelLayer = labelLayer;

Figure75:TranslucentLabels

1.8.

ProgrammaticRasterSymbology

66of85

1.8.1. DownloadData

Objective:

DownloadaRasterLayer

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 pluginthatisexclusivetothewindowsplatformusingFrankWarmerdansGDALlibrariesand 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/

67of85


Figure76:EarthExplorer

Ifthelinkabovedoesntwork,youcantrysearchingforUSGSandlookingforlinksthatallow 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 openitwithMapWindow6.Beforewecanworkwiththedataprogrammatically,wewilluse MapWindow6tochangethedataformattobgd.ThisisactuallyassimpleasopeningtheBIL, rightclickingonthelegendandchoosingexportdata.Dontworryifthecoloringlooksstrange. Itisusualforthenodatavaluestodistortthecoloringuntiltheycanbeproperlyexcludedfrom thesymbology.Fornow,weareonlyconcernedwithconvertingtheformattoan*.bgdfile.

68of85


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

Objective:

AddARasterLayer

69of85

Raster r = new Raster(); r.Open(@"[Your Folder]\Ex3\Data\DEM\Elevation.bgd"); IMapRasterLayer myLayer = map1.Layers.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 offbyanunexpectednodatavalue.Wecanusethesymbolizerinterfaceforrastersineither MapWindow6.0oryournewprojectbydoubleclickingnexttotheelevationlayerinthelegend. Thiswilllaunchadialogliketheonebelow.

70of85


Figure80:Statistics

Wecanseerightawaythatofthe manysamplepointsthatweretakenfromthisimage,only oneortwovaluesintheextremeupperrangeof32,000and65,000respectivelycanthrowoff theentiresymbolicrangeforthisraster.Wecanrepairthiseasilybyslidingthesymbolicsliders downtotheleftendoftheplot.Whatislessobviousuntilyoustartzoominginisthatalmostall ofthevaluesareeffectivelynodatavaluesof0andareshowinguponourplot.Youcanuse themousewheeltozoomintoandoutofhistogram,butinthiscaseitwillbeverydifficultto 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.

71of85


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

72of85

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

Objective:

ControlCategoryRange

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.
private void ControlRange(IMapRasterLayer myLayer) { myLayer.Symbolizer.Scheme.Categories[0].Range = new Range(1, 150); myLayer.Symbolizer.Scheme.Categories[0].ApplyMinMax(myLayer.Symbolizer.EditorSettings); myLayer.Symbolizer.Scheme.Categories[1].Range = new Range(150, 800); myLayer.Symbolizer.Scheme.Categories[1].ApplyMinMax(myLayer.Symbolizer.EditorSettings); myLayer.WriteBitmap(); }

73of85

Figure84:ProgrammaticRestrictRange

1.8.4. ShadedRelief

Objective:

AddLighting

myLayer.Symbolizer.Scheme.Categories[0].Range = new Range(1, 150); myLayer.Symbolizer.Scheme.Categories[0].ApplyMinMax(myLayer.Symbolizer.EditorSettings); myLayer.Symbolizer.Scheme.Categories[1].Range = new Range(150, 800); myLayer.Symbolizer.Scheme.Categories[1].ApplyMinMax(myLayer.Symbolizer.EditorSettings); myLayer.Symbolizer.ShadedRelief.ElevationFactor = 1; myLayer.Symbolizer.ShadedRelief.IsUsed = true; myLayer.WriteBitmap();

74of85

Figure85:WithLighting

1.8.5. PredefinedSchemes

Objective:

UseGlacierColoring

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.Symbolizer.Scheme.ApplyScheme(ColorSchemes.Glaciers, myLayer.DataSet); myLayer.Symbolizer.Scheme.Categories[0].Range = new Range(1, 150); myLayer.Symbolizer.Scheme.Categories[0].ApplyMinMax(myLayer.Symbolizer.EditorSettings); myLayer.Symbolizer.Scheme.Categories[1].Range = new Range(150, 800); myLayer.Symbolizer.Scheme.Categories[1].ApplyMinMax(myLayer.Symbolizer.EditorSettings); myLayer.Symbolizer.ShadedRelief.ElevationFactor = 1; myLayer.Symbolizer.ShadedRelief.IsUsed = true; myLayer.WriteBitmap();

75of85

Figure86:Glaciers

1.8.6. EditRasterValues

Objective:

FixRasterValues

Previously,wehavebeenusingtrickstocolortheelevationbutwherewedirectlyignoredthe values that were either nodata values that read 0, or else apparently bad data values that showedimpossiblevalueslike65,000.Inthissectionwewillusetherasterdataclassitselfin order to repair the values programmatically. This will only alter the copy that we have in memoryandwillnotoverwritethevaluestothediskunlesswespecificallyinstructittodoso. Intheexamplebelow,wecancyclethroughallofthevaluesintherasterusingtheNumRows 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.

76of85

Raster r = new Raster(); r.Open(@"C:\dev\MapWindow6Dev\Tutorial\Components\Ex3\Data\DEM\Elevation.bgd"); r.NoDataValue = 0; for(int row = 0; row < r.NumRows; row++) { for(int col = 0; col < r.NumColumns; col++) { if (r.Value[row, col] > 600) r.Value[row, col] = 600; } } IMapRasterLayer myLayer = map1.Layers.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 havenowlabeledasnodatavalues.Assigningthenodatavaluecanberiskybecausethere maybevaluesthatwereusingtheoldnodatavalue.Thiscaneasilybefixedbycyclingthrough therasterinthesamewayandadjustingvaluessothattheyworkwiththegivenstatistics.

77of85


Figure88:AfterFixingRaster

1.8.7. QuantileBreaks

Objective:

QuantileBreakValues

JustliketheFeatureSets,RasterscanusetheEditorSettingspropertyinordertocustomizehow tobuildschemes,ratherthanhavingtospecifytheschemesdirectly.Thisiswhereourprevious editstofixtherastervaluesbecomemoreimportant.Ifwehadtriedtoapplyquantilebreaks before,insteadofcoloringtherasterappropriately,wewouldhavehadallbutoneoftheranges read00.Now,wegetareasonablerange.


myLayer.Symbolizer.EditorSettings.IntervalMethod = IntervalMethods.Quantile; myLayer.Symbolizer.EditorSettings.NumBreaks = 5; myLayer.Symbolizer.Scheme.CreateCategories(myLayer.DataSet); myLayer.Symbolizer.ShadedRelief.ElevationFactor = 1; myLayer.Symbolizer.ShadedRelief.IsUsed = true; myLayer.WriteBitmap();

78of85


Figure89:QuantileBreaks

Figure90:RasterSymbologyClasses

79of85

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

Class:

MapWinGIS.Point

ThePointclasswasformerlyaclassthatprovidedrapidaccesstoX,YandZvalues. ThisclasshasbeenreplacedbytheCoordinateclass.APoint,asdefinedbytheOGC Simple Feature Specification, has geometry methods like Intersects, and is independentlyavailableinMapWindow6,buthasmanymorecapabilitiesthatjust storingacoordinatelocation.Therefore,thecoordinateclasshastakenoverasthe classtouse.

1.9.2. Extents

Class:

MapWinGIS.Extents

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.

80of85

1.9.3. Shape

Class:

MapWinGIS.Shape

The Shape class in MapWindow 4 was a generic feature and provided basicaccesstothecoordinates,andgavethegeographicextentsforthatshape. Intheold model,theonlyconnectivitybetweena shapeand theattributes was thattheywouldbothhavethesameindex.Inthenewversion,aFeaturehasa 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.

81of85

1.9.4. Shapefile

Class:

MapWinGIS.Shapefile

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 knowwhatkindsofclasseswillbenecessaryinordertoaccessthedataonafile,orpossiblya database or web service. Therefore, we provide the FeatureSet as a kind of wrapper for an internalIFeatureSet.WhentheOpenmethodiscalled,internally,theFeatureSetclassrequests anewIFeatureSetfromthedefaultDataManager.Anyrequestsforfeaturesorotherproperties aresimplypassedtotheinternalfeatureset. 82of85

1.9.5. Grid

Class:

MapWinGIS.Grid

The grid class was a wrapper class that could internally represent an integer, float,short,orevendoublegrid.Themaingoalofthegridclasswastobeableto cyclethroughtherowsandcolumnsofarasterdatafileandgetorsetthevarious numericvalues. ThenewrepresentationiscalledaRaster.UnliketheMapWindowGrid,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 simplyaccessdoubleval=myRaster.Value[7,6].Regardlessofwhatthesource 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 theposition ofarasterinspace. The NoDataValueisalsouseful,asitcanhelp changehowstatisticsarecalculated.

83of85

1.9.6. GridHeader
Class:
The Header was an important part of the grid. It defined the spatial locationslikethelowerleftXandlowerleftYcoordinatesaswellasdefininga cellsize.OneofthelimitationsoftheMapWindow4gridswasthattheydid notsupportskewterms.InMapWindow6.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.

MapWinGIS.GridHeader

1.9.7. Image

Class:

MapWinGIS.Image

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.

84of85

1.10.

ExtensionMethods
Extensions Rasters

Notallofthemethodsaresupporteddirectlyonaraster.Manyuseful methodsareactuallysupportedintheformofExtensionMethods.Forthe raster, this includes useful methods that can alter the raster bounds, like Translate, or Scale, or Rotate. But other useful abilities like CreateHillShade actuallyusetherastervaluesthemselvesinordertocalculateafloatingpoint valuethathelpstocontroltheshadedreliefaspectofanyimagethatiscreated fromaraster.OthermethodslikeGetRandomValues,andGetNearestValueare helpful for doing analysis, but one of the most critical methods is CellToProj andProjToCell,whichallowsthedevelopertoeasilygobackandforthbetween geospatialcoordinatesandtherowandcolumnindicies.

Extensions

Feature

TheFeature,andinfactanyclassthatimplementstheIFeatureinterfacewillbe extendedwiththegeometrymethodsthataresocriticaltovectorcalculations. These not only include the overlay operations like Intersection, Union and SymmetricDifference,butalltheteststhatyoumightwanttouseliketouches 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.

85of85

You might also like