arcgis api for silverlight开发系列之四:实现地图提示MapTips及QueryTask揭秘

照例让我们以源码开始

<Grid x:Name="LayoutRoot" Background="White">
<Grid.Resources>
<symbol:SimpleFillSymbol x:Key="DefaultFillSymbol" Fill="#01FFFFFF" BorderBrush="#88000000"
BorderThickness="2" />
<symbol:SimpleMarkerSymbol x:Key="DefaultMarkerSymbol" Color="Red" Size="6" Style="Diamond" />
</Grid.Resources>

<esri:Map x:Name="MyMap" WrapAround="True" Extent="-15000000,2000000,-7000000,8000000">
<esri:ArcGISTiledMapServiceLayer ID="BaseMapLayer"
Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />

<esri:GraphicsLayer ID="CitiesGraphicsLayer">
<esri:GraphicsLayer.MapTip>
<Border BorderBrush="DarkGray" CornerRadius="13" BorderThickness="1" Margin="0,0,15,15">
<Border.Effect>
<DropShadowEffect ShadowDepth="10" BlurRadius="14" Direction="300" />
</Border.Effect>
<Border CornerRadius="10" Background="#DDFFEEEE" BorderThickness="5" BorderBrush="#77FF0000">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="10">
<StackPanel Orientation="Horizontal">
<TextBlock Text="City Name: " FontWeight="Bold" Foreground="#FF0F274E" FontSize="10" VerticalAlignment="Center"/>
<TextBlock Text="{Binding [CITY_NAME]}" HorizontalAlignment="Left" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Population: " FontWeight="Bold" Foreground="#FF0F274E" FontSize="10" VerticalAlignment="Center" />
<TextBlock Text="{Binding [POP1990]}" HorizontalAlignment="Left" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Border>
</Border>
</esri:GraphicsLayer.MapTip>
</esri:GraphicsLayer>

</esri:Map>

</Grid>

注意前端引入 xmlns:symbol="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client"

后台:

public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
MyMap.PropertyChanged += MyMap_PropertyChanged;
}

void MyMap_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "SpatialReference")
{
CitiesGraphicsLayerLoad();
MyMap.PropertyChanged -= MyMap_PropertyChanged;
}
}
private void CitiesGraphicsLayerLoad()
{
ESRI.ArcGIS.Client.Tasks.Query query = new ESRI.ArcGIS.Client.Tasks.Query()
{
Geometry = new ESRI.ArcGIS.Client.Geometry.Envelope(-180, 0, 0, 90),
ReturnGeometry = true,
OutSpatialReference = MyMap.SpatialReference
};
query.OutFields.Add("*");
query.Where = "POP1990 > 100000";
QueryTask queryTask = new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0");
queryTask.ExecuteCompleted += CitiesGraphicsLayerQueryTask_ExecuteCompleted;
queryTask.ExecuteAsync(query);
}

void CitiesGraphicsLayerQueryTask_ExecuteCompleted(object sender, QueryEventArgs queryArgs)
{
if (queryArgs.FeatureSet == null)
return;

FeatureSet resultFeatureSet = queryArgs.FeatureSet;
ESRI.ArcGIS.Client.GraphicsLayer graphicsLayer =
MyMap.Layers["CitiesGraphicsLayer"] as ESRI.ArcGIS.Client.GraphicsLayer;

if (resultFeatureSet != null && resultFeatureSet.Features.Count > 0)
{
foreach (ESRI.ArcGIS.Client.Graphic graphicFeature in resultFeatureSet.Features)
{
graphicFeature.Symbol = LayoutRoot.Resources["DefaultMarkerSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol;
graphicsLayer.Graphics.Add(graphicFeature);
}
}
}
}

运行看看效果,然后我们再研究QueryTask的神秘。

QueryTask是一个进行空间和属性查询的功能类,它是针对某个地图服务的某个子图层进行查询(这个是与后面介绍FindTask的差别所在)。下面分别看看属性查询和空间查询的实例,其实MapTips的实现也是利用QueryTask查询属性。不妨再看一个查询属性应用:

 <Grid x:Name="LayoutRoot" Background="White">
       
        <Canvas x:Name="ResultsDisplayCanvas" HorizontalAlignment="Center" VerticalAlignment="Top" Width="547" Height="200" Margin="0,30,0,0" >
            <Rectangle Stroke="Gray"  RadiusX="10" RadiusY="10" Fill="#77919191" Canvas.Left="0" Canvas.Top="0" Width="547" Height="200" >
                <Rectangle.Effect>
                    <DropShadowEffect/>
                </Rectangle.Effect>
            </Rectangle>
            <Rectangle Fill="#FFFFFFFF" Stroke="DarkGray" RadiusX="5" RadiusY="5" Canvas.Left="10" Canvas.Top="20" Width="530" Height="170"  />
            <TextBlock x:Name="DataDisplayTitle" Text="Using Query tasks without maps" Foreground="White" FontSize="9" Canvas.Left="10" Canvas.Top="4" FontWeight="Bold" />
            <StackPanel Orientation="Horizontal" Margin="5,0,15,0" Canvas.Top="25" >
                <TextBlock Text="US State Name contains:" Margin="10,0,0,0" VerticalAlignment="Center"/>
                <TextBox x:Name="StateNameTextBox" Text="New" Height="23" HorizontalAlignment="Left" VerticalAlignment="Center" Width="125" TextWrapping="NoWrap"
                     Margin="10,0,10,0" FontSize="12" Background="White" AcceptsReturn="False" />
                <Button Content="Do Query" Width="75" VerticalAlignment="Center" HorizontalAlignment="Right" Click="QueryButton_Click" Margin="0,0,10,0" Cursor="Hand" />
            </StackPanel>
           
            <slData:DataGrid x:Name="QueryDetailsDataGrid" AutoGenerateColumns="False" HeadersVisibility="Column" Background="White"
                             IsReadOnly="True" Canvas.Left="10" Canvas.Top="50" Height="140" Width="530"
                             HorizontalScrollBarVisibility="Hidden">
                <slData:DataGrid.Columns>
                    <slData:DataGridTextColumn Width="85" Binding="{Binding Attributes[STATE_NAME]}" Header="State Name"/>
                    <slData:DataGridTextColumn Width="110" Binding="{Binding  Attributes[SUB_REGION] }" Header="Region"/>
                    <slData:DataGridTextColumn Width="45" Binding="{Binding  Attributes[STATE_FIPS] }" Header="FIPS"/>
                    <slData:DataGridTextColumn Width="85" Binding="{Binding  Attributes[STATE_ABBR] }" Header="Abbreviation"/>
                    <slData:DataGridTextColumn Width="103" Binding="{Binding  Attributes[POP2000] }" Header="Population 2000"/>
                    <slData:DataGridTextColumn Width="102" Binding="{Binding  Attributes[POP2007] }" Header="Population 2007"/>
                </slData:DataGrid.Columns>
            </slData:DataGrid>
        </Canvas>
       
    </Grid>

 public partial class QueryWithoutMap : UserControl
    {
        public QueryWithoutMap()
        {
            InitializeComponent();
        }

        void QueryButton_Click(object sender, RoutedEventArgs e)
        {
            QueryTask queryTask =
                new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5");
            queryTask.ExecuteCompleted += QueryTask_ExecuteCompleted;
            queryTask.Failed += QueryTask_Failed;

            ESRI.ArcGIS.Client.Tasks.Query query = new ESRI.ArcGIS.Client.Tasks.Query();
            query.Text = StateNameTextBox.Text;

            query.OutFields.Add("*");
            queryTask.ExecuteAsync(query);
        }

        void QueryTask_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
        {
            FeatureSet featureSet = args.FeatureSet;

            if (featureSet != null && featureSet.Features.Count > 0)
                QueryDetailsDataGrid.ItemsSource = featureSet.Features;
            else
                MessageBox.Show("No features returned from query");
        }

        private void QueryTask_Failed(object sender, TaskFailedEventArgs args)
        {
            MessageBox.Show("Query execute error: " + args.Error);
        }
    }


这段代码中注意 query.Text = StateNameTextBox.Text;和 query.OutFields.Add("*")。query.Text值对应Url中的子图层的显示字段,也就是在Url中图层的显示字段中模糊查找query.Text。直接访问Uri会看到Display Field: STATE_NAME,这样就等同另种写法query.Where = "STATE_NAME like '%" + StateNameTextBox.Text + "%'";

query.OutFields.Add("*")表示返回所有属性字段。

下面看一个QueryTask查询空间的实例:

 

<Grid x:Name="LayoutRoot" Background="White">

        <Grid.Resources>
            <Style x:Key="MyCustomRow" TargetType="slData:DataGridRow">
                <Setter Property="IsTabStop" Value="False" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="slData:DataGridRow">
                            <slPrimitives:DataGridFrozenGrid Name="Root">
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualStateGroup.Transitions>
                                            <VisualTransition GeneratedDuration="0" />
                                        </VisualStateGroup.Transitions>
                                        <VisualState x:Name="Normal" >
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To=".5"/>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#ebf4fa"/>
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Normal AlternatingRow">
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="0"/>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#bbd9ee"/>
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="MouseOver">
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To=".5"/>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#8800FFFF"/>
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Normal Selected">
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#8800FFFF"/>
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="MouseOver Selected">
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#8800FFFF"/>
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Unfocused Selected">
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#8800FFFF"/>
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>

                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*"/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>

                                <Grid.Resources>
                                    <Storyboard x:Key="DetailsVisibleTransition">
                                        <DoubleAnimation Storyboard.TargetName="DetailsPresenter" Storyboard.TargetProperty="ContentHeight"
                                           Duration="00:00:0.1" />
                                    </Storyboard>
                                </Grid.Resources>

                                <Rectangle x:Name="BackgroundRectangle" Grid.RowSpan="2" Grid.ColumnSpan="2" Opacity="0"
                                           Fill="#FFFFCC00"/>

                                <slPrimitives:DataGridRowHeader Grid.RowSpan="3" Name="RowHeader"
                                           slPrimitives:DataGridFrozenGrid.IsFrozen="True" />
                                <slPrimitives:DataGridCellsPresenter Grid.Column="1" Name="CellsPresenter"
                                           slPrimitives:DataGridFrozenGrid.IsFrozen="True" />
                                <slPrimitives:DataGridDetailsPresenter Grid.Row="1" Grid.Column="1" Name="DetailsPresenter" />
                                <Rectangle Grid.Row="2" Grid.Column="1" Name="BottomGridLine" HorizontalAlignment="Stretch"
                                           Height="1" />
                            </slPrimitives:DataGridFrozenGrid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

            <symbol:SimpleMarkerSymbol x:Key="DefaultMarkerSymbol" Color="Red" Size="12" Style="Circle" />
            <symbol:SimpleLineSymbol x:Key="DefaultLineSymbol" Color="Red" Width="4" />
            <symbol:FillSymbol x:Key="DefaultFillSymbol" >
                <symbol:FillSymbol.ControlTemplate>
                    <ControlTemplate>
                        <Path x:Name="Element" IsHitTestVisible="False" Fill="#66FF0000"
                            Stroke="Red" StrokeThickness="1"/>
                    </ControlTemplate>
                </symbol:FillSymbol.ControlTemplate>
            </symbol:FillSymbol>
            <symbol:FillSymbol x:Key="ResultsFillSymbol">
                <symbol:FillSymbol.ControlTemplate>
                    <ControlTemplate x:Name="CustomPolygonTemplate">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal">
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="Element"
                                                Storyboard.TargetProperty="(Fill).(Color)"
                                                To="#880000FF" Duration="0:0:0.1" />
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="Element"
                                                Storyboard.TargetProperty="(Fill).(Color)"
                                                To="#8800FFFF" Duration="0:0:0.1" />
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="Element"
                                                Storyboard.TargetProperty="(Fill).(Color)"
                                                To="#8800FFFF" Duration="0:0:0.1" />
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Path x:Name="Element" Stroke="Blue" Fill="#880000FF"
                                StrokeStartLineCap="Round" StrokeThickness="2"
                                StrokeLineJoin="Round" StrokeEndLineCap="Round" />
                        </Grid>
                    </ControlTemplate>
                </symbol:FillSymbol.ControlTemplate>
            </symbol:FillSymbol>
        </Grid.Resources>

        <esri:Map x:Name="MyMap" WrapAround="True" Extent="-15000000,2000000,-7000000,8000000">
            <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer"
                      Url=">
            <esri:GraphicsLayer ID="MySelectionGraphicsLayer" />
        </esri:Map>

    </Grid>

 

注意引入xmlns:slPrimitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"

 

后台:

 public partial class MainPage : UserControl
    {
        private Draw MyDrawSurface;

        public MainPage()
        {
            InitializeComponent();

            MyDrawSurface = new Draw(MyMap)
            {
              LineSymbol = LayoutRoot.Resources["DefaultLineSymbol"] as SimpleLineSymbol,
              FillSymbol = LayoutRoot.Resources["DefaultFillSymbol"] as FillSymbol
            };
            MyDrawSurface.DrawComplete += MyDrawSurface_DrawComplete;
            MyDrawSurface.DrawMode = DrawMode.Point;

            MyDrawSurface.IsEnabled = true;
        }


        private void MyDrawSurface_DrawComplete(object sender, ESRI.ArcGIS.Client.DrawEventArgs args)
        {
            GraphicsLayer selectionGraphicslayer = MyMap.Layers["MySelectionGraphicsLayer"] as GraphicsLayer;
            selectionGraphicslayer.ClearGraphics();

            QueryTask queryTask = new QueryTask("

http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5");
            queryTask.ExecuteCompleted += QueryTask_ExecuteCompleted;
            queryTask.Failed += QueryTask_Failed;

            // Bind data grid to query results
            Binding resultFeaturesBinding = new Binding("LastResult.Features");
            resultFeaturesBinding.Source = queryTask;

            Query query = new ESRI.ArcGIS.Client.Tasks.Query();

            // Specify fields to return from query
            query.OutFields.AddRange(new string[] { "STATE_NAME", "SUB_REGION", "STATE_FIPS", "STATE_ABBR", "POP2000", "POP2007" });
            query.Geometry = args.Geometry;

            // Return geometry with result features
            query.ReturnGeometry = true;
            query.OutSpatialReference = MyMap.SpatialReference;

            queryTask.ExecuteAsync(query);
        }

        private void QueryTask_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
        {
            FeatureSet featureSet = args.FeatureSet;

            if (featureSet == null || featureSet.Features.Count < 1)
            {
                MessageBox.Show("No features retured from query");
                return;
            }

            GraphicsLayer graphicsLayer = MyMap.Layers["MySelectionGraphicsLayer"] as GraphicsLayer;

            if (featureSet != null && featureSet.Features.Count > 0)
            {
                foreach (Graphic feature in featureSet.Features)
                {
                    feature.Symbol = LayoutRoot.Resources["ResultsFillSymbol"] as FillSymbol;
                    graphicsLayer.Graphics.Insert(0, feature);
                }
              
            }
            MyDrawSurface.IsEnabled = true;

            //MyDrawSurface.IsEnabled = (MyDrawSurface.DrawMode != DrawMode.None);
        }

        private void QueryTask_Failed(object sender, TaskFailedEventArgs args)
        {
            MessageBox.Show("Query failed: " + args.Error);
        }

        private void QueryDetailsDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            foreach (Graphic g in e.AddedItems)
                g.Select();

            foreach (Graphic g in e.RemovedItems)
                g.UnSelect();
        }
    }

运行,在地图上单击。

这个实例相信大家先运行操作之后,再简单看看代码就会明白,在这我不解释,另外如果我们再往深处想一下,可以利用这点进行缓冲区的查询。

最后总之,大家记住进行空间和属性查询就是QueryTask的主要应用。后面我们再介绍FindTask和IdentifyTask两个常用的功能类。

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leesmn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值