Common Questions About Map Suite Web 2.55
Click on any of the frequently asked questions below to be taken to the
answer.
- If I have the latitude and longitude of a
point, how can I plot it on a map?
- I would like to have more custom properties
(like a tag property) on a map shape object. How can I add my own
properties?
- How do I convert screen coordinates into
world coordinates?
- How do I convert world coordinates into
screen coordinates?
- How can I find a map shape when the user
clicks it?
- How can I find a feature (road, city, etc.)
when the user clicks it?
- How can I zoom in on an area based on a
query?
- How can I label a map feature with specific
text?
- I see a layer can have different zoomLevels.
What would I use this feature for?
- How can I draw a scale bar that displays to
the side of the map (not on top of the map)?
- How can I find out if a certain point is
contained within a certain rectangular area?
- How can I get information about point or
feature from a dbf file?
- Once I have a record number, how can I get
the shape for that record?
- How can I zoom in or out programmatically?
- How can I stop a user from zooming out too
far? Is there a way to limit zooming out?
- How can I set the full extent of a map to
something specific?
- How can I display my data so each item
falls within some group? For example, if I have several cities with
different populations, how could I group these cities into the categories
of small, medium, and large, each with its own symbol on the map?
- How can I display my data so each item is
represented with a special symbol based on a exact textual match (not
categories, classes or ranges)? For example, a lake should be blue, a dry
lake should be brown, etc.
- How can I use my own rendering logic when
the symbol representing an place's location is being drawn?
- How can I have items labeled differently
based on a value in a field in the shape file? For example, if I have
several cities in each country in Europe, I want to show capitals in a
larger font than non-capitals.
- I see that a map can have multiple layers.
Why would I use multiple layers?
- When a user selects a certain feature, I
want to be able to change its symbol to show it is different from the
other features. How would I "highlight" a feature when it is
selected?
- I want a user to be able to draw various
shapes (circles, rectangles, etc.) and I want to execute some custom logic
while the shape is being created. How can I do this?
- What are map shapes and how can I use them?
- How can I define my own custom labeling
plug-in?
- How can I get data from a shape file? Can I
use SQL queries?
- Can I change the data in a shape file, and
if so, how?
- What vector and raster formats are
supported by Map Suite?
- How do I zoom in to Point?
- How do I zoom in to a set of MapShape Points?
- How can I dynamically load controls using
spatial queries?
- Is there a way to highlight map features
based on a SQL query?
- How can I add satellite and aerial imagery
to my project?
If I have the latitude and longitude of a point, how can I
plot it on a map?
All you need to do is, 1) Create a new point, 2) Add that point to the map.
Create a new Webforms project, add a map (name it Map1) to the form, and add
the following code to the form's load event:
C#
using MapSuite;
using
MapSuite.Geometry;
// This first section is only to get a map of US to show.
Map1.MapUnit = MapLengthUnits.DecimalDegrees;
Layer lyr = new Layer(@"..\sampledata\world\cntry02.shp",true);
lyr.ZoomLevelExtentUnit = ZoomLevelExtentUnits.DecimalDegrees;
lyr.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
lyr.ZoomLevel01.GeoStyle = GeoAreaStyles.GetSimpleAreaStyle(GeoColor.KnownColors.LightGray, GeoColor.KnownColors.Black, 1);
Map1.Layers.Add(lyr);
// This second section is all you need
to plot a point if you have the latitude and longitude
PointMapShape pointMapShape = new PointMapShape();
pointMapShape.Shape = new
PointShape(-119.09, 34.32);
pointMapShape.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
pointMapShape.ZoomLevel01.GeoStyle = GeoPointStyles.City1;
pointMapShape.ZoomLevel01.GeoTextStyle = GeoTextStyles.GetSimpleTextStyle(string.Empty, "Arial",
12, GeoFontStyle.Bold, GeoColor.KnownColors.Black);
pointMapShape.Name = "Los
Angles";
Map1.MapShapes.Add(pointMapShape);
VB.NET
Imports MapSuite
Imports
MapSuite.Geometry
' This first section is only to get a map of US to show.
Map1.MapUnit = MapLengthUnits.DecimalDegrees
Dim lyr As New Layer("..\sampledata\world\cntry02.shp",
True)
lyr.ZoomLevelExtentUnit =
ZoomLevelExtentUnits.DecimalDegrees
lyr.ZoomLevel01.ApplyUntilZoomLevel =
ApplyUntilZoomLevel.ZoomLevel18
lyr.ZoomLevel01.GeoStyle =
GeoAreaStyles.GetSimpleAreaStyle(GeoColor.KnownColors.LightGray,
GeoColor.KnownColors.Black, 1)
Map1.Layers.Add(lyr)
' This second section is all you need to
plot a point if you have the latitude and longitude
Dim pointMapShape As New PointMapShape()
pointMapShape.Shape = New
PointShape(-119.09, 34.32)
pointMapShape.ZoomLevel01.ApplyUntilZoomLevel =
ApplyUntilZoomLevel.ZoomLevel18
pointMapShape.ZoomLevel01.GeoStyle =
GeoPointStyles.City1
pointMapShape.ZoomLevel01.GeoTextStyle =
GeoTextStyles.GetSimpleTextStyle(String.Empty, "Arial", 12, GeoFontStyle.Bold,
GeoColor.KnownColors.Black)
pointMapShape.Name = "Los
Angles"
Map1.MapShapes.Add(pointMapShape)
Back to Top
I would like to have more custom properties (like a tag
property) on a map shape object. How can I add my own properties?
Adding custom properties is quite easy. All you have to do is inherit from
one of the classes and add your own custom properties, like in the following
code:
C#
using MapSuite;
using MapSuite.Geometry;
public class MyPointMapShape : PointMapShape
{
private string tag = string.Empty;
public
MyPointMapShape(PointShape pointShape, PointSymbol pointSymbol)
:base(pointShape,pointSymbol)
{
}
public string Tag
{
get
{
return
tag;
}
set
{
tag = value;
}
}
}
VB.NET
Imports MapSuite
Imports MapSuite.Geometry
Public Class
MyPointMapShape
Inherits
PointMapShape
Private m_tag As String = String.Empty
Public Sub New(ByVal pointShape As
PointShape, ByVal pointSymbol As PointSymbol)
MyBase.New(pointShape,
pointSymbol)
End Sub
Public Property Tag() As String
Get
Return
m_tag
End Get
Set(ByVal value As String)
m_tag = value
End Set
End Property
End
Class
From here, you can add as many custom properties as you would like.
Back to Top
How do I convert screen coordinates into world coordinates?
The map control has a method ToWorldCoordinate which takes in a PointF
object (a point in canvas / screen coordinates). Returned is a PointR object (a
point in world coordinates).
C#
System.Drawing.PointF
controlPointF = new System.Drawing.PointF(45, 34);
PointR pointR =
Map1.ToWorldCoordinate(controlPointF);
PointShape p0 = new PointShape(pointR.X,
pointR.Y);
VB.NET
Dim controlPointF As New System.Drawing.PointF(45, 34)
Dim pointR As PointR =
Map1.ToWorldCoordinate(controlPointF)
Dim p0 As New PointShape(pointR.X, pointR.Y)
Back to Top
How do I convert world coordinates into screen coordinates?
The map control has a method ToCanvasCoordinate which takes in a PointR
object (a point in world coordinates). Returned is a PointF object (a point in
canvas / screen coordinates).
C#
PointShape pointShape = new PointShape(-119.09,
34.32);
System.Drawing.PointF screetPoint =
Map1.ToCanvasCoordinate(pointShape.X, pointShape.Y);
VB.NET
Dim pointShape As New PointShape(-119.09, 34.32)
Dim screetPoint As
System.Drawing.PointF = Map1.ToCanvasCoordinate(pointShape.X, pointShape.Y)
Back to Top
How can I find a map shape when the user clicks it?
First, set the Map.Mode to ModeType.SelectMapShapes. Second, add the
SelectMapShapes Event on the MapControl Event Control. Once this is done,
every time a map shape is clicked, the Map_SelectMapShapes event will fire,
passing in the map shapes that were selected. It is the map shapes (plural)
because you could have more than one map shape in one location. Therefore, when
that location is clicked, it is unclear which map shape was meant. So, it is
actually an array of map shapes. Here is the code to make it clearer. Note: The
Geometry sample named "Information" can show you more detail on this.
C#
Map1.Mode
= MapSuite.WebEdition.Map.ModeType.SelectMapShapes;
protected void Map1_SelectMapShapes(BaseMapShape[] MapShapes)
{
if (MapShapes
!= null)
{
System.Windows.Forms.MessageBox.Show(String.Format("MapShapes Number: {0}",
MapShapes.Length));
}
}
VB.NET
Map1.Mode
= MapSuite.WebEdition.Map.ModeType.SelectMapShapes
Protected Sub
Map1_SelectMapShapes(ByVal MapShapes() As MapSuite.BaseMapShape) Handles
Map1.SelectMapShapes
If MapShapes IsNot Nothing Then
System.Windows.Forms.MessageBox.Show([String].Format("MapShapes
Number: {0}", MapShapes.Length))
End If
End
Sub
Back to Top
How can I find a feature (road, city, etc.) when the user
clicks it?
First, set the Map.Mode to ModeType.SelectFeatures. Once this is done, every
time a feature is clicked, the Map_SelectFeatures event will fire, passing in
the features that were selected. It is the features (plural) because you could
have more than one feature in one location (for example, a bridge crossing over
a river). Here is the code to make it clearer. Note: The Query sample named
"Select Features Mode" can show you more detail on this.
C#
Map1.Mode
= MapSuite.WebEdition.Map.ModeType.SelectFeatures;
protected void
Map1_SelectFeatures(FeatureInfo[]
FeatureInfo)
{
if (FeatureInfo
!= null)
{
System.Windows.Forms.MessageBox.Show(String.Format("FeatureInfos Number: {0}",
FeatureInfo.Length));
}
}
VB.NET
Map1.Mode
= MapSuite.WebEdition.Map.ModeType.SelectFeatures
Protected Sub
Map1_SelectFeatures(ByVal FeatureInfo() As MapSuite.FeatureInfo) Handles
Map1.SelectFeatures
If FeatureInfo IsNot Nothing Then
System.Windows.Forms.MessageBox.Show([String].Format("FeatureInfo
Number: {0}", FeatureInfo.Length))
End If
End
Sub
Back to Top
How can I zoom in on an area based on a query?
First, you need to create a custom field object, but the real work comes
from calling GetRecordsExtents()
from the layer object to see the extent you need to use. Below is some code to
make this a little clearer.
C#
//Here you would set the record numbers to something
meaningful in your your system
int[] RecordNumber = new int[3];
RecordNumber[0] = 2;
RecordNumber[1] = 5;
RecordNumber[2] = 17;
RectangleR NewExtent =
Map1.Layers[0].GetRecordsExtents(RecordNumber);
NewExtent.ScaleUp(10);
Map1.CurrentExtent
= NewExtent;
VB.NET
'--Here you would set the record numbers to something
meaningful in your your system
Dim RecordNumber As Integer() = New Integer(2) {}
RecordNumber(0) = 2
RecordNumber(1) = 5
RecordNumber(2) = 17
Dim NewExtent As
RectangleR = Map1.Layers(0).GetRecordsExtents(RecordNumber)
NewExtent.ScaleUp(10)
Map1.CurrentExtent
= NewExtent
Back to Top
How can I label a map feature with specific text?
The Querying sample named "Select Features Mode" can show you how
to do this but the shortest version is to use the preset GeoStyles and
GeoTextStyles. You need to pass in the field name (from the dbf file) that you
want to use as the label. Here is some code to make it a little clearer.
C#
Map1.MapUnit = MapLengthUnits.DecimalDegrees;
Layer lyr = new Layer(@"..\sampledata\usa\austin\austinpoints.shp",
true);
lyr.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
// Set the GeoStyle and GeoTextStyle for
the layer, need to pass in the dbf field name.
lyr.ZoomLevel01.GeoStyle = GeoPointStyles.City1;
lyr.ZoomLevel01.GeoTextStyle = GeoTextStyles.City1("Name");
Map1.Layers.Add(lyr);
VB.NET
Map1.MapUnit = MapLengthUnits.DecimalDegrees
Dim lyr As New Layer("..\sampledata\usa\austin\austinpoints.shp",
True)
lyr.ZoomLevel01.ApplyUntilZoomLevel =
ApplyUntilZoomLevel.ZoomLevel18
' Set the GeoStyle and GeoTextStyle for
the layer, need to pass in the dbf field name.
lyr.ZoomLevel01.GeoStyle = GeoPointStyles.City1
lyr.ZoomLevel01.GeoTextStyle = GeoTextStyles.City1("Name")
Map1.Layers.Add(lyr)
Back to Top
I see a layer can have different
zoomlevels. What would I use this feature for?
Imagine you have an application which maps a
traveler's journey between two points. You would, likely, start by showing the
entire US as the full extent. At this level, you would show the states and
maybe the interstate and US highways. As the user zooms in to a single state,
you might show state highways. As they zoom in more you might show county
roads. As they zoom in so they are looking at a city, you could show all the
city streets.
In such an application you would need to setup
different zoomlevels to control what the is shown to the user and when
(otherwise, the map would be too cluttered). In this example, you would setup a
zoomlevel to show states, interstate and US highways. This zoomlevel would be
setup to show when the user was at any zoom level (say between 30,000 miles
across and 0 miles across). Then another zoomlevel would be created to show
state highways when the user is zoomed into the state level (say between 750
miles across and 0 miles across). You keep setting up more and more zoomlevels
like this. Your final zoomlevel would be to show the city streets when the user
is zoomed to between 10 miles across and 0 miles across). You may notice that
all of the zoomlevels here are set to keep showing as the user zooms in (the
second parameter is 0 miles across). You could also set one or more zoomlevels
to stop showing once zoomed in too close to something.
The Misc sample named "ZoomLevels" can
show you in more detail how to use zoomlevels.
Back to Top
How can I draw a scale bar that
displays to the side of the map (not on top of the map)?
In Desktop Edition we can implement this effect,
but cannot in WebEdition. In WebEditiion, the desired location has to be within
the Map and some options provided to locate the ScaleBar using the following
code. Besides, we also provide some properties to denote the ScaleBar effects.
C#
Map1.ScaleBar.Location = ScaleBarLocationEnum.UpperLeft;
Map1.ScaleBar.Visible
= true;
VB.NET
Map1.ScaleBar.Location =
ScaleBarLocationEnum.UpperLeft
Map1.ScaleBar.Visible
= True
The sample named "LayerInfoApp" includes
this code. If you review this sample, you should understand a bit better.
Back to Top
How can I find out if a certain
point is contained within a certain rectangular area?
You should call Layer.SpatialQuery on the layer
that contains the point in question. You should pass in the rectangle (or other
shape) that you want to search. You will also need to pass in the containment
rule, in this case SaptialQueryContainment.Contained. Returned will be an array
of record numbers of the items within the shape you passed in. You can test
this array to see if the point you are interested in is in the there.
C#
protected void
Map1_AjaxFinishedTrackShape(object sender, AjaxFinishTrackShapeEventArgs e)
{
SpatialQuery (e.Shape);
}
private void SpatialQuery (BaseShape Shape)
{
bool
PointIsInRectangle = false;
Layer nlayer = Map1.Layers[0];
SpatialQueryContainment SpatialRule = SpatialQueryContainment.Contained;
int[]
recordNumbers = nlayer.SpatialQuery(Shape, SpatialRule);
foreach
(int i in
recordNumbers)
{
// Here we are
using 23 to represent the record number of the point in question.
if (i ==
23)
{
// Put your
logic here to do something special if the point is selected.
PointIsInRectangle = true;
}
}
}
VB.NET
Protected Sub
Map1_AjaxFinishedTrackShape(ByVal sender As Object, ByVal e As
AjaxFinishTrackShapeEventArgs)
SpatialQuery(e.Shape)
End Sub
Private Sub
SpatialQuery(ByVal Shape As BaseShape)
Dim
PointIsInRectangle As Boolean
= False
Dim nlayer As Layer = Map1.Layers(0)
Dim SpatialRule As SpatialQueryContainment =
SpatialQueryContainment.Contained
Dim
recordNumbers As Integer()
= nlayer.SpatialQuery(Shape, SpatialRule)
For Each i As Integer In
recordNumbers
' Here we are
using 23 to represent the record number of the point in question.
If i = 23 Then
' Put your
logic here to do something special if the point is selected.
PointIsInRectangle = True
End If
Next
End
Sub
The Querying sample named "Spatial
Query" covers this topic in greater detail.
Back to Top
How can I get information about
point or feature from a dbf file?
Using Layer.DataQuery you can get all the
information available in the dbf file. This routine takes in either a SQL
string or record number(s). If you have the record number of the point you want
information about (23 in this example), you would use the following code to get
the data about that point from the dbf file into a DataTable object:
C#
DataTable
dt = Map1.Layers[0].DataQuery(23, false);
VB.NET
Dim
dt As DataTable = Map1.Layers(0).DataQuery(23, False)
The Querying sample "Combination Query"
will show you more detail on this topic.
Back to Top
Once I have a record number, how
can I get the shape for that record?
Using Layer.GetShape you can get the shape object
for a record (in this example, 23). The following code would accomplish this:
C#
BaseShape
shape = Map1.Layers[0].GetShape(23);
VB.NET
Dim
shape As MapSuite.Geometry.BaseShape =
Map1.Layers(0).GetShape(23)
You could also use Layer.DataQuery with the
following code (this will return all the dbf file information as well as the
shape):
C#
DataTable
dt = Map1.Layers[0].DataQuery(23, false);
VB.NET
Dim
dt As DataTable = Map1.Layers(0).DataQuery(23, False)
Back to Top
How can I zoom in or out
programmatically?
Zooming in or out is quite easy – you can do it
with a single line of code:
C#
Map1.ZoomIn
(40); // this will zoom in 40%
Map1.ZoomOut (40); // this will zoom out 40%
VB.NET
Map1.ZoomIn
(40) '-- This will zoom in 40%
Map1.ZoomOut (40) '-- This will zoom out 40%
You can see this code in every sample under the
routine PerformAction which is used by the menu and the toolbar.
Back to Top
How can I stop a user from
zooming out too far? Is there a way to limit zooming out?
Before you zoom out via code, you can test the
current width of the map and either zoom out or not depending on what you find.
The following code could be used for this:
C#
using MapSuite;
using MapSuite.Geometry;
//This will zoom out 40% only if the map is currently showing less
than 900 miles across.
if (Map1.CurrentExtent.get_Width(MapLengthUnits.DecimalDegrees, MapLengthUnits.miles) < 900)
{
Map1.ZoomOut(40);
}
VB.NET
Imports MapSuite
Imports
MapSuite.Geometry
'This will zoom out 40% only if the map
is currently showing less than 900 miles across.
If
(Map1.CurrentExtent.Width(MapLengthUnits.DecimalDegrees, MapLengthUnits.miles)
< 900) Then
Map1.ZoomOut(40)
End
If
Back to Top
How can I set the full extent of
a map to something specific?
The Map1.FullExtent is a read-only property so you
cannot change it but you can easily accomplish your task by creating your own
extent and when the user clicks on your "Full Extent" menu
item/toobar button you just assign your custom extent to the map's current
extent. The following code shows you how.
C#
// First you need a module level variable
to hold the custom full extent.
RectangleR rect;
//
Then (in some routine) set the map so that it is showing the extent that
// will be your custom full extent,
saving that in the variable.
rect = Map1.CurrentExtent;
//
Then, when you want to go to your custom full extent, just assign the variable
to the map's current extent.
Map1.CurrentExtent
= rect;
VB.NET
' First you need a module level variable
to hold the custom full extent.
Dim rect As RectangleR
'
Then (in some routine) set the map so that it is showing the extent that
' will be your custom full extent,
saving that in the variable.
rect = Map1.CurrentExtent
' Then, when you want to go to your
custom full extent, just assign the variable to the map's current extent.
Map1.CurrentExtent
= rect
Back to Top
How can I display my data so each
item falls within some group? For example, if I have several cities with
different populations, how could I group these cities into the categories of
small, medium, and large, each with its own symbol on the map?
To accomplish this you would use class breaks. You
can see the Rendering sample named "Label Value Renderer" (or another
one is Class Break Renderer) for more detail. Basically, you need to create a
series of class breaks and one class break cap to group the data. For example,
let's use the example of cities, like in Label Value Renderer. In that sample,
each listed city falls into one of five categories: Less than 500,000; 500,000
- 999,999; 1,000,000 - 1,999,999; 2,000,000 - 4,999,999; and 5,000,000 and
over. When we setup the class breaks, you'll see how it works. The code below
accomplishes the task.
C#
// First we need to setup the zoomlevel
and collection.
ZoomLevel zoomLevel = new ZoomLevel(10000,
2500);
SymbolClassBreakCollection classBreaks = new SymbolClassBreakCollection();
// Create first break, which is 'Under
500,000' and add it to the collection.
SymbolClassBreakRenderer.ClassBreak
break1 = new SymbolClassBreakRenderer.ClassBreak(500000, mCustomPointSymbol1);
classBreaks.Add(break1);
// Create second break, which is 'Under
1,000,000' and add it to the collection
SymbolClassBreakRenderer.ClassBreak
break2 = new SymbolClassBreakRenderer.ClassBreak(1000000, mCustomPointSymbol2);
classBreaks.Add(break2);
// Create third break, which is 'Under
2,000,000' and add it to the collection
SymbolClassBreakRenderer.ClassBreak
break3 = new SymbolClassBreakRenderer.ClassBreak(2000000, mCustomPointSymbol3);
classBreaks.Add(break3);
// Create cap, which will handle the final
two categories. Every class break collection must end with a cap
// In this case, the cap says,
everything over 5,000,000 should get Symbol5 and under 5,000,000 will get
Symbol4
SymbolClassBreakRenderer.ClassBreakCap
cap = new SymbolClassBreakRenderer.ClassBreakCap(5000000, mCustomPointSymbol5,
mCustomPointSymbol4);
classBreaks.Add(cap);
// Now, we just add the class break
collection to a renderer and add the renderer to the zoomlevel.
SymbolClassBreakRenderer rend = new SymbolClassBreakRenderer("population", classBreaks);
zoomLevel.GeoStyle.SymbolRenderers.Add(rend);
// At this point, we have setup
our class breaks.
VB.NET
' First we need to setup the zoomlevel
and collection.
Dim zoomLevel As New ZoomLevel(10000, 2500)
Dim classBreaks As New SymbolClassBreakCollection()
' Create first break, which is 'Under
500,000' and add it to the collection.
Dim break1 As New SymbolClassBreakRenderer.ClassBreak(500000,
mCustomPointSymbol1)
classBreaks.Add(break1)
' Create second break, which is 'Under
1,000,000' and add it to the collection
Dim break2 As New SymbolClassBreakRenderer.ClassBreak(1000000,
mCustomPointSymbol2)
classBreaks.Add(break2)
' Create third break, which is 'Under
2,000,000' and add it to the collection
Dim break3 As New SymbolClassBreakRenderer.ClassBreak(2000000,
mCustomPointSymbol3)
classBreaks.Add(break3)
' Create cap, which will handle the
final two categories. Every class break collection must end with a cap
' In this case, the cap says, everything
over 5,000,000 should get Symbol5 and under 5,000,000 will get Symbol4
Dim cap As New SymbolClassBreakRenderer.ClassBreakCap(5000000,
mCustomPointSymbol5, mCustomPointSymbol4)
classBreaks.Add(cap)
' Now, we just add the class break
collection to a renderer and add the renderer to the zoomlevel.
Dim rend As New SymbolClassBreakRenderer("population",
classBreaks)
zoomLevel.GeoStyle.SymbolRenderers.Add(rend)
' At this point, we have setup our class breaks.
When you are this far, you have the class breaks
setup. It is important that you remember that the sequence is quite important.
The sequence in which the class breaks are added to the collection will
determine into which class each value falls. The logic will work something like
the following.
- For each value to be put into a class
break (for each city in this example)
- Compare to each class break
- Does the current value fall below the
current class break level?
- If yes, then the current value is
assigned to the current class break, go to the next value (city).
- If no, then go to the next class
break.
- If we get to the class break cap and
the current value is higher than the cap (5,000,000 in this example) then
assign to the highest class break, regardless of how high the value is.
So, if you add the class breaks in a different
order, expect different results.
Back to Top
How can I display my data so
each item is represented with a special symbol based on a exact textual match
(not categories, classes or ranges)? For example, a lake should be blue, a dry
lake should be brown, etc.
To accomplish this you would use symbol value
renderers. You can see the Rendering sample named "Value Renderer"
for more detail. You need to create a collection to hold the values to match
and then setup a symbol for each value ('Lake', 'Dry Lake', etc.). See the
following code.
C#
// First we need to setup the zoomlevel
and collection.
ZoomLevel zoomLevel = new ZoomLevel(10000,
0);
SymbolValueCollection values = new SymbolValueCollection();
SymbolValueRenderer.Value
val;
AreaSymbol sym;
// Add renderer value for any record
named "Lake". This will be a simple light sky blue color for a lake.
sym = new AreaSymbol(new GeoPen(GeoColor.KnownColors.Black),
new GeoSolidBrush(GeoColor.KnownColors.LightSkyBlue));
val = new SymbolValueRenderer.Value("Lake", sym);
values.Add(val);
// Add renderer value for any record
named "Dry Lake". This will be an actual graphic that looks like a
dry lake.
Bitmap bmp = new Bitmap(@"..\SampleData\Texures\rust
pebbles.bmp");
sym = new AreaSymbol(new GeoPen(GeoColor.FromArgb(0,0,0,0)),new GeoTextureBrush(bmp));
val = new SymbolValueRenderer.Value("Dry Lake", sym);
values.Add(val);
// Now, we must create the renderer
(collection of values) and add it to the zoomlevel.
SymbolValueRenderer rend = new SymbolValueRenderer("Feature", values);
zoomLevel.GeoStyle.SymbolRenderers.Add(rend);
// At this point, lakes and dry lakes
are configured to show using the symbols we specified
// All you need to do now is add the zoomlevel to the layer and
add the layer to the map.
VB.NET
' First we need to setup the zoomlevel
and collection.
Dim zoomLevel As New ZoomLevel(10000, 0)
Dim values As New SymbolValueCollection()
Dim val As
SymbolValueRenderer.Value
Dim sym As AreaSymbol
' Add renderer value for any record
named "Lake". This will be a simple light sky blue color for a lake.
sym = New
AreaSymbol(New
GeoPen(GeoColor.KnownColors.Black), New
GeoSolidBrush(GeoColor.KnownColors.LightSkyBlue))
val = New
SymbolValueRenderer.Value("Lake",
sym)
values.Add(val)
' Add renderer value for any record
named "Dry Lake". This will be an actual graphic that looks like a
dry lake.
Dim bmp As New Bitmap("..\SampleData\Texures\rust
pebbles.bmp")
sym = New
AreaSymbol(New GeoPen(GeoColor.FromArgb(0, 0,
0, 0)), New GeoTextureBrush(bmp))
val = New
SymbolValueRenderer.Value("Dry Lake", sym)
values.Add(val)
' Now, we must create the renderer
(collection of values) and add it to the zoomlevel.
Dim rend As New SymbolValueRenderer("Feature",
values)
zoomLevel.GeoStyle.SymbolRenderers.Add(rend)
' At this point, lakes and dry lakes are
configured to show using the symbols we specified
' All you need to do now is add the zoomlevel to the layer and add
the layer to the map.
Back to Top
How can I use my own rendering
logic when the symbol representing an place's location is being drawn?
Setting up your own rendering logic for this is
quite easy. You can see the Rendering sample named "Custom Symbols"
for a more detailed example on how to accomplish this but simply put, all you need
to do is create a module level variable of type PointSymbol and then wire-up a
custom draw event to handle that object's drawing. The following code should
make it clearer:
C#
// Module-level variable to represent
the point symbol for each location.
private
PointSymbol mCustomPointSymbol;
// Then, create the custom draw routine
private void
mCustomPointSymbol_CustomDraw(Graphics
graphics, PointF pointF, PointSymbol symbol)
{
int xCoordinate
= Convert.ToInt32(pointF.X - 7);
int yCoordinate
= Convert.ToInt32(pointF.Y - 7);
Rectangle
rect = new Rectangle(xCoordinate,
yCoordinate, 14, 14);
GraphicsPath
graphicsPath = new GraphicsPath();
graphicsPath.AddEllipse(rect);
PathGradientBrush
brush = new PathGradientBrush(graphicsPath.PathPoints);
Color[]
colors = { Color.FromArgb(170, 37, 137, 43)
};
brush.CenterColor = Color.FromArgb(255,
32, 115, 36);
brush.SurroundColors = colors;
brush.FocusScales = new
PointF(Convert.ToSingle(0.01),
Convert.ToSingle(0.01));
graphics.FillEllipse(brush, rect);
brush.Dispose();
}
// Then, in the page's load event, instantiate the variable and wire-up
the custom draw routine
protected void Page_Load (object
sender, System.EventArgs e)
{
mCustomPointSymbol = new
PointSymbol(PointStyleEnum.Custom);
mCustomPointSymbol.CustomDraw
+= new
PointSymbol.CustomDrawEventHandler(mCustomPointSymbol_CustomDraw);
}
VB.NET
' Module-level variable to represent the
point symbol for each location.
Private mCustomPointSymbol As
PointSymbol
'
Then, create the custom draw routine
Private Sub
mCustomPointSymbol_CustomDraw(ByVal graphics As Graphics, ByVal
pointF As PointF, ByVal
symbol As PointSymbol)
Dim xCoordinate As Integer =
Convert.ToInt32(pointF.X - 7)
Dim yCoordinate As Integer =
Convert.ToInt32(pointF.Y - 7)
Dim rect As New
Rectangle(xCoordinate, yCoordinate, 14, 14)
Dim graphicsPath
As New
GraphicsPath()
graphicsPath.AddEllipse(rect)
Dim brush As New
PathGradientBrush(graphicsPath.PathPoints)
Dim colors As Color() = {Color.FromArgb(170, 37, 137, 43)}
brush.CenterColor = Color.FromArgb(255, 32, 115,
36)
brush.SurroundColors = colors
brush.FocusScales = New
PointF(Convert.ToSingle(0.01), Convert.ToSingle(0.01))
graphics.FillEllipse(brush, rect)
brush.Dispose()
End
Sub
'Then, in
the page's load event, instantiate the variable and wire-up the custom draw
routine
Protected Sub
Page_Load(ByVal sender As
Object, ByVal e
As EventArgs)
mCustomPointSymbol = New
PointSymbol(PointStyleEnum.[Custom])
AddHandler
mCustomPointSymbol.CustomDraw, AddressOf
mCustomPointSymbol_CustomDraw
End Sub
Back to Top
How can I have items labeled
differently based on a value in a field in the shape file? For example, if I have
several cities in each country in Europe, I want to show capitals in a larger
font than non-capitals.
To accomplish this you would use the label value
renderer. You can see the Rendering sample named "Label Value
Renderer" for more detail. You need to create a label value collection and
add to that collection one label value for each value to be match. In this
example, we will have two label values; one for "Y" and one for
"N" in the field named "Capital." The code below does just
that.
C#
// First we need to setup the zoomlevel
and collection.
ZoomLevel zoomLevel = new ZoomLevel(2500,
0);
LabelValueCollection col = new LabelValueCollection();
LabelValueRenderer.LabelValue
val;
TextSymbol sym;
// Setup for captitals.
sym = new TextSymbol(new GeoFont("Arial",12,GeoFontStyle.Bold),new
GeoSolidBrush(GeoColor.KnownColors.Black),0,-8);
val = new LabelValueRenderer.LabelValue("Y",sym);
col.Add(sym);
// Setup for non-captitals.
sym = new TextSymbol(new GeoFont("Arial",8,
GeoFontStyle.Bold),new
GeoSolidBrush(GeoColor.KnownColors.Black),0,-6);
val = new LabelValueRenderer.LabelValue("N",sym);
col.Add(val);
// Create renderer, testing field
"Capital" but displaying field "Name".
LabelValueRenderer render = new LabelValueRenderer("Captical", "Name",
col);
// Add renderer to the zoomlevel.
zoomLevel.GeoTextStyle.LabelRenderers.Add(render);
VB.NET
' First we need to setup the zoomlevel
and collection.
Dim zoomLevel As New ZoomLevel(2500, 0)
Dim col As New LabelValueCollection()
Dim val As
LabelValueRenderer.LabelValue
Dim sym As TextSymbol
' Setup for captitals.
sym = New
TextSymbol(New GeoFont("Arial",
12, GeoFontStyle.Bold), New
GeoSolidBrush(GeoColor.KnownColors.Black), 0, -8)
val = New
LabelValueRenderer.LabelValue("Y",
sym)
col.Add(sym)
' Setup for non-captitals.
sym = New
TextSymbol(New GeoFont("Arial",
8, GeoFontStyle.Bold), New
GeoSolidBrush(GeoColor.KnownColors.Black), 0, -6)
val = New
LabelValueRenderer.LabelValue("N",
sym)
col.Add(val)
' Create renderer, testing field
"Capital" but displaying field "Name".
Dim render As New LabelValueRenderer("Captical",
"Name", col)
' Add renderer to the zoomlevel.
zoomLevel.GeoTextStyle.LabelRenderers.Add(render)
Back to Top
I see that a map can have
multiple layers. Why would I use multiple layers?
Since a layer is the object that holds the data
(that is a layer has one and only one shape file as it's data source) if you
want to have multiple data sources then you need multiple layers. The Misc
sample named "ZoomLevels" can show you more details about this. In
this sample, you will see six layers created. One layer has the streets of Austin, one layer has the US highways, one layer has the details about the US states, etc. The zoomlevels in this sample just, in effect, tell each layer to render
only at certain zoom factors. The point is that each layer actually has the
data from the shape file. So, multiple shape files mean multiple layers.
Back to Top
When a user selects a certain
feature, I want to be able to change its symbol to show it is different from
the other features. How would I "highlight" a feature when it is
selected?
In the Querying sample named "Select Features
Mode," you can see exactly how to do this. The basics are this: Loop
through each shape, clear the shape's symbols (so only the shape shows but no
highlighting symbols show), then if the shape from the current round in the
loop is the one that was selected, then add to it the symbols that you would
like to use for highlighting. The following code will illustrate this.
C#
// This is a simplified version of the
code in the Select Features Mode sample app
// This code assumes that all shapes on
the map are point shapes (there are no line or area shapes).
private void
UpdateSelectedSymols(int index)
{
for( int i = 0 ; i < Map1.MapShapes.Count ; i++)
{
Map1.MapShapes[i].Symbols.Clear();
if(i ==
index)
{
GeoSolidBrush
brush = new GeoSolidBrush(GeoColor.FromArgb(150,GeoColor.KnownColors.Red));
Map1.MapShapes[i].Symbols.Add(new AreaSymbol(new GeoPen(GeoColor.KnownColors.Black),brush));
}
else
{
GeoSolidBrush
brush = new GeoSolidBrush(GeoColor.FromArgb(150,GeoColor.KnownColors.Orange));
Map1.MapShapes[i].Symbols.Add(new AreaSymbol(new GeoPen(GeoColor.KnownColors.Black),brush));
}
}
}
VB.NET
' This is a simplified version of the
code in the Select Features Mode sample app
' This code assumes that all shapes on
the map are point shapes (there are no line or area shapes).
Private Sub
UpdateSelectedSymols(ByVal index As Integer)
For i As Integer = 0 To Map1.MapShapes.Count - 1
Map1.MapShapes(i).Symbols.Clear()
If i = index Then
Dim brush As New
GeoSolidBrush(GeoColor.FromArgb(150, GeoColor.KnownColors.Red))
Map1.MapShapes(i).Symbols.Add(New AreaSymbol(New
GeoPen(GeoColor.KnownColors.Black), brush))
Else
Dim brush As New
GeoSolidBrush(GeoColor.FromArgb(150, GeoColor.KnownColors.Orange))
Map1.MapShapes(i).Symbols.Add(New AreaSymbol(New
GeoPen(GeoColor.KnownColors.Black), brush))
End If
Next
End
Sub
Back to Top
I want a user to be able to draw
various shapes (circles, rectangles, etc.) and I want to execute some custom
logic while the shape is being created. How can I do this?
The Misc sample named "Track Shapes"
will be very helpful to you in understanding how to accomplish this. In this
sample there are no layers, no shape files, just track shapes being drawn (they
can also be moved). As you can see from the code in this sample, there are
plenty of events which you can tie into. You can execute your logic when the
shape is just starting to be dragged, when the dragging is complete, or while
the dragging is happening. As well, you can run your logic while the track
shape is being drawn or when the drawing is complete. All of these events are
used in the sample.
While the track shape is being drawn, you will see
that there is logic to show the total area / perimeter / radius of the shape.
When the track shape is finished being drawn, you will see logic to make the
shape permanent (actually add it to the map as a map shape).
Explore this sample and it should be pretty clear
how to accomplish these things. Below is a bit of the logic from the sample
which is in the Map1_TrackShapesDraw event.
C#
protected void
Map1_AjaxFinishedTrackShape(object sender,
MapSuite.WebEdition.AjaxFinishTrackShapeEventArgs
e)
{
BaseShape
baseshpae = e.Shape;
double area,
perimeter;
if (baseshpae is BaseAreaShape)
{
BaseAreaShape
baseArea = baseshpae as BaseAreaShape;
area = baseArea.get_Area(MapLengthUnits.kilometres, MapAreaUnits.squarekm);
perimeter = baseArea.get_Perimeter(MapLengthUnits.kilometres, MapLengthUnits.kilometres);
}
}
VB.NET
Protected Sub
Map1_AjaxFinishedTrackShape(ByVal sender As Object, ByVal e As
MapSuite.WebEdition.AjaxFinishTrackShapeEventArgs)
Dim baseshpae As
BaseShape = e.Shape
Dim area As Double, perimeter As Double
If TypeOf baseshpae Is
BaseAreaShape Then
Dim baseArea As BaseAreaShape = TryCast(baseshpae,
BaseAreaShape)
area =
baseArea.Area(MapLengthUnits.kilometres, MapAreaUnits.squarekm)
perimeter =
baseArea.Perimeter(MapLengthUnits.kilometres, MapLengthUnits.kilometres)
End If
End
Sub
Back to Top
What are map shapes and how can I
use them?
The Misc sample named "Track Shapes"
will show you how to create map shapes based on a track shape (a shape a user
draws). A map shape is a shape that is added via code and not from a shape
file. That is, mostly shapes will be added from shape files (roads, buildings,
etc.) but you might want to have your own shapes. Your own shapes might include
proposed buildings or even vehicles driving down the street.
Map shapes can be easily moved and reside outside
the context of layers. Map shapes are on the map, not on a layer. Let's say you
want to allow a user to plot the points, on a map of the world, where they have
visited. For this, you would load a layer with data of the world. Then you
would set the map into track point mode. Then, let the user click creating the
various points. Each time the user clicks, the Map1_FinishedTrackShape event
will fire – here you will add the map shape and record any data in a data store
(for example, storing the latitude and longitude in a database).
The following code should make it clear:
C#
// Put this code in the form's load
event. This will show a map of the world.
Map1.MapUnit = MapLengthUnits.DecimalDegrees;
Layer lyr = new Layer(@"..\sampledata\world\cntry02.shp",
true);
lyr.ZoomLevelExtentUnit = ZoomLevelExtentUnits.DecimalDegrees;
lyr.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel18;
lyr.ZoomLevel01.GeoStyle = GeoAreaStyles.GetSimpleAreaStyle(GeoColor.KnownColors.LightGray, GeoColor.KnownColors.Black, 1);
Map1.Layers.Add(lyr);
//
Then, set the map's mode to track point so that every time the user clicks, a
point shape will be created.
Map1.Mode = MapSuite.WebEdition.Map.ModeType.TrackPoint;
// Finally, in the FinishedTrackShape
event, add the code to add the point to the map as a map shape.
protected void
Map1_AjaxFinishedTrackShape(object sender,
MapSuite.WebEdition.AjaxFinishTrackShapeEventArgs
e)
{
if(e.Shape is BasePointShape)
{
BasePointShape
pnt = e.Shape as BasePointShape;
Map1.MapShapes.Add(new
PointMapShape(pnt));
}
}
VB.NET
' Put this code in the form's load
event. This will show a map of the world.
Map1.MapUnit = MapLengthUnits.DecimalDegrees
Dim lyr As New Layer("..\sampledata\world\cntry02.shp",
True)
lyr.ZoomLevelExtentUnit =
ZoomLevelExtentUnits.DecimalDegrees
lyr.ZoomLevel01.ApplyUntilZoomLevel =
ApplyUntilZoomLevel.ZoomLevel18
lyr.ZoomLevel01.GeoStyle =
GeoAreaStyles.GetSimpleAreaStyle(GeoColor.KnownColors.LightGray,
GeoColor.KnownColors.Black, 1)
Map1.Layers.Add(lyr)
'
Then, set the map's mode to track point so that every time the user clicks, a
point shape will be created.
Map1.Mode =
MapSuite.WebEdition.Map.ModeType.TrackPoint
'
Finally, in the FinishedTrackShape event, add the code to add the point to the
map as a map shape.
Protected Sub
Map1_AjaxFinishedTrackShape(ByVal sender As Object, ByVal e As
MapSuite.WebEdition.AjaxFinishTrackShapeEventArgs)
If TypeOf e.Shape Is
BasePointShape Then
Dim pnt As BasePointShape = TryCast(e.Shape,
BasePointShape)
Map1.MapShapes.Add(New
PointMapShape(pnt))
End If
End
Sub
As you can see, there is very little code to
actually add a map shape to a map (two lines). Most of the code will depend on
how you want to store the data about the points the user selected.
Back to Top
How can I define my own custom
labeling plug-in?
The Rendering sample named "Custom
Labeler" goes over this is greater detail but what you will need to do is
create a class that inherits from MapSuite.ILabeler. There are several methods
to implement, all named DrawLabels (taking in different parameters). In the
sample, you will see DrawLabels implemented for Polygons and MultiLines. The
code for polygons is below:
C#
// Class declaration
public class CustomLabeler : MapSuite.ILabeler
{
// DrawLabels routine
public void DrawLabels(Graphics
g, Array[] TextSymbolArrays, Array[] SymbolArray, MapSuite.Geometry.PolygonF[] Polygons, ref
SimplePolygonF[] LabeledAreas, int CanvasWidth, int
CanvasHeight)
{
// Drawing labels
for polygons
StringFormat
Format = new StringFormat();
Format.Alignment = StringAlignment.Center;
for (int i = 0; i <= Polygons.Length - 1; i++)
{
TextSymbol[]
TextSymbols = (TextSymbol[])TextSymbolArrays[i];
for (int j = 0; j <= Polygons[i].Parts.Length - 1; j++)
{
for
(int k = 0; k <= TextSymbols.Length - 1;
k++)
{
g.DrawString(TextSymbols[k].TextValue, TextSymbols[k].Font,
TextSymbols[k].Brush, Polygons[i].Parts[j].Centroid.X + TextSymbols[k].XOffset,
Polygons[i].Parts[j].Centroid.Y + TextSymbols[k].YOffset, Format);
}
}
}
}
public void DrawLabels(Graphics
g, Array[] TextSymbolArrays, Array[] SymbolArrays, PointF[]
Points, ref SimplePolygonF[]
LabeledAreas, int CanvasWidth, int CanvasHeight)
{
throw new Exception("The method or operation is not implemented.");
}
public void DrawLabels(Graphics
g, Array[] TextSymbolArrays, Array[] SymbolArrays, MultiPointF[]
MultiPoints, ref SimplePolygonF[]
LabeledAreas, int CanvasWidth, int CanvasHeight)
{
throw new Exception("The method or operation is not implemented.");
}
public void DrawLabels(Graphics
g, Array[] TextSymbolArrays, Array[] SymbolArrays, MultiLineF[]
MultiLines, ref SimplePolygonF[]
LabeledAreas, int CanvasWidth, int CanvasHeight)
{
throw new Exception("The method or operation is not implemented.");
}
}
VB.NET
' Class declaration
Public Class CustomLabeler
Implements
ILabeler
' DrawLabels routine
Public Sub DrawLabels(ByVal
g As Graphics, ByVal
TextSymbolArrays As Array(), ByVal SymbolArray As
Array(), ByVal Polygons As MapSuite.Geometry.PolygonF(), ByRef
LabeledAreas As SimplePolygonF(), ByVal CanvasWidth As Integer, _
ByVal
CanvasHeight As Integer)
Implements ILabeler.DrawLabels
' Drawing labels
for polygons
Dim Format As New StringFormat()
Format.Alignment = StringAlignment.Center
For i As Integer = 0 To Polygons.Length - 1
Dim
TextSymbols As TextSymbol() = DirectCast(TextSymbolArrays(i), TextSymbol())
For j As Integer = 0 To Polygons(i).Parts.Length - 1
For
k As Integer =
0 To TextSymbols.Length - 1
g.DrawString(TextSymbols(k).TextValue, TextSymbols(k).Font,
TextSymbols(k).Brush, Polygons(i).Parts(j).Centroid.X + TextSymbols(k).XOffset,
Polygons(i).Parts(j).Centroid.Y + TextSymbols(k).YOffset, Format)
Next
Next
Next
End Sub
Public Sub DrawLabels(ByVal
g As Graphics, ByVal
TextSymbolArrays As Array(), ByVal SymbolArrays As
Array(), ByVal Points As
PointF(), ByRef LabeledAreas As SimplePolygonF(), ByVal
CanvasWidth As Integer,
_
ByVal
CanvasHeight As Integer)
Implements ILabeler.DrawLabels
Throw New Exception("The
method or operation is not implemented.")
End Sub
Public Sub DrawLabels(ByVal
g As Graphics, ByVal
TextSymbolArrays As Array(), ByVal SymbolArrays As
Array(), ByVal MultiPoints As MultiPointF(), ByRef
LabeledAreas As SimplePolygonF(), ByVal CanvasWidth As Integer, _
ByVal
CanvasHeight As Integer)
Implements ILabeler.DrawLabels
Throw New Exception("The
method or operation is not implemented.")
End Sub
Public Sub DrawLabels(ByVal
g As Graphics, ByVal
TextSymbolArrays As Array(), ByVal SymbolArrays As
Array(), ByVal MultiLines As MultiLineF(), ByRef
LabeledAreas As SimplePolygonF(), ByVal CanvasWidth As Integer, _
ByVal
CanvasHeight As Integer)
Implements ILabeler.DrawLabels
Throw New Exception("The
method or operation is not implemented.")
End Sub
End
Class
Now, to use your custom labeler, you just need to
create it and plug it in. Like the following:
C#
// this assumes you have a zoomlevel
object declared as zoomlevel.
CustomLabeler cl = new CustomLabeler();
zoomlevel.LabelerPlugin
= cl;
VB.NET
' this assumes you have a zoomlevel object
declared as zoomlevel.
Dim cl As CustomLabeler
= New CustomLabeler()
zoomlevel.LabelerPlugin
= cl
Back to Top
How can I get data from a shape
file? Can I use SQL queries?
Yes, you can use SQL queries to get data from
shape files. The Querying sample named "SQL Query" is the sample that
best illustrates this but below you will see some code that will help you.
C#
string SQL = "Select *
From TexasCounties where pop2001 > 100000 and pop2001 < 500000";
// false = don't include shapes in
returned data.
DataTable
dt = Map1.Layers[0].SQLQuery(SQL, false,"Population");
VB.NET
Dim SQL As String = "Select *
From TexasCounties where pop2001 > 100000 and pop2001 < 500000"
' false = don't include shapes in
returned data.
Dim
dt As DataTable = Map1.Layers(0).SQLQuery(SQL, False, "Population")
That's it. Since a layer is really just a
representation of a shape file, you can query the shape file by querying the
layer – all with only two lines of code.
Back to Top
Can I change the data in a shape
file, and if so, how?
Yes, you can. To delete shapes in the file, use
the Layer.DeleteShape method which takes in a record number. If you want to
change the data in a shape file, first you must call Layer.BeginEdit and then
follow that with either Layer.CommitEdit or Layer.RollbackEdit. Between calling
BeingEdit and CommitEdit or RollbackEdit you can call Layer.DeleteShape,
Layer.AddShape, or Layer.UpdateShape depending on whether you want to do a
delete, insert, or an update. The Layer sample named "Edit Shape
File" is the sample that best illustrates this but below you will see some
code that will help you.
C#
// Insert a new shape
protected void
Map1_FinishedTrackShape(BaseShape Shape)
{
Map1.Layers[0].BeginEdit();
Map1.Layers[0].AddShape(Shape);
Map1.Layers[0].CommitEdit();
}
// Update an existing shape, 32 is the shape record number you want to
update.
protected void
Map1_FinishedTrackShape(BaseShape Shape)
{
Map1.Layers[0].BeginEdit();
Map1.Layers[0].UpdateShape(32, Shape);
Map1.Layers[0].CommitEdit();
}
// Delete an existing shape, 32 is the shape record number you want to
update.
protected void
Map1_FinishedTrackShape(BaseShape Shape)
{
Map1.Layers[0].BeginEdit();
Map1.Layers[0].DeleteShape(32);
Map1.Layers[0].CommitEdit();
}
VB.NET
' Insert a new shape
Protected Sub
Map1_FinishedTrackShape(ByVal Shape As BaseShape)
Map1.Layers(0).BeginEdit()
Map1.Layers(0).AddShape(Shape)
Map1.Layers(0).CommitEdit()
End Sub
' Update an existing shape, 32 is the
shape record number you want to update.
Protected Sub
Map1_FinishedTrackShape(ByVal Shape As BaseShape)
Map1.Layers(0).BeginEdit()
Map1.Layers(0).UpdateShape(32, Shape)
Map1.Layers(0).CommitEdit()
End Sub
' Delete an existing shape, 32 is the
shape record number you want to update.
Protected Sub
Map1_FinishedTrackShape(ByVal Shape As BaseShape)
Map1.Layers(0).BeginEdit()
Map1.Layers(0).DeleteShape(32)
Map1.Layers(0).CommitEdit()
End
Sub
Back to Top
What do I need to do to
distribute my application which uses Map Suite? How do I get all the
dependencies on the destination computer?
In the full version of Map Suite, we include a
merge module that can be included in your setup program. The merge module will
install everything needed for Map Suite to run on that machine.
Back to Top
What vector and raster formats
are supported by Map Suite?
For vector data, Map Suite supports ShapeFile
format.
For raster imagery, Map Suite supports TIFF, GeoTIFF, MrSID, ECW, JPEG2000, BMP
and JPEG.
Back to Top
How do I zoom in to a Point?
Zooming into a point is a common question we
receive from our customers. Since point-based objects don't consume much area,
it can be a bit difficult to create an extent to zoom in to. The answer to this
problem is the buffer method. The buffer method allows you to buffer a point by
a certain distance to give it area. For example, in the code below we have
taken a point and buffered it by 5 miles on each side. Once we have this new
buffered point, all we need to do is get the RectangleR from the envelope and
set this to the map extent. This will then zoom the map into an area 10 miles
around your point. Below is some sample code to help get you started:
C#
// The following code will zoom the map into an area 10
miles around the point.
PointShape pnt = new PointShape(lonValue,
latValue);
Map1.CurrentExtent
= pnt.Buffer(5, MapLengthUnits.DecimalDegrees,
MapLengthUnits.miles).Envelope.ToRectangleR();
VB.NET
'-- The following will zoom the map into an area 10 miles
around the point.
Dim pnt As New PointShape(lonValue,
latValue)
Map1.CurrentExtent
= pnt.Buffer(5, MapLengthUnits.DecimalDegrees,
MapLengthUnits.miles).Envelope.ToRectangleR()
Back to Top
How do I zoom in to a set of
MapShape Points?
To zoom the map in to an extent that includes
specific points see the following routine:
C#
private RectangleR
CalculateMapExtent()
{
//Declare Variables
PointShape
pointShape;
double
upperLeftLat = 0;
double
upperLeftLong = 0;
double
lowerRightLat = 0;
double
lowerRightLong = 0;
//Loop through the
points collection to find the upper left and lower right point values
foreach (BaseMapShape baseMapShape in
Map1.MapShapes)
{
if
(baseMapShape is PointMapShape)
{
pointShape = (PointShape)baseMapShape.BaseShape;
if
(pointShape.Y > upperLeftLat | upperLeftLat == 0) upperLeftLat = pointShape.Y;
if
(pointShape.X < upperLeftLong | upperLeftLong == 0) upperLeftLong =
pointShape.X;
if
(pointShape.Y < lowerRightLat | lowerRightLat == 0) lowerRightLat =
pointShape.Y;
if
(pointShape.X > lowerRightLong | lowerRightLong == 0) lowerRightLong =
pointShape.X;
}
}
//Create variables to
set the extent
PointR
upperLeftPoint = new PointR(upperLeftLong,
upperLeftLat);
PointR
lowerRightPoint = new PointR(lowerRightLong,
lowerRightLat);
RectangleR
mapExtent = new RectangleR(upperLeftPoint,
lowerRightPoint);
//Scale Up Map extent
by 5%
mapExtent.ScaleUp(5);
if
(mapExtent.get_Width(MapLengthUnits.DecimalDegrees,
MapLengthUnits.miles) < 400)
{
while
(!(mapExtent.get_Width(MapLengthUnits.DecimalDegrees,
MapLengthUnits.miles) > 400))
{
mapExtent.ScaleUp(5);
}
}
return
mapExtent;
}
VB.NET
Private Function
CalculateMapExtent() As RectangleR
'Declare Variables
Dim pointShape As PointShape
Dim upperLeftLat As Double = 0
Dim upperLeftLong
As Double = 0
Dim lowerRightLat
As Double = 0
Dim
lowerRightLong As Double
= 0
'Loop through the
points collection to find the upper left and lower right point values
For Each baseMapShape As
BaseMapShape In Map1.MapShapes
If TypeOf baseMapShape Is
PointMapShape Then
pointShape = DirectCast(baseMapShape.BaseShape,
PointShape)
If
pointShape.Y > upperLeftLat Or upperLeftLat
= 0 Then
upperLeftLat = pointShape.Y
End If
If
pointShape.X < upperLeftLong Or
upperLeftLong = 0 Then
upperLeftLong = pointShape.X
End If
If
pointShape.Y < lowerRightLat Or
lowerRightLat = 0 Then
lowerRightLat = pointShape.Y
End If
If
pointShape.X > lowerRightLong Or
lowerRightLong = 0 Then
lowerRightLong = pointShape.X
End If
End If
Next
'Create variables to
set the extent
Dim
upperLeftPoint As New
PointR(upperLeftLong, upperLeftLat)
Dim
lowerRightPoint As New
PointR(lowerRightLong, lowerRightLat)
Dim mapExtent As New
RectangleR(upperLeftPoint, lowerRightPoint)
'Scale Up Map extent by
5%
mapExtent.ScaleUp(5)
If
mapExtent.Width(MapLengthUnits.DecimalDegrees, MapLengthUnits.miles) < 400 Then
While Not (mapExtent.Width(MapLengthUnits.DecimalDegrees,
MapLengthUnits.miles) > 400)
mapExtent.ScaleUp(5)
End While
End If
Return mapExtent
End
Function
Back to Top
How can I dynamically load
controls using spatial queries?
A common task that Map Suite developers are faced
with is dynamically loading user interface controls like a combo box based upon
what is currently being displayed on the map. For example, you may have a map
of the United States but only want to show the name of the states that are
currently being displayed. The code below will show you how to do a spatial
query using the Map1.CurrentExtent property which will only return the states
that are currently shown on the map. Typically the best place to put this code
is inside the Map1_CurrentExtentChanged event handler; this way, every time the map extent changes
the control will be updated.
C#
//Add the following code to the Map1_CurrentExtentChanged
event handler
if (Map1.Layers["states"] != null)
{
// Build Up a
Rectangle based upon the Map's current extent
StraightRectangle MapExtent = new StraightRectangle(Map1.CurrentExtent);
int[] RecordIDs
= null;
//Get the RecordID's
for the states that are currently within the Map's extent
RecordIDs = Map1.Layers["states"].SpatialQuery(MapExtent,
SpatialQueryContainment.Containing);
DataTable CurrentStates = null;
//Get a Datatable
containing information for the states that are visible
CurrentStates = Map1.Layers["states"].DataQuery(RecordIDs, false);
//Bind the Datatable
to the combo box
this.cboStates.DataSource
= CurrentStates;
this.cboStates.ValueMember
= "STATE_NAME";
}
VB.NET
' Add the following
code to the Map1_CurrentExtentChanged event handler
If Map1.Layers("states")
IsNot Nothing Then
' Build Up a Rectangle based upon the
Map's current extent
Dim MapExtent As New StraightRectangle(Map1.CurrentExtent)
Dim RecordIDs As Integer() = Nothing
'Get the RecordID's for the states that
are currently within the Map's extent
RecordIDs = Map1.Layers("states").SpatialQuery(MapExtent,
SpatialQueryContainment.Containing)
Dim CurrentStates As
DataTable = Nothing
'Get a Datatable containing information
for the states that are visible
CurrentStates = Map1.Layers("states").DataQuery(RecordIDs, False)
'Bind the Datatable to the combo box
Me.cboStates.DataSource
= CurrentStates
Me.cboStates.ValueMember
= "STATE_NAME"
End
If
Back to Top
Is there a way to highlight map
features based on a SQL query?
Yes. Using any of the Map Suite products you can
easily highlight a particular map feature. In the code example below we have
written a simple SQL query that will return a single state from the states
shape file and color it red using the Selects method. Utilizing the Selects
method off of the Layer object is a quick and easy way to highlight one or many
features on the map. To test this functionality out all you need to do is add
the code below into the Load routine within the SelectMapShapes sample
application (Note: You will need to add this code before the Map1.Refresh line
and after the PrepareLayer call).
C#
int[] RecordIDs;
//Retrieve the record numbers for the
state(s) you want to highlight
RecordIDs = Map1.Layers["states"].SQLQuery("Select * From States Where State_Name = 'Kansas'", "RecID");
//Highlight the state by using the
selects method
Map1.Layers["states"].Selects(RecordIDs);
//Define what color the selected states
should show up as
AreaSymbol RedStateSymbol = new
AreaSymbol(new
GeoSolidBrush(GeoColor.KnownColors.Red));
Map1.Layers["states"].SelectSymbols.Add(RedStateSymbol);
VB.NET
Dim RecordIDs As Integer()
'Retrieve the record numbers for the
state(s) you want to highlight
RecordIDs = Map1.Layers("states").SQLQuery("Select * From States Where State_Name = 'Kansas'", "RecID")
'Highlight the state by using the
selects method
Map1.Layers("states").Selects(RecordIDs)
'Define what color the selected states
should show up as
Dim RedStateSymbol As New AreaSymbol(New
GeoSolidBrush(GeoColor.KnownColors.Red))
Map1.Layers("states").SelectSymbols.Add(RedStateSymbol)
Back to Top
How can I add satellite and
aerial imagery to my project?
Using the ImageLayer Class you can add images in
MrSid, ECW, TIFF, BMP, JPEG2000, or JPEG formats. Below we have written code
that loads the image layer, sets the zoomlevel for the SymbolRenderer, and adds
roads pulled from a shape file.
C#
//Set Map Units
Map1.MapUnit = MapLengthUnits.metres;
//Load Image
ImageLayer imageLayer = new ImageLayer(@"..\..\sampledata\usa\unionspring\doqq_cir_unionsprg_ny.tif");
Map1.ImageLayers.Add(imageLayer);
//Setup Road Layer
Layer roadsLayer = new Layer(@"..\..\sampledata\usa\unionspring\unionspringroads.shp",
true);
//Set rendering styles for roads
roadsLayer.ZoomLevel01.GeoStyle
= GeoLineStyles.GetSimpleLineStyle(GeoColor.KnownColors.LightGoldenrodYellow, 4, GeoColor.KnownColors.Black, 5);
roadsLayer.ZoomLevel01.GeoTextStyle = GeoTextStyles.GetMaskTextStyle("Name", "Arail",
8, GeoFontStyle.Bold, GeoColor.KnownColors.Black, GeoColor.KnownColors.LightGoldenrodYellow, 9, 0);
roadsLayer.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.ZoomLevel05;
Map1.Layers.Add(roadsLayer);
VB.NET
'Set Map Units
Map1.MapUnit =
MapLengthUnits.metres
'Load Image
Dim imageLayer As New ImageLayer("..\..\sampledata\usa\unionspring\doqq_cir_unionsprg_ny.tif")
Map1.ImageLayers.Add(imageLayer)
'Setup Road Layer
Dim roadsLayer As New Layer("..\..\sampledata\usa\unionspring\unionspringroads.shp",
True)
'Set rendering styles for roads
roadsLayer.ZoomLevel01.GeoStyle =
GeoLineStyles.GetSimpleLineStyle(GeoColor.KnownColors.LightGoldenrodYellow, 4,
GeoColor.KnownColors.Black, 5)
roadsLayer.ZoomLevel01.GeoTextStyle =
GeoTextStyles.GetMaskTextStyle("Name",
"Arail", 8, GeoFontStyle.Bold,
GeoColor.KnownColors.Black, GeoColor.KnownColors.LightGoldenrodYellow,9, 0)
roadsLayer.ZoomLevel01.ApplyUntilZoomLevel =
ApplyUntilZoomLevel.ZoomLevel05
Map1.Layers.Add(roadsLayer)
Some tips on using ImageLayers:
- Make sure that your vector layer is in
the same projection as your image layer. This will ensure that the roads
in your shape file match up with the roads in your image.
- ImageLayers use Upper and Lower
Threshold properties instead of adding a zoomLevel to the layer.
- Image layers need to be georeferenced
to show up correctly on the map. This geo referencing information is
stored in a corresponding world file.
- Be sure to check out our ImageApp
Sample Application to see additional ways to add images to your maps.
Back to Top
|
|
Try Map Suite free for 60 days.
|
Get started fast with Map Suite.
|
Sample Map Suite GIS applications.
|
Watch Map Suite video demos.
|
Purchase this product online.
|
|