This document provides information about developing a police traffic map app using Android Google Maps API. It discusses Taiwan's high traffic accident rates, open data mining from government sources, app permissions, location services, map types, gestures, camera controls, markers, polylines/polygons, and converting between coordinates and addresses. It also addresses common issues like testing before release and staying within free usage limits of the Google Maps platform.
4. Opendata挖礦
如果我跟你說:
我知道一個寶藏:那是一個充滿黃金的地方….
You pay your time, you got money.
Open dateTaiwan .國人專屬.
還有: 中國,美加.英法俄 印度 日韓 ,南美, 中東
台灣政府的行政效率低落.
CPU的挖礦速度是1,功耗相當的情況下:
那麼GPU大概就是10,
而ASIC的挖礦速度是2000,。
Open data也是挖礦,非常慢:
但你可能有10%機率挖到鑽石. 90%泥土.
5. App flow
and logic:
取得Open
data 資料
Check
1.internet
2. Server
api alive
Download
in
AsynTask
Gson
parser
Data
ArrayList
& filter
Listview
&
Adapter
User
Condition
(filter) &
User click
marker
→get real
data.
警廣即時路況| 政府資料開放平臺
https://data.gov.tw/dataset/15221
本資料與警廣即時路況查詢網頁至多有1分鐘的時間差,每次取得最後更新的1000
筆路況資料。路況區域︰"A","N","M","S","E"代表"全","北","中","南","東"。
6. Map api
programming
主要步驟
Get map
ready
Get user’s
gps
permission
GPS
setting
Wait
gps
ready
Map
configura
tion
Place
marker
User disable
gps or gps is
slow
User back to
last page or
exit or rotate
screen
No
internet
Zoom
map
User click
marker
Register
location
listener
耗電問題
沒有
google
play
8. AI engine: gps
input and
event output
Input
latitude
and
longitude
Compare
Data
In 1km
Check
Data is
Valid,
Check
time
TTS
Ui show
1000- 100- 1-
9. Specify app
permissions
Android offers two location permissions:
android.permission.ACCESS_COARSE_LOCATION –
Allows the API to use WiFi or mobile cell data (or both) to
determine the device's location.
accuracy approximately equivalent to a city block.
android.permission.ACCESS_FINE_LOCATION –
including the Global Positioning System (GPS) as well asWiFi
and mobile cell data.
Requesting Permissions at RunTime:
If device is Android 6.0 or app target SDK is 23
the app has to request those permissions at run time.
10. Permissions
automatically
merged into
your manifest
The following permissions are defined in the Google Play services
manifest, and are automatically merged into your app's manifest
at build time.
You don't need to add them explicitly to your manifest:
android.permission.INTERNET - Used by theAPI to download map
tiles fromGoogle Maps servers.
android.permission.ACCESS_NETWORK_STATE -Allows theAPI to
check the connection status in order to determine whether data can
be downloaded.
<uses-feature android:glEsVersion="0x00020000"
android:required="true"/>
13. Map types
Normal: Typical road map + roads and city names
Satellite: Satellite photograph data. Road and feature labels are
not visible.
Hybrid: Satellite photograph with road maps added.
Terrain: Topographic data. map with mountains, rivers.
14. Adding a Map
with a Marker
public class MapsMarkerActivity extends AppCompatActivity
implementsOnMapReadyCallback {
@Override
public void onMapReady(GoogleMapgoogleMap)
{
//Add a marker in Sydney,Australia,
// and move the map's camera to the same location.
LatLng sydney = new LatLng(-33.852, 151.211);
googleMap.addMarker(new MarkerOptions().position(sydney)
.title("Marker in Sydney"));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney
));
}
}
18. Gestures
Scroll (pan) gestures
A user can scroll (pan) around the map by dragging the map with
their finger.
UiSettings.setScrollGesturesEnabled(boolean).
Tilt gestures (傾斜)
can tilt the map by placing two fingers on the map and moving
them down or up together to increase or decrease the angle
respectively.
UiSettings.setTiltGesturesEnabled(boolean).
Rotate gestures
by placing two fingers on the map and applying a rotate motion.
UiSettings.setRotateGesturesEnabled(boolean).
20. Move the
camera
private static final LatLng SYDNEY = new LatLng(-33.88,151.21);
private static final LatLng MOUNTAIN_VIEW = new LatLng(37.4, -122.1);
private GoogleMap map;
... // Obtain the map from a MapFragment or MapView.
// Move the camera instantly to Sydney with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomIn());
// Zoom out to zoom level 10, animating with a duration of 2 seconds.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
// Construct a CameraPosition focusing on Mountain View and animate the camera to that position.
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(MOUNTAIN_VIEW) // Sets the center of the map to Mountain View
.zoom(17) // Sets the zoom
.bearing(90) // Sets the orientation of the camera to east
.tilt(30) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
21. Zoom in to all
marker
https://youtu.be/hxEuNRXH2yE
22. My Location
layer
@Override
public void onMapReady(GoogleMap map) {
mMap = map;
// TODO: Before enabling the My Location layer, you must
request
// location permission from the user. This sample does not include
// a request for location permission.
mMap.setMyLocationEnabled(true);
mMap.setOnMyLocationButtonClickListener(this);
mMap.setOnMyLocationClickListener(this);
}
@Override
public void onMyLocationClick(@NonNull Location location) {
Toast.makeText(this, "Current location:n" + location,
Toast.LENGTH_LONG).show();
}
@Override
public boolean onMyLocationButtonClick() {
Toast.makeText(this, "MyLocation button clicked",
Toast.LENGTH_SHORT).show();
// Return false so that we don't consume the event and the
default behavior still occurs
// (the camera animates to the user's current position).
return false;
}
}
24. Polylines and
Polygons
@Override
public void onMapReady(GoogleMap googleMap) {
//Add polylines and polygons to the map.This section shows just
// a single polyline. Read the rest of the tutorial to learn more.
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions()
.clickable(true)
.add(
new LatLng(-35.016, 143.321),
new LatLng(-34.747, 145.592),
new LatLng(-34.364, 147.891),
new LatLng(-33.501, 150.217),
new LatLng(-32.306, 149.248),
new LatLng(-32.491, 147.309)));
// Position the map's camera nearAlice Springs in the center of Australia,
// and set the zoom factor so most ofAustralia shows on the screen.
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(newLatLng(-
23.684, 133.903), 4));
// Set listeners for click events.
googleMap.setOnPolylineClickListener(this);
googleMap.setOnPolygonClickListener(this);
}
polyline.setEndCap(new RoundCap());
polyline.setWidth(POLYLINE_STROKE_WIDTH_PX);
polyline.setColor(COLOR_BLACK_ARGB);
polyline.setJointType(JointType.ROUND);
25. Add a circle in
Sydney
GoogleMap map;
Circle circle = map.addCircle(new CircleOptions()
.center(new LatLng(-33.87365, 151.20689))
.radius(10000)
.strokeColor(Color.RED)
.fillColor(Color.BLUE));
// in meters
26. 使用地名、地
址查詢位置
使用Geocoder
將經緯度轉地
址
Geocoder geocoder = new Geocoder(act, Locale.getDefault());
try
{
final List<Address> addresses = geocoder.getFromLocation(LATITUDE, LONGITUDE,
1);
if( addresses != null )
{
final Address returnedAddress = addresses.get(0);
String strReturnedAddress = "";
final int idx_add = returnedAddress.getMaxAddressLineIndex();
for( int i = 0; i < returnedAddress.getAddressLine(idx_add).length(); i++ )
{
if( returnedAddress.getAddressLine(i) != null )
{
strReturnedAddress += (returnedAddress.getAddressLine(i));
}
}
….
lstAddress.get(0).getCountryName(); //台灣省
lstAddress.get(0).getAdminArea(); //台北市
lstAddress.get(0).getLocality(); //中正區
lstAddress.get(0).getThoroughfare(); //信陽街(包含路巷弄)
lstAddress.get(0).getFeatureName(); //會得到33(號)
lstAddress.get(0).getPostalCode(); //會得到100(郵遞區號)
Geocoder geoCoder = new Geocoder(context, Locale.getDefault());
List<Address> addressLocation = geoCoder.getFromLocationName(addressString, 1);
double latitude = addressLocation.get(0).getLatitude();
double longitude = addressLocation.get(0).getLongitude();
Ps: addressString:地址
28. 我還可以免費
使用Google
地圖平台嗎?
可以。自 2018 年 7 月 16 日起,只要您啟用計費方案,即
可獲得每月 $200 美元的免費額度, 可用於地圖、路線或
Place.
根據目前數百萬位使用者的 Google API 使用情況來判斷,
大部分都在此額度範圍內,多半還是可以繼續 免費使用
Google 地圖.
每月抵免額$200
對應的免費用量
每月用量範圍
(每千次呼叫價格)
0-100,000 100,001-500,000
行動版原生靜態地圖 載入次數不限 $0.00 $0.00
行動版原生動態地圖 載入次數不限 $0.00 $0.00
嵌入 載入次數不限 $0.00 $0.00
進階嵌入 最多 14,000 次載入 $14.00 $11.20
靜態地圖 最多 100,000次載入 $2.00 $1.60
動態地圖 最多 28,000 次載入 $7.00 $5.60
靜態街景服務 最多 28,000 次全景 $7.00 $5.60
動態街景服務 最多 14,000 次全景 $14.00 $11.20
Ps: A web page or application that displays a map using the Maps JavaScript API.
29. MapsAndroid
API key
Go to the Google Cloud Platform Console in your browser
Key type: Android-restricted
app's SHA-1 fingerp rint
BB:0D:AC:74:D3:21:E1:43:67:71:9B:62:91:AF:A1:66:6E:44:5D:75
com.example.android.mapexample
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyBdVl-cTICxwYKrZ95SuvNw7daMuDt1KG0"/>
For backwards compatibility, the API also supports the name
com.google.android.maps.v2.API_KEY. This legacy name allows
authentication to the Android Maps API v2 only.
31. 坑:
比較時間的問
題
Compare date
and time issue
public static final SimpleDateFormat sdf_datetime = new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Date time2 = PBSWarning.sdf_datetime.parse(date1 + " " + time1);
Calendar cal1 = Calendar.getInstance();
cal1.setTime(time2);
cal_now = Calendar.getInstance();
cal_now.add(Calendar.HOUR_OF_DAY, -2);
x2 = cal1.getTime();
x_now = cal_now.getTime();
final boolean b_is_in_range = x_now.before(x2);
return b_is_in_range;
Data
time
now
time