PoiSearchActivity sample: add search by tag (#579)

This commit is contained in:
Gustl22 2018-09-02 14:45:01 +02:00 committed by Emux
parent 7a7ceb6d60
commit da09a62605
No known key found for this signature in database
GPG Key ID: 64ED9980896038C3
5 changed files with 246 additions and 9 deletions

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.oscim.android.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ToggleButton
android:id="@+id/toggleControls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|start"
android:onClick="onToggleControls" />
<LinearLayout
android:id="@+id/controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#bb000000"
android:orientation="vertical"
android:padding="10dp"
android:visibility="gone">
<ListView
android:id="@+id/search_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/add_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/add" />
<Button
android:id="@+id/start_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/key"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/search_key"
android:inputType="text"
android:maxLines="1"
android:textColor="@android:color/white" />
<EditText
android:id="@+id/value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/search_value"
android:inputType="text"
android:maxLines="1"
android:textColor="@android:color/white" />
<Button
android:id="@+id/remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/remove" />
</LinearLayout>

View File

@ -7,10 +7,6 @@
<string name="theme_tubes">Tubes</string>
<string name="theme_newtron">NewTron</string>
<string name="theme_external">External theme</string>
<string name="ok">OK</string>
<string name="cancel">Cancel</string>
<string name="error">Error</string>
<string name="file_invalid">The selected file is invalid.</string>
<string name="styler_mode_line">Line</string>
<string name="styler_mode_area">Area</string>
<string name="styler_mode_outline">Outline</string>
@ -19,5 +15,14 @@
<string name="style_2">Hide nature</string>
<string name="menu_gridlayer">Grid</string>
<string name="dialog_reverse_geocoding_title">Reverse Geocoding</string>
<string name="add">Add</string>
<string name="cancel">Cancel</string>
<string name="error">Error</string>
<string name="file_invalid">The selected file is invalid.</string>
<string name="ok">OK</string>
<string name="remove">Remove</string>
<string name="search">Search</string>
<string name="search_key">\'*\' or OSM key</string>
<string name="search_value">void or value</string>
</resources>

View File

@ -80,6 +80,11 @@ public class MapsforgeActivity extends MapActivity {
mS3db = s3db;
}
public MapsforgeActivity(boolean s3db, int contentView) {
super(contentView);
mS3db = s3db;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

View File

@ -1,5 +1,6 @@
/*
* Copyright 2017-2018 devemux86
* Copyright 2018 Gustl22
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
@ -14,12 +15,24 @@
*/
package org.oscim.android.test;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.ToggleButton;
import org.mapsforge.core.model.Tag;
import org.mapsforge.poi.android.storage.AndroidPoiPersistenceManagerFactory;
import org.mapsforge.poi.storage.ExactMatchPoiCategoryFilter;
import org.mapsforge.poi.storage.PoiCategoryFilter;
@ -70,10 +83,47 @@ public class PoiSearchActivity extends MapsforgeActivity implements ItemizedLaye
}
}
public PoiSearchActivity() {
super(false, R.layout.activity_map_poi);
}
private void initSearch() {
final List<Pattern> searchPatterns = new ArrayList<>();
final PatternAdapter adapter = new PatternAdapter(this, searchPatterns);
ListView searchList = (ListView) findViewById(R.id.search_list);
searchList.setAdapter(adapter);
Button addItem = (Button) findViewById(R.id.add_item);
addItem.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
searchPatterns.add(new Pattern("", ""));
adapter.notifyDataSetChanged();
}
});
Button startSearch = (Button) findViewById(R.id.start_search);
startSearch.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Clear overlays
mMarkerLayer.removeAllItems();
mMap.render();
// POI search
List<Tag> tags = new ArrayList<>();
for (Pattern pattern : searchPatterns)
tags.add(new Tag(pattern.key, pattern.val));
new PoiSearchTask(PoiSearchActivity.this, null, tags).execute(mMap.getBoundingBox(0));
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initSearch();
// Map events receiver
mMap.layers().add(new PoiSearchActivity.MapEventsReceiver(mMap));
}
@ -128,6 +178,11 @@ public class PoiSearchActivity extends MapsforgeActivity implements ItemizedLaye
return false;
}
public void onToggleControls(View view) {
findViewById(R.id.controls).setVisibility(((ToggleButton) view).isChecked() ?
View.VISIBLE : View.GONE);
}
private class MapEventsReceiver extends Layer implements GestureListener {
MapEventsReceiver(Map map) {
@ -141,20 +196,99 @@ public class PoiSearchActivity extends MapsforgeActivity implements ItemizedLaye
mMarkerLayer.removeAllItems();
mMap.render();
// POI search
new PoiSearchTask(PoiSearchActivity.this, POI_CATEGORY).execute(mMap.getBoundingBox(0));
new PoiSearchTask(PoiSearchActivity.this, POI_CATEGORY, null).execute(mMap.getBoundingBox(0));
return true;
}
return false;
}
}
private class Pattern {
String key;
String val;
Pattern(String key, String val) {
this.key = key;
this.val = val;
}
}
private class PatternAdapter extends ArrayAdapter<Pattern> {
PatternAdapter(Context context, List<Pattern> patterns) {
super(context, 0, patterns);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Pattern pattern = getItem(position);
assert pattern != null;
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null)
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_poi_search, parent, false);
// Populate the data
EditText etKey = (EditText) convertView.findViewById(R.id.key);
etKey.removeTextChangedListener((PatternTextWatcher) etKey.getTag()); // remove previous listeners
etKey.setText(pattern.key); // set text when no listener is attached
PatternTextWatcher ptwKey = new PatternTextWatcher(pattern, true);
etKey.setTag(ptwKey);
etKey.addTextChangedListener(ptwKey);
EditText etValue = (EditText) convertView.findViewById(R.id.value);
etValue.removeTextChangedListener((PatternTextWatcher) etValue.getTag());
etValue.setText(pattern.val);
PatternTextWatcher ptwVal = new PatternTextWatcher(pattern, false);
etValue.setTag(ptwVal);
etValue.addTextChangedListener(ptwVal);
Button remove = (Button) convertView.findViewById(R.id.remove);
remove.setTag(pattern);
remove.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Pattern pat = (Pattern) v.getTag();
remove(pat);
}
});
return convertView;
}
}
private class PatternTextWatcher implements TextWatcher {
private Pattern pattern;
private boolean isKey;
PatternTextWatcher(Pattern pattern, boolean isKey) {
this.pattern = pattern;
this.isKey = isKey;
}
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (isKey)
pattern.key = s.toString();
else
pattern.val = s.toString();
}
}
private class PoiSearchTask extends AsyncTask<BoundingBox, Void, Collection<PointOfInterest>> {
private final WeakReference<PoiSearchActivity> weakActivity;
private final String category;
private final List<Tag> patterns;
private PoiSearchTask(PoiSearchActivity activity, String category) {
private PoiSearchTask(PoiSearchActivity activity, String category, List<Tag> patterns) {
this.weakActivity = new WeakReference<>(activity);
this.category = category;
this.patterns = patterns;
}
@Override
@ -163,11 +297,12 @@ public class PoiSearchActivity extends MapsforgeActivity implements ItemizedLaye
try {
PoiCategoryManager categoryManager = mPersistenceManager.getCategoryManager();
PoiCategoryFilter categoryFilter = new ExactMatchPoiCategoryFilter();
categoryFilter.addCategory(categoryManager.getPoiCategoryByTitle(category));
if (category != null)
categoryFilter.addCategory(categoryManager.getPoiCategoryByTitle(category));
org.mapsforge.core.model.BoundingBox bb = new org.mapsforge.core.model.BoundingBox(
params[0].getMinLatitude(), params[0].getMinLongitude(),
params[0].getMaxLatitude(), params[0].getMaxLongitude());
return mPersistenceManager.findInRect(bb, categoryFilter, null, Integer.MAX_VALUE);
return mPersistenceManager.findInRect(bb, categoryFilter, patterns, Integer.MAX_VALUE);
} catch (Throwable t) {
log.error(t.getMessage(), t);
}
@ -180,7 +315,8 @@ public class PoiSearchActivity extends MapsforgeActivity implements ItemizedLaye
if (activity == null) {
return;
}
Toast.makeText(activity, category + ": " + (pointOfInterests != null ? pointOfInterests.size() : 0), Toast.LENGTH_SHORT).show();
Toast.makeText(activity, (category != null ? category : "Results") + ": "
+ (pointOfInterests != null ? pointOfInterests.size() : 0), Toast.LENGTH_SHORT).show();
if (pointOfInterests == null) {
return;
}