安卓智能地图开发与实施十三:空间查询与展示 - ArcGIS Runtime SDK for Android(Version 100.0.0)
空间查询与展示空间查询需要入口(屏幕触摸、文字输入,甚至绘制个Geometry进行查询),也需要展示容器,如果查询仅仅返回一条记录,在地图中弹出窗口展示信息足矣。当返回多条记录,特别是多个图层的多条记录便需要类似AnimatedExpandableListView的容器来放置查询结果。
空间查询与展示
空间查询需要入口(屏幕触摸、文字输入,甚至绘制个Geometry进行查询),也需要展示容器,如果查询仅仅返回一条记录,在地图中弹出窗口展示信息足矣。当返回多条记录,特别是多个图层的多条记录便需要类似AnimatedExpandableListView的容器来放置查询结果。
查询效果(脖子不好时):
写在开头
源程序请自行下载:
链接:http://pan.baidu.com/s/1qXJ6LxM 密码:uh2d
若失效,可发邮件给韩源萌(polyline@126.com)索要。
后面的都是废话(代码解释)
搜索菜单
空间查询的入口可以是个按钮,找一个类似ArcMap中的Identify图标的图片作为菜单的icon 即可。SearchView是Android原生的搜索框控件,它提供了一个用户界面,用于用户搜索查询。
main_activity_header_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--搜索菜单-->
<item
android:id="@+id/action_identify"
android:orderInCategory="50"
android:title="空间查询"
app:showAsAction="always"
android:icon="@drawable/ic_action_search_identity"/>
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:orderInCategory="50"
android:title="属性搜索"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"/>
</menu>
处理空间查询
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_identify) {
//this.OpenBottomPanelFunction();
mainConfigurations.ChangeMapViewOnTouchFunction(Configurations.MapTouchType.TOTALIDENTIFY);
return true;
}
return super.onOptionsItemSelected(item);
}
处理文本查询
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_activity_header_menu, menu);
MenuItem menuItemSearch = menu.findItem(R.id.action_search);//在菜单中找到对应控件的item
mainSearchView = (SearchView) MenuItemCompat.getActionView(menuItemSearch);
mainSearchView.setQueryHint("查找...");
mainSearchView.setSubmitButtonEnabled(false);
mainSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
final MapQueryClass mapQueryClass = new MapQueryClass();
mapQueryClass.Search(mainConfigurations.getMainReadOperationsFL(),
query,
new IQueryResult() {
@Override
public void getQuery() {
List<MapQueryClass.MapQueryResult> mapQueryResults= mapQueryClass.getMapQueryResult();
for (MapQueryClass.MapQueryResult mapQueryResult:mapQueryResults
) {
mapQueryResult.labelField =
mainConfigurations.GetLayerLabelFieldName(mapQueryResult.featureLayer.getName());
}
mainSearchView.onActionViewCollapsed();
mainSearchView.clearFocus();
ShowSearchResultFunction(mapQueryResults);
}
});
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
MenuItem menuItemidentify = menu.findItem(R.id.action_identify);//在菜单中找到对应控件的item
return true;
}
MapView的触摸事件
MapView的setOnTouchListener没有对应的移除机制。
public void ChangeMapViewOnTouchFunction(MapTouchType type) {
ChangeMapViewOnTouchFunction(type, null);
}
public void ChangeMapViewOnTouchFunction(MapTouchType type, FeatureLayer featureLayer) {
if (mainCallout.isShowing()) {
mainCallout.dismiss();
}
switch (type) {
case SKETCH:
mainSketchGraphicsOverlay.mCanMapTouch = true;
canLayerTouchidentity = false;
canMapTouchidentity = false;
break;
case LAYERIDENTIFY:
mainSketchGraphicsOverlay.mCanMapTouch = false;
canLayerTouchidentity = true;
canMapTouchidentity = false;
StartLayerTouchFunction(featureLayer);
break;
case TOTALIDENTIFY:
mainSketchGraphicsOverlay.mCanMapTouch = false;
canLayerTouchidentity = false;
canMapTouchidentity = true;
StartMapTouchFunction();
break;
case CLEAR:
mainSketchGraphicsOverlay.mCanMapTouch = false;
canLayerTouchidentity = false;
canMapTouchidentity = false;
break;
}
}
这里的代码处理的比较乱,合适的方式是定义一个枚举的变量,没必要弄这么多Boolean。
StartLayerTouchFunction
protected void StartLayerTouchFunction(FeatureLayer featureLayer) {
if(featureLayer == null)
{
return;
}
ClearLayerFunction();
final FeatureLayer mainFeatureLayer = featureLayer;
mainMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mainMapView) {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// remove any existing callouts
if (canLayerTouchidentity == false) {
return super.onSingleTapConfirmed(e);
}
android.graphics.Point screenPoint = new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()));
final Point clickPoint = MapViewMethodsClass.GetMapPointFromScreenPointFunction(mainMapView,screenPoint);
Envelope mapEnvelope = MapViewMethodsClass.GetEnvelopeFromMapPointFunction(
mainMapView,screenPoint,10);
final MapQueryClass mapQueryClass = new MapQueryClass();
mapQueryClass.Select(
mainFeatureLayer,
mapEnvelope,
new IQueryResult() {
@Override
public void getQuery() {
List<MapQueryClass.MapQueryResult> mapQueryResults= mapQueryClass.getMapQueryResult();
for (MapQueryClass.MapQueryResult mapQueryResult:mapQueryResults
) {
mapQueryResult.labelField =
GetLayerLabelFieldName(mapQueryResult.featureLayer.getName());
//mapQueryResult.setFeatureLayerSelected(true);
}
HymnActivity.mainHymnActivity.ShowSearchResultFunction(mapQueryResults);
}
}
);
return super.onSingleTapConfirmed(e);
}
});
}
StartMapTouchFunction
protected void StartMapTouchFunction(){
mainMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this,mainMapView) {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (canMapTouchidentity == false) {
return super.onSingleTapConfirmed(e);
}
ClearLayerFunction();
android.graphics.Point screenPoint =
new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()));
Envelope mapEnvelope =
MapViewMethodsClass.GetEnvelopeFromMapPointFunction(mainMapView,screenPoint,10);
final MapQueryClass mapQueryClass = new MapQueryClass();
mapQueryClass.Select(
mainReadOperationsFL,
mapEnvelope,
new IQueryResult() {
@Override
public void getQuery() {
List<MapQueryClass.MapQueryResult> mapQueryResults= mapQueryClass.getMapQueryResult();
for (MapQueryClass.MapQueryResult mapQueryResult:mapQueryResults
) {
mapQueryResult.labelField =
GetLayerLabelFieldName(mapQueryResult.featureLayer.getName());
//mapQueryResult.setFeatureLayerSelected(true);
}
HymnActivity.mainHymnActivity.ShowSearchResultFunction(mapQueryResults);
}
}
);
return super.onSingleTapConfirmed(e);
}
});
}
ShowMapCallOutFunction
public void ShowMapCallOutFunction(Feature feature){
TextView calloutContent = new TextView(getApplicationContext());
calloutContent.setTextColor(Color.BLACK);
calloutContent.setSingleLine(false);
calloutContent.setVerticalScrollBarEnabled(true);
calloutContent.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
calloutContent.setMovementMethod(new ScrollingMovementMethod());
calloutContent.setMaxWidth(600);
calloutContent.setLines(5);
calloutContent.setText(
AttributeMethodsClass.GetCalloutStringByAttributeFunction(
feature.getAttributes()));
mainCallout.setLocation(GeometryMethodsClass.GetFeatureCenterFunction(feature));
mainCallout.setContent(calloutContent);
mainCallout.show();
}
查询结果的承载 - AnimatedExpandableListView
对AnimatedExpandableListView感兴趣的可参考
https://github.com/idunnololz/AnimatedExpandableListView
main_search_result_group_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingRight="10dp"
android:paddingLeft="40dp">
<TextView
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:id="@+id/resultGroupContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout_editor_absoluteY="0dp"
android:layout_marginLeft="0dp"
app:layout_constraintLeft_toLeftOf="parent" />
<TextView
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="10"
android:id="@+id/resultGroupCountContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout_editor_absoluteY="0dp"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
main_search_result_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingRight="10dp"
android:paddingLeft="50dp">
<TextView
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:id="@+id/resultListContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
SearchResultAdapter.java
package esrichina.hymn.usingmappingbyhymnlocal.Adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.esri.arcgisruntime.data.Feature;
import com.esri.arcgisruntime.layers.FeatureLayer;
import java.util.ArrayList;
import java.util.List;
import esrichina.hymn.ListView.AnimatedExpandableListView;
import esrichina.hymn.MapQuery.MapQueryClass;
import esrichina.hymn.usingmappingbyhymnlocal.R;
/**
* Created by HymnHan on 2017/5/17.
*/
public class SearchResultAdapter extends AnimatedExpandableListView.AnimatedExpandableListAdapter {
private LayoutInflater inflater;
private List<MapQueryClass.MapQueryResult> items = new ArrayList<>();
public SearchResultAdapter(Context context) {
inflater = LayoutInflater.from(context);
}
public void setData(List<MapQueryClass.MapQueryResult> items) {
this.items = items;
}
@Override
public Feature getChild(int groupPosition, int childPosition) {
return items.get(groupPosition).features.get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getRealChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder holder;
MapQueryClass.MapQueryResult mapQueryResult = getGroup(groupPosition);
if (convertView == null) {
holder = new ChildHolder();
convertView = inflater.inflate(R.layout.main_search_result_list_item, parent, false);
holder.title = (TextView) convertView.findViewById(R.id.resultListContainer);
convertView.setTag(holder);
} else {
holder = (ChildHolder) convertView.getTag();
}
holder.title.setText(mapQueryResult.getTitle(childPosition));
holder.mapQueryResult = mapQueryResult;
//holder.hint.setText(item.hint);
return convertView;
}
@Override
public int getRealChildrenCount(int groupPosition) {
return items.get(groupPosition).features.size();
}
@Override
public MapQueryClass.MapQueryResult getGroup(int groupPosition) {
return items.get(groupPosition);
}
@Override
public int getGroupCount() {
return items.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder holder;
MapQueryClass.MapQueryResult mapQueryResult = getGroup(groupPosition);
if (convertView == null) {
holder = new GroupHolder();
convertView = inflater.inflate(R.layout.main_search_result_group_item, parent, false);
holder.title = (TextView) convertView.findViewById(R.id.resultGroupContainer);
holder.count = (TextView) convertView.findViewById(R.id.resultGroupCountContainer);
convertView.setTag(holder);
} else {
holder = (GroupHolder) convertView.getTag();
}
holder.title.setText(mapQueryResult.getLayerTitle());
holder.count.setText("共 " + String.valueOf(mapQueryResult.getFeatureCount()) + " 条");
holder.mapQueryResult = mapQueryResult;
return convertView;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int arg0, int arg1) {
return true;
}
public static class ChildHolder {
public TextView title;
public MapQueryClass.MapQueryResult mapQueryResult;
}
public static class GroupHolder {
public TextView title;
public TextView count;
public MapQueryClass.MapQueryResult mapQueryResult;
}
}
SearchResultComponent.java
package esrichina.hymn.usingmappingbyhymnlocal.Components;
import android.view.View;
import android.widget.ExpandableListView;
import com.esri.arcgisruntime.data.Feature;
import java.util.ArrayList;
import java.util.List;
import esrichina.hymn.ListView.AnimatedExpandableListView;
import esrichina.hymn.MapQuery.MapQueryClass;
import esrichina.hymn.Methods.MapViewMethodsClass;
import esrichina.hymn.usingmappingbyhymnlocal.Adapters.SearchResultAdapter;
import esrichina.hymn.usingmappingbyhymnlocal.R;
/**
* Created by HymnHan on 2017/5/19.
*/
public class SearchResultComponent extends BaseComponent {
private AnimatedExpandableListView searchResultContainer;
private SearchResultAdapter searchResultAdapter;
public SearchResultComponent() {
searchResultAdapter = new SearchResultAdapter(mainHymnActivity);
searchResultContainer = (AnimatedExpandableListView) mainHymnActivity.findViewById(R.id.searchResultContainer);
searchResultContainer.setAdapter(searchResultAdapter);
searchResultContainer.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
SearchResultAdapter.ChildHolder childHolder =
(SearchResultAdapter.ChildHolder) v.getTag();
Feature feature = childHolder.mapQueryResult.features.get(childPosition);
MapViewMethodsClass.CenterMapViewByGeometryFunction(
mainHymnActivity.getMainMapView(),
feature,
10);
childHolder.mapQueryResult.selectFeature(feature);
mainConfigurations.ShowMapCallOutFunction(feature);
return false;
}
});
}
public void ClearSearchResultFunction()
{
searchResultAdapter.setData(new ArrayList<MapQueryClass.MapQueryResult>());
searchResultAdapter.notifyDataSetChanged();
}
public void ShowSearchResultFunction(List<MapQueryClass.MapQueryResult> mapQueryResults)
{
searchResultAdapter.setData(mapQueryResults);
searchResultAdapter.notifyDataSetChanged();
searchResultContainer.expandGroupWithAnimation(0);
}
}
查询结果的承载 - SlidingUpPanelLayout
对SlidingUpPanelLayout感兴趣的可参考
https://github.com/umano/AndroidSlidingUpPanel
<esrichina.hymn.DragUpPanel.SlidingUpPanelLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mainSliding"
android:gravity="bottom"
app:umanoPanelHeight="20dp"
app:umanoShadowHeight="4dp"
app:umanoParallaxOffset="100dp"
app:umanoDragView="@+id/dragView"
app:umanoOverlay="false"
app:umanoScrollableView="@+id/searchResultContainer"
app:umanoAnchorPoint="0.565"
app:umanoFadeColor="@color/geometry_swatch_background"
app:umanoInitialState="hidden">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/main_map_container"/>
<include layout="@layout/main_activity_header_container"/>
</android.support.design.widget.CoordinatorLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical"
android:clickable="true"
android:focusable="false"
android:id="@+id/dragView">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_panel_header"
android:orientation="horizontal"
android:background="@color/bootstrap_brand_info">
</LinearLayout>
<include layout="@layout/main_search_result_container"/>
</LinearLayout>
</esrichina.hymn.DragUpPanel.SlidingUpPanelLayout>
查询结果的清除
更多推荐
所有评论(0)