2014年4月11日金曜日

Azure sql server上保存された場所を現在地からの距離順で表示

Azure sql serverのtableに場所名とその位置情報を保存している。
現在地からの距離順で場所を表示させる方法。

Azure mobile serviceのtableスクリプトを利用する。
読み取り操作に、以下のスクリプトを入れる。
requestのパラメータとして、現在地の経度と緯度をserver scriptに渡す。
SHOPINFOのGPSLOC列から位置情報を取り出し、距離を計算する。

function read(query, user, request) {
    var lat = request.parameters.lat;
    var lng = request.parameters.lng;
    var sql = "DECLARE @g geography;"+
              "SET @g = geography::Point(?,?, 4326);"+
              "SELECT *,round(@g.STDistance(GPSLOC),0) as DIST from [dbo].SHOPINFO order by DIST;"
    mssql.query(sql,[lat,lng],{success: function(results) {
        request.respond(200,results);
    }
    })
}

アプリから、get methodで以下のURLにアクセスする。
https://abcdef.azure-mobile.net/tables/shopinfo?lat=latitudeFromGps&lng=longitudeFromGps


参考になったページ:http://hatsune.hatenablog.jp/entry/2014/02/06/092155

2014年2月25日火曜日

既存のAzure上テーブルをmobile serviceにリンクさせる

Azureのsql server管理ポータルでmobile serviceと同じ名前のキスーマに追加し、編集してあるテーブルをmobile serviceにリンクさせるには、mobile serviceのDATAタブの「CRAETE」をクリックし、既存のテーブル名を指定するだけで、リンクできる。

以下のURLには、もっと詳しい情報がある。
http://blogs.msdn.com/b/jpsanders/archive/2013/05/24/using-an-existing-azure-sql-table-with-windows-azure-mobile-services.aspx

2014年2月24日月曜日

sql serverによる2点間の距離を出す

位置gとsql serverに保存している位置h間の距離を出すには、以下のTransact-SQLを使用

DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::Point(35.66263195952044,139.7095092421263, 4326);
set @h = (select location from [dbo].[Landmark] where id=1);
SELECT @g.STDistance(@h);

sql serverにおける位置情報の保存

Azure mobile serviceのDBはsql serverとなっている。アプリで位置情報を扱うため、その保存方法を調べてみた。以下の文章に、3つが書かれている。
http://www.sql-server-helper.com/sql-server-2008/convert-latitude-longitude-to-geography-point.aspx


  • 方法1、STPointFromTextを使用

ALTER TABLE [dbo].[Landmark]
ADD [GeoLocation] GEOGRAPHY
GO

UPDATE [dbo].[Landmark]
SET [GeoLocation] = geography::STPointFromText('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' + CAST([Latitude] AS VARCHAR(20)) + ')', 4326)
GO

ここは、経度Latitudeより緯度Longitudeが先に来ている。


  • 方法2、STGeomFromTextを使用

UPDATE [dbo].[Landmark]
SET [GeoLocation] = geography::STGeomFromText('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' + CAST([Latitude] AS VARCHAR(20)) + ')', 4326)
GO

STGeomFromText は、POINT以外 POLYGON, LINESTRING, MULTIPOINT, MULTIPOLYGON, MULTILINESTRING and GEOMETRYCOLLECTIONもサポートしている。


  • 方法3、geography::Pointを使用

UPDATE [dbo].[Landmark]
SET [GeoLocation] = geography::Point([Latitude], [Longitude], 4326)
GO

ここは、経度Latitudeが先で、一番使いやすいと思う。


  • 方法4、geography::Parseを使用

UPDATE [dbo].[Landmark]
SET [GeoLocation] = geography::Parse('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' +
                    CAST([Latitude] AS VARCHAR(20)) + ')')
GO

geography::STGeomFromText と唯一の違いは、spatial reference ID (SRID) 4326の指定は不要。

2014年1月29日水曜日

PhoneGapをインストールには

PhoneGapをインストールには、まずnode.jsをインストール
Android開発には、Eclipse with ADTが必要、そして、PATHにはADTツールを通す
環境変数JAVA_HOMEを設定(ADTはJAVAベース)
Ant(JAVA build用)をインストール、ANT_HOMEを設定、antをPATHに通す

2014年1月26日日曜日

apkファイルをエミュレータにインストール

Genymotionを入れた。Eclipseのエミュレータよりずっと速かった。
apkファイルをインストールには、エミュレータを起動してから、以下のコマンドとなる。

adb install xxx.apk

2013年10月13日日曜日

Azure SQLのデータをListViewに表示させる


public class MainActivity extends Activity {

MobileServiceClient mClient;
MobileServiceTable<TokutenItem> mTokutenTable;
TokutenItemAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.benefit_list);
// 1)ListViewとadapterを設定、rowのlayoutも紐づく
mAdapter = new TokutenItemAdapter(this, R.layout.benifit_cell);
ListView listViewBenefit = (ListView) findViewById(R.id.benefitList);
listViewBenefit.setAdapter(mAdapter);

try {
// 2)Create the Mobile Service Client instance, using the provided
// Mobile Service URL and key
mClient = new MobileServiceClient(
        "https://xxxxxxx.azure-mobile.net/",
"keyforAzuraMobileService"
this);

// 3)Get the Mobile Service Table instance to use
mTokutenTable = mClient.getTable(TokutenItem.class);
} catch (MalformedURLException e) {
createAndShowDialog(new Exception("There was an error creating the Mobile Service. Verify the URL"), "Error");
}
// 4)SQL実行
mTokutenTable.where().field("venusId").eq("4e25173e091a817e3dd67300")
.execute(new TableQueryCallback<TokutenItem>() {
                          // 5)SQL完了したあとのcallbackでadapterを更新
public void onCompleted(List<TokutenItem> result, 
        int count,
                Exception exception, 
                ServiceFilterResponse response) {   
   if (exception == null) {
mAdapter.clear();
        for (TokutenItem item : result) {
mAdapter.add(item);
}

   } else {
        createAndShowDialog(exception, "Error");
  }
        }
});
}

Adapterの設計

public class TokutenItemAdapter extends ArrayAdapter<TokutenItem>{
/**
* Adapter context
*/
Context mContext;

/**
* Adapter View layout
*/
int mLayoutResourceId;

public TokutenItemAdapter(Context context, int layoutResourceId) {
super(context, layoutResourceId);

mContext = context;
mLayoutResourceId = layoutResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;

final TokutenItem currentItem = getItem(position);

if (row == null) {//再利用できるrowがあるかどうかをチェック、なければ新規作成
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
row = inflater.inflate(mLayoutResourceId, parent, false);
}

//rowのlayoutになにを表示させるかを設定
TextView pointTv = (TextView) row.findViewById(R.id.point);
TextView priceDownTv = (TextView) row.findViewById(R.id.priceDown);
pointTv.setText(Float.toString(currentItem.getPointUp()));
priceDownTv.setText(Integer.toString(currentItem.getPriceDown()));
return row;
}

}