本文章属于项目资料整理,所用资源均来源于网络
需求分析及技术调研
项目描述
- 因公司业务需要开发一款应用在体育赛事指挥调度的软件,用来在地图上定位现场的摄像师实时的位置,和计算摄像师到地图中标定的沿途关键点的路程。
模块划分
- 根据项目描述,需要一个实时采集摄像师的软件,暂且叫做手机位置发射端。需要一个平板地图显示接收端。而中间需要一个服务器端作为转发器,最终采用方案3作为项目实施方案。
关于转发服务器的解决方案
- 直接用socket通信,平板接收端当作Socket服务器,手机当作Socket客户端。后来发现在公网中IP地址总是变化的后来也就放弃这个方案了。
- 用公司服务器开发人员做一个Socket服务器。这个方案被我否绝了,原因是自己做一个Socket服务器没有什么经验,而且需要一个公网ip。
- 采用百度鹰眼传输位置信息。这样一来,平板接收端的SDK体系更加紧凑。因为接收端的地图显示用百度地图,数据传输也是用百度的产品百度鹰眼。
- 采用环信即时通信模块中的点对点聊天功能,可以把位置实时传给平板接收端。据官网上说这个消耗流量很小。但是后来我感觉能用一家的服务都用一家的服务就行了,万一以后环信的服务和百度地图有冲突了不好解决。
关于定位的一些网络资源
全球四大卫星定位系统
- GPS系统(美国)
http://baike.baidu.com/view/1069040.htm
目前世界使用最多的全球卫星导航定位系统是美国的GPS系统,一共由24颗卫星组成。 - 北斗系统(中国)
http://baike.baidu.com/view/590829.htm?fromtitle=%E5%8C%97%E6%96%97%E7%B3%BB%E7%BB%9F&fromid=405303&type=syn
北斗卫星导航系统由空间段计划由35颗卫星组成,包括5颗静止轨道卫星、27颗中地球轨道卫星、3颗倾斜同步轨道卫星。 - GLONASS系统(俄罗斯)
http://baike.baidu.com/view/776922.htm?fromtitle=Glonass%E7%B3%BB%E7%BB%9F&fromid=1968003&type=syn
由27颗工作星和3颗备份星组成。 - 伽利略卫星导航系统(欧盟)
http://baike.baidu.com/view/8985450.htm
系统由30颗卫星组成,其中27颗工作星,3颗备份星。
手机常用的定位技术
- GPS,GLONASS,北斗,iBeacon,A-GPS,WIFI,基站
iBeacon
http://baike.baidu.com/link?url=FTveasqBuouEXTtP6n2l75pXtULlPxZXZ4Q-HowakFy0G35PtJ7ePTRCr8ANvffOflC7FXrTI811Ms8SD4zhwK
A-GPS
http://baike.baidu.com/link?url=JbTGM-D2eLyolW84hIxBVMDUr6OR8Au4Ipj7P2I2HoYhtZ_RsDjVwqouwNWh5wBdB-KZHvyohMViCfrLjVDxhq7myPSAm20IaAZjEcmVmOqN_8xsULJVJQ37FIJxwAEQHakD1fBpqdQ8F7ALuFj_W_
WIFI
http://www.zhihu.com/question/20593603
基站
http://baike.baidu.com/link?url=a3LbIe8pO_kwE1AxGEpc5M8uRgtljlrBk8kSX7peNQZkXzFOR6GFkxC35hYdh73zQm20CVmbT2bHncKuELB2T_
被纠偏的国内电子地图
- 百度地图
之前并没有注意到百度地图上的经纬度坐标点是经过纠偏算法之后的地图,导致最近在做一个关于定位系统软件的时候遇到了些麻烦,我利用Android自带的获取地理经纬度的方法获取到真实的经纬度坐标并把坐标点放在地图上时并没有注意定位点已经偏离了一条街的距离(因为当时两条街挨着很近,而且都是在马路左侧所以当时大意了)。
下面是网上一些解释
gps纠偏及大陆地图偏移原因:http://yanue.net/post-121.html
为何您的坐标不准?如何纠偏? :http://www.cnblogs.com/milkmap/p/3627940.html
百度定位SDK:http://lbsyun.baidu.com/index.php?title=android-locsdk/qa
GPS定位基本原理
手机位置发射端代码
- 功能说明:屏幕上显示经纬度坐标值且需要不断的上报GPS数据到百度服务器,并自定义控件实现GPS卫星信号强度。
xml布局
采用GridLayout实现上半部分的属性和属性值的布局。
底部SNR柱形图采用View绘制而成
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="2"
android:columnOrderPreserved="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:padding="8dp"
android:rowOrderPreserved="true"
android:useDefaultMargins="true"
tools:context=".EagleLaunchActivity" >
<TextView
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="设备ID:" />
<TextView
android:id="@+id/device_id"
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill" />
<TextView
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="GPS状态:" />
<TextView
android:id="@+id/gps_state"
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill" />
<TextView
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="定位精度:" />
<TextView
android:id="@+id/accuracy"
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill" />
<TextView
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="当前速度:" />
<TextView
android:id="@+id/speed"
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill" />
<TextView
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="GPS经度:" />
<TextView
android:id="@+id/longitude"
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill" />
<TextView
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="GPS纬度:" />
<TextView
android:id="@+id/latitude"
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill" />
<TextView
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="GPS海拔:" />
<TextView
android:id="@+id/altitude"
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill" />
<xxx.xxxx.eaglemap_launch.DrawView
android:id="@+id/drawView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_columnSpan="2"
android:layout_gravity="fill"
android:background="#aabbccdd" >
<TextView
android:id="@+id/find_fix"
style="@style/gps_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="SNR柱形图" />
</xxx.xxxx.eaglemap_launch.DrawView>
</GridLayout>
Java代码如下,采用setData()方法赋值。
package xxx.xxxx.eaglemap_launch;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
public class DrawView extends RelativeLayout {
private ArrayList<Satellite> list;
private final int maxSate = 24;//最大卫星数量
private final int unit = 70;//SNR信号最大值
private final int gap = 3;//柱子间隙
private float textSize = 30;//文字大小
private final int threshold30 = 30;
private final int threshold40 = 40;
private final int textSpace = 50;//预留的标题文字空间
private void init() {
textSize = getResources().getDimension(R.dimen.DrawViewTextSize);
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DrawView(Context context) {
super(context);
init();
}
public void setData(ArrayList<Satellite> list) {
this.list = list;
invalidate();//将会调用onDraw方法,触发重绘
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint(Paint.FAKE_BOLD_TEXT_FLAG);
p.setColor(Color.BLACK);
p.setTextSize(textSize);
p.setTextAlign(Align.CENTER);
p.setStyle(Paint.Style.FILL);// 设置填满
int width = canvas.getWidth();
int bottom = canvas.getHeight();
if (list == null) {
return;
}
int length = list.size();
for (int i = 0; i < length; i++) {
Satellite s = list.get(i);
int d = (int) s.snr;
int top = bottom - (bottom - textSpace) / unit * d;
int left = width / maxSate * i;
int right = width / maxSate * (i + 1) - gap;
p.setColor(Color.BLACK);
canvas.drawText(d + "", left + (right - left) / 2, top, p);
if(d >= threshold40 && s.usedInFix) {
p.setColor(Color.GREEN);
} else if (d >= threshold30 && s.usedInFix) {
p.setColor(Color.YELLOW);
} else if (s.usedInFix) {
p.setColor(Color.RED);
} else {
p.setColor(Color.GRAY);
}
canvas.drawRect(left, top, right, bottom, p);
}
}
}