いわゆる逆ジオコーディングってやつです。 普通にGoogle Maps APIに関数があるので簡単です。
プログラム
番地まではほぼ完璧に出ますが、号は登録されてなかったりするので 必ずしもヒットするわけではないです。
そこでPostgisで緯度、経度から住所検索をしようと思ったけど、国交省の位置データは番地さえもないですね。
となると、ZenrinとかZenrinとか・・・w
また君か!と、操作が難しいUITabeViewの再描画処理。
でも今回はうっかりと、かなり初歩的な事を知らないばかりにハマりました。 おかしい!?retainもしているはずなのに・・・。
結論から言うと、取得データの更新が保証されないままUITableViewを再描画をしていました。
まず、UITableView:reloadData をするもスクロールすると「NSMutableArrayの数があわないよ!」みたいな英語のエラーで落ちる。
データが更新されてるいるからと、まさかUITableViewのバインディングがされていないとは気づかなかった・・・。
(1) データを違う結果で取得。 (2) NSMutableArrayにデータが受け渡される。 (3) UITableViewがバインドされていないために、numberOfSectionsInTableView、numberOfRowsInSectionが呼ばれない。 (4) スクロールするとデータ取得したNSMutableArrayで描画が始まる。 (5) スクロール途中でデータ数があわないため落ちる。
UITableView は@synthesizeされているからバインディングされてなくても動作上動いてしまうんですよね。
nilとNULLは違う
これはよく言われる事ですが、まさにこれでした。 データ取得処理でnilでなく、NULLでデータが返えっていたのでcountできていなかったみたいです。
で、[NSNull null] の存在を初めて知りました・・・。
- (void)loadData {
NSMutableArray *results = [[api publicArtistList:indexName :@""] retain];
if (results != nil) {
keys = [[results valueForKey:@"keys"] retain];
artists = [[results valueForKey:@"artists"] retain];
[artistListTable reloadData];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (artistKeys == (NSMutableArray *) [NSNull null]) {
NSLog(@"NULL");
return 0;
} else {
NSLog(@"OK");
return [keys count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (artistKeys == (NSMutableArray *) [NSNull null]) {
NSLog(@"keys NULL");
return 0;
} else if (artists == (NSMutableArray *) [NSNull null]) {
NSLog(@"artists NULL");
return 0;
} else {
NSLog(@"OK");
return [[artists valueForKey:[artistKeys objectAtIndex:section]] count];
}
}
PHPでsvnをある程度自動化したいが、apache権限で実行してしまうので色々不都合がある。 apacheユーザをsvn認証に登録する方法も考えられるが、やはり一般ユーザで実行するのがスマート。
てことで、svnコマンドのオプションを調べたら、
--username --password
がありました(そのままじゃん)。 ※当たり前ですが、ユーザ名、パスワード(BASIC認証)は予め設定してあることが前提
$cmd = "svn mkdir http://hoge.com/svn/repos_name/trunk -m 'trunk' --username 'xxx' --password 'xxx'";
exec($cmd, $output, $ret);
ちなみに、--no-auth-cache を利用すると認証情報をキャッシュしない。
久々にHTMLネタ。 今更ながら、jQueryでリッチテキストエディタを見つけたので。
世の中のCMS、Blogソリューションにも多く導入されているので信頼性は高いようだ。
まず大きく3つに分類される。
markitup/jquery.markitup.js
markitup/sets/set.js
markitup/skins/markitup/style.css
markitup/skins/markitup/images/
パスはhtmlタグで任意に変更してやればよい。
ここでは、別途「Basic Html set」を公式ページからダウンロードして利用しました。 Add-onsも用意されているので、機能拡張も可能です。
ここでの「mySettings」は、set.jsで定義されたもの。
[JScript]
mySettings = {
onShiftEnter: {keepDefault:false, replaceWith:'
\n'},
onCtrlEnter: {keepDefault:false, openWith:'\n
', closeWith:'
\n'}, onTab: {keepDefault:false, openWith:' '}, markupSet: [ {name:'Heading 1', key:'1', openWith:'<h1(!( class="[![Class]!]")!)>', closeWith:'', placeHolder:'Your title here...' }, {name:'Heading 2', key:'2', openWith:'<h2(!( class="[![Class]!]")!)>', closeWith:'', placeHolder:'Your title here...' }, {name:'Heading 3', key:'3', openWith:'<h3(!( class="[![Class]!]")!)>', closeWith:'', placeHolder:'Your title here...' }, {name:'Heading 4', key:'4', openWith:'<h4(!( class="[![Class]!]")!)>', closeWith:'', placeHolder:'Your title here...' }, {name:'Heading 5', key:'5', openWith:'<h5(!( class="[![Class]!]")!)>', closeWith:'', placeHolder:'Your title here...' }, {name:'Heading 6', key:'6', openWith:'<h6(!( class="[![Class]!]")!)>', closeWith:'', placeHolder:'Your title here...' }, {name:'Paragraph', openWith:'<p(!( class="[![Class]!]")!)>', closeWith:'
' }, {separator:'---------------' }, {name:'Bold', key:'B', openWith:'(!(|!|)!)', closeWith:'(!(|!|)!)' }, {name:'Italic', key:'I', openWith:'(!(|!|)!)', closeWith:'(!(|!|)!)' }, {name:'Stroke through', key:'S', openWith:'\n' }, {name:'Ol', openWith:'
\n' }, {name:'Li', openWith:'
各ボタンの機能をオブジェクトとして追加するが、name、openWith、closeWith といったプロパティやコールバック関数が用意されている。
ファイル名を変えたい・・・と言う事が多々あると思います。 Xcodeにもファイル名を変更する機能(関連ファイルも同時に)が多分あるだろうな? と思いつつも、特に使っていなかったり。
流石にファイルやコードが膨大になってくると、手作業では厳しくなってきたり。 と言う事で、
変更したい名称を選択し右クリックから「リファクタリング...」を選択。
変更後の名称を入力し【プレビュー】をクリック。
内容を確認し【適用】をクリックして、ファイル名を変更する。
ビルドすると保存ダイアログが表示されるので【すべてを保存】する。
サンプリング音を12音階で作っていたのですが、 実は基音(C音)のピッチを変更してもわからない程だったので路線変更(?) メモリの節約にはなりそう。
という事で、平均律の計算が必要になってきます。 平均律と尺度
「C=1, C#=2, D=3・・・B=12」として周波数で音を鳴らすには、
double n = (noteIndex - 1)/12.0f;
double pitch = pow(2, n);
alSourcef (_sources[0], AL_PITCH, pitch);
alSourcePlay(_sources[0]);
※_sources[0]はC音のサンプリングバッファ
とりあえず音を上げるだけの処理なので、音を下げる場合は別の計算が必要です。 また再生時に音をピッチを変更しますが、CPU負荷的にどうかは検証してません。
今実験してるプログラムで、サンプリング音(ACCフォーマット)を連続で鳴らす時に
サンプリングによってはプチノイズがはいってしまいます。
DAWをやった事がある人なら経験してると思いますが、
波形のつなぎ目で急激な変化が起こって「プチッ」となるやつです。
えっと、AudioQueueServicesとかでも試しましたが、波形のつなぎ目とかじゃなくても途中で停止すると「プチッ」って鳴りました。 サンプル音がどこで切れるかが重要なんですね。
サンプリング音を長め(4秒弱)にしているので、音が消える前に無理矢理オフにしてしまうので不自然です。
手法的に考えられるのは。
(1) サンプリング音終わりをゲインを0に近づける (2) サンプリング音を短めに作り直して、Attack, Decay, Sustain, Releaseのシンセ方式にする (3) 短いサンプル音を作って音をわける
の2つだとは思います。
理想は(2)なんでしょうけど、OpenALでどうするんだろう?
ちなみに、OpenALの日本語でまとめられたWikiがあります。 OpenAL Wiki
alSourcefにAL_GAINを与えて音量を調節する方法や、Doppler Shift(ドップラー効果)になるんだろうけど、 どの方法が一般的なんだろうか? OpenALマスターには当分慣れそうもない。
MacVimの設定は以下のファイルを設定
/Applications/MacVim.app/Contents/Resources/vim/gvimrc
colorscheme desert
set nobackup
set tabstop=4
set softtabstop=4
set shiftwidth=4
set expandtab
sudo port install postgresql84-server
sudo port install php5-postgresql +postgresql84
sudo mkdir -p /opt/local/var/db/postgresql84/defaultdb sudo chown postgres:postgres /opt/local/var/db/postgresql84/defaultdb sudo su postgres -c '/opt/local/lib/postgresql83/bin/initdb -D /opt/local/var/db/postgresql84/defaultdb'
ローカル環境なので、他のホストからの通信を許可する 例)10.0.1.7から
sudo vi /opt/local/var/db/postgresql84/defaultdb/pg_hba.conf
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
host all all 10.0.1.7/32 trust
# IPv6 local connections:
host all all ::1/128 trust
sudo vi /opt/local/var/db/postgresql84/defaultdb/postgresql.conf
listen_addresses = '*'
//起動
sudo -u postgres /opt/local/lib/postgresql84/bin/pg_ctl -D /opt/local/var/db/postgresql84/defaultdb -o "-i" -m immediate start
//停止
sudo -u postgres /opt/local/lib/postgresql84/bin/pg_ctl -D /opt/local/var/db/postgresql84/defaultdb -o "-i" -m immediate stop
//再起動
sudo -u postgres /opt/local/lib/postgresql84/bin/pg_ctl -D /opt/local/var/db/postgresql84/defaultdb -o "-i" -m immediate restart
sudo launchctl load -w /Library/LaunchDaemons/org.macports.postgresql84-server.plist
sudo -u postgres /opt/local/lib/postgresql84/bin/createdb -U postgres -E UNICODE データベース名
メール送信処理は、よっぽどの事がない限りMFMailComposeViewControllerが便利かと思おう。 自らコンポーネントを作らずしてメール送信フォームの表示から送信までやってくれる。
誇張とかじゃなくて、本当に3分クッキングでできてしまいます。
MFMailComposeViewControllerを利用するには、MessageUI.frameworkを追加する必要がある。 そして、MessageUIを読み込んでMFMailComposeViewControllerDelegateを追加
#import
...
@interface MailViewController : UIViewController {
...
- (void)pageMailForm {
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:@"テストタイトル"];
[picker setMessageBody:@"メール本文" isHTML:NO];
//Documentsディレクトリのsample.jpgを添付する
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:@"sample.jpg", song.name];
NSString *filePath = [basePath stringByAppendingPathComponent:fileName];
NSData* fileData = [NSData dataWithContentsOfFile:filePath];
[picker addAttachmentData:fileData mimeType:@"image/jpg" fileName:fileName];
[self presentModalViewController:picker animated:YES];
[picker release];
}
送信ボタンをクリックすると呼ばれるDelegateメソッド。 結果判別やエラー処理で使います。
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
switch (result) {
case MFMailComposeResultSent:
//送信完了
break;
case MFMailComposeResultSaved:
//下書き保存
break;
case MFMailComposeResultCancelled:
//キャンセル
break;
case MFMailComposeResultFailed:
//失敗
break;
}
[self dismissModalViewControllerAnimated:YES];
}
これを元にサブクラスを作ってやれば、もっと幸せになれそうですね。