GPSの研究　その21

#概要
GPSを理解したかった。
android1.6でナビ作って見た。

#写真
地図は、出ない。
方角と距離で、辿り着く。
赤丸が目的地、青丸が北。

![device-2018-06-21-143303.png](https://qiita-image-store.s3.amazonaws.com/0/18104/5bf363b1-df76-e3c2-6124-cb991c541c75.png)

#サンプルコード


```
package com.ohisamallc.ohiapp128;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.hardware.GeomagneticField;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.Toast;

public class ohiapp34 extends Activity implements LocationListener, SensorEventListener
{
	private static final String TAG = "ohiapp34";
	private static final String[] locationProviders = {
		LocationManager.GPS_PROVIDER
	};
	private LocationManager locationManager;
	private rdView rdView;
	private EditText et0;
	private EditText et1;
	private SensorManager sensorManager;
	private Sensor orienter;
	private Sensor magter;
	private Sensor accter;
	private Location locb;
	private static final int MATRIX_SIZE = 16;
	float[] inR = new float[MATRIX_SIZE];
	float[] outR = new float[MATRIX_SIZE];
	float[] I = new float[MATRIX_SIZE];
	float[] ov = new float[3];
	float[] acc = new float[3];
	float[] mag = new float[3];
	private GeomagneticField geomagnetic;
	private String add;
 	@Override public void onCreate(Bundle savedInstanceState)
	{
 		super.onCreate(savedInstanceState);
 		Intent intent = getIntent();
		Bundle extra = intent.getExtras();
		add = extra.getString("add");
		String[] csv = add.split(" > ");
		String[] a = csv[1].split(",");
		rdView = new rdView(this);
		TableLayout tableLayout = new TableLayout(this);
		et0 = new EditText(this);
		et0.setWidth(150);
		et1 = new EditText(this);
		et1.setWidth(220);
		et0.setText(csv[0]);
		et1.setText(csv[1]);
		TableRow tableRow1 = new TableRow(this);
		tableRow1.addView(et0);
		TableRow tableRow2 = new TableRow(this);
		tableRow2.addView(et1);
		tableLayout.addView(tableRow1, new TableLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
		tableLayout.addView(tableRow2, new TableLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
		tableLayout.addView(rdView, new TableLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
		setContentView(tableLayout);
		locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
		for (String name : locationProviders)
		{
			LocationProvider prov = locationManager.getProvider(name);
			if (prov != null)
			{
				locationManager.requestLocationUpdates(name, 60000, 0f, this);
				Location loc1 = locationManager.getLastKnownLocation(name);
				if (loc1 != null)
				{
				}
			}
		}
		locb = new Location(LocationManager.GPS_PROVIDER);
		locb.setLatitude(new Float(a[0]));
		locb.setLongitude(new Float(a[1]));
		rdView.setlocb(locb);
		sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
		List<Sensor> list;
		list = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
		if (list.size() > 0) orienter = list.get(0);
		list = sensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD);
		if (list.size() > 0) magter = list.get(0);
		list = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
		if (list.size() > 0) accter = list.get(0);
	}
	@Override protected void onResume()
	{
		super.onResume();
		if (orienter != null)
		{
			sensorManager.registerListener(this, orienter, SensorManager.SENSOR_DELAY_UI);
		}
		if (magter != null)
		{
			sensorManager.registerListener(this, magter, SensorManager.SENSOR_DELAY_UI);
		}
		if (accter != null)
		{
			sensorManager.registerListener(this, accter, SensorManager.SENSOR_DELAY_UI);
		}
	}
	@Override public void onDestroy()
	{
		locationManager.removeUpdates(this);
		locationManager = null;
		sensorManager.unregisterListener(this);
		super.onDestroy();
	}
	public void onLocationChanged(Location loc)
	{
		synchronized (this)
		{
			if (loc.getProvider().equals(LocationManager.GPS_PROVIDER))
			{
				rdView.setloc(loc);
				rdView.invalidate();
				float latitude = new Double(loc.getLatitude()).floatValue();
				float longitude = new Double(loc.getLongitude()).floatValue();
				float altitude = new Double(loc.getAltitude()).floatValue();
				geomagnetic = new GeomagneticField(latitude, longitude, altitude, new Date().getTime());
			}
		}
	}
	public void onProviderEnabled(String provider)
	{
		synchronized (this)
		{
			if (provider.equals(LocationManager.GPS_PROVIDER))
			{
			}
		}
	}
	public void onProviderDisabled(String provider)
	{
		synchronized (this)
		{
			if (provider.equals(LocationManager.GPS_PROVIDER))
			{
			}
		}
	}
	public void onStatusChanged(String provider, int status, Bundle extras)
	{
		synchronized (this)
		{
			if (status == LocationProvider.OUT_OF_SERVICE)
			{
			}
			if (provider.equals(LocationManager.GPS_PROVIDER))
			{
			}
		}
	}
	@Override public void onAccuracyChanged(Sensor arg0, int arg1)
	{
	}
	@Override public void onSensorChanged(SensorEvent event)
	{
		if (event.sensor == orienter)
		{
			rdView.setoriention(event.values);
		}
		if (event.sensor == magter)
		{
			mag = event.values.clone();
		}
		if (event.sensor == accter)
		{
			acc = event.values.clone();
		}
		if (mag != null && acc != null)
		{
			SensorManager.getRotationMatrix(inR, null, acc, mag);
			SensorManager.remapCoordinateSystem(inR, SensorManager.AXIS_MINUS_Z, SensorManager.AXIS_X, outR);
			SensorManager.getOrientation(inR, ov);
			rdView.setov(ov);
			float[] rotate = new float[9];
			SensorManager.getRotationMatrix(rotate, null, acc, mag);
			final float[] orient = new float[3];
			SensorManager.getOrientation(rotate, orient);
			rdView.invalidate();
			float magneticNorth = event.values[SensorManager.DATA_X];
			if (geomagnetic != null)
			{
				float trueNorth = magneticNorth + geomagnetic.getDeclination();
				rdView.settn(trueNorth);
			}
		}
	}
}
class rdView extends View
{
	static final int NUM_SATS = 32;
	private int flg = 1;
	private Location loc;
	private Calendar calen = Calendar.getInstance();
	private float[] ori;
	private float distance;
	private float bearing;
	private Location locb;
	float[] ov = new float[3];
	float tn;
	private Path path = new Path();
	private RectF rect = new RectF();
	public rdView(Context context)
	{
		super(context);
		rect.set(-0.5f, -0.5f, 0.5f, 0.5f);
		path.addRoundRect(new RectF(-0.52f, -0.2f, -0.37f, 0.3f), 0.07f, 0.07f, Path.Direction.CW);
		path.addRoundRect(new RectF(0.38f,  -0.2f, 0.53f,  0.3f), 0.07f, 0.07f, Path.Direction.CW);
		path.addRect(new RectF(-0.34f, -0.17f, 0.36f, 0.3f), Path.Direction.CW);
		path.addRoundRect(new RectF(-0.34f, 0.25f, 0.36f, 0.35f), 0.05f, 0.05f, Path.Direction.CW);
		path.addRoundRect(new RectF(-0.19f,  0.25f, -0.04f, 0.6f), 0.07f, 0.07f, Path.Direction.CW);
		path.addRoundRect(new RectF(0.06f,  0.25f, 0.21f, 0.6f), 0.07f, 0.07f, Path.Direction.CW);
		path.addArc(new RectF(-0.34f, -0.52f, 0.36f, 0.12f), 180, 180);
		path.moveTo(-0.14f, -0.45f);
		path.lineTo(-0.24f, -0.6f);
		path.lineTo(-0.23f, -0.61f);
		path.lineTo(-0.13f, -0.46f);
		path.moveTo(0.16f, -0.45f);
		path.lineTo(0.26f, -0.6f);
		path.lineTo(0.28f, -0.61f);
		path.lineTo(0.18f, -0.46f);
	}
	public void settn(float tn)
	{
		this.tn = tn;
	}
	public void setov(float[] ov)
	{
		this.ov = ov;
	}
	public void setoriention(float[] ori)
	{
		this.ori = ori;
	}
	public void setlocb(Location locb)
	{
		this.locb = locb;
	}
	public void setloc(Location loc)
	{
		this.loc = loc;
	}
	public void setflg(int flg)
	{
		this.flg = flg;
	}
	protected void onDraw(Canvas canvas)
	{
		Paint paint = new Paint();
		Paint paint1 = new Paint();
		final int outer = 0xFFC0C0C0;
		final int inner = 0xFFff7010;
		paint.setColor(Color.WHITE);
		paint.setStrokeWidth(2f);
		paint.setStyle(Paint.Style.STROKE);
		int centerX = this.getWidth() / 2;
		int centerY = this.getHeight() / 2;
		float maxRadius = (Math.min(this.getHeight() - 20, this.getWidth()) - 20) / 2;
		double[] elevations = new double[] {0, Math.PI / 2, Math.PI / 3, Math.PI / 6};
		for (double elevation : elevations)
		{
			double radius = (double) Math.cos(elevation) * maxRadius;
		}
		paint.setStyle(Paint.Style.FILL_AND_STROKE);
		paint.setTextSize(30);
		if (flg == 1)
		{
			if (loc != null)
			{
				bearing  = loc.bearingTo(locb);
				distance = loc.distanceTo(locb);
				double h = (double) Math.cos((0 * Math.PI) / 180) * maxRadius;
				int satX = (int) (centerX + h * Math.sin(((360 - ori[0]) * Math.PI) / 180));
				int satY = (int) (centerY - h * Math.cos(((360 - ori[0]) * Math.PI) / 180));
				paint.setColor(Color.BLUE);
				canvas.drawCircle(satX, satY, 10, paint);
				h = (double) Math.cos((30 * Math.PI) / 180) * maxRadius;
				satX = (int) (centerX + h * Math.sin(((360 + bearing - ori[0]) * Math.PI) / 180));
				satY = (int) (centerY - h * Math.cos(((360 + bearing - ori[0]) * Math.PI) / 180));
				paint.setColor(Color.RED);
				canvas.drawCircle(satX, satY, 10, paint);
				canvas.save(Canvas.MATRIX_SAVE_FLAG);
				canvas.translate(centerX, centerY);
				canvas.save(Canvas.MATRIX_SAVE_FLAG);
				paint1.setColor(outer);
				canvas.scale(200, 200);
				canvas.drawOval(rect, paint1);
				canvas.restore();
				canvas.scale(140, 140);
				paint1.setColor(Color.YELLOW);
				canvas.rotate(360 + bearing - ori[0]);
				canvas.drawPath(path, paint1);
				canvas.restore();
				paint.setColor(Color.DKGRAY);
				String p;
				p = "distance " + new Float(distance / 1000).toString() + " km";
				canvas.drawText(p, 10, 30, paint);
				p = "Lat " + new Float(loc.getLatitude()).toString();
				canvas.drawText(p, 10, 60, paint);
				p = "Lon " + new Float(loc.getLongitude()).toString();
				canvas.drawText(p, 10, 90, paint);
				p = "Alt " + new Float(loc.getAltitude()).toString() + "m";
				canvas.drawText(p, 10, 150, paint);
				if (loc.getTime() > 0)
				{
					calen.setTimeInMillis(loc.getTime());
					SimpleDateFormat a = new SimpleDateFormat("HH:mm:ss");
					canvas.drawText(a.format(calen.getTime()), 10, 210, paint);
				}
			}
		}
	}
}



```

以上。