2016年1月29日金曜日

boost::geometry 自己交差解消

boost::geometry では、自己交差しているポリゴン図形の入力はエラーとして受け付けません。 関連:boost::geometry でもハマった とは言っても、人間の手を介して入力される限り、自己交差しているような図形は後を絶ちません。 やっぱり、これを解消する手段は、是非とも欲しいところであります。 参考:http://boost-geometry.203548.n3.nabble.com/How-to-repair-self-intersections-td4025893.html 参考URLによりますと、開発バージョンの中には、extensions というヘッダが構築されておりまして、その中にありました。
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.

// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#include <algorithm> // for reverse, unique
#include <iostream>
#include <string>

#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/adapted/c_array.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>

#include <boost/geometry/extensions/algorithms/dissolve.hpp>

// dissolve.hpp の中で省略系の namespace が宣言なしに使用されていたので追加
namespace bg = boost::geometry;


BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)


int main(void)
{
    using namespace boost::geometry;

    typedef model::d2::point_xy<double> point_2d;
    typedef model::polygon<point_2d> polygon_2d;
    typedef model::box<point_2d> box_2d;
    typedef model::multi_polygon<polygon_2d> multi_polygon_2d;

    // Define a polygon and fill the outer ring.
    // In most cases you will read it from a file or database
    polygon_2d poly;
    {
        const double coor[][2] = {
          { -162.277344, -684.941406 },
          { -154.300781, -684.707031 },
          { -147.291016, -768.253906 },
          { -148.601562, -752.630859 },
          { -156.675781, -753.292969 },
          { -155.425781, -768.546875 }
      };
      assign_points(poly, coor);
    }

    // Polygons should be closed, and directed clockwise. If you're not sure if that is the case,
    // call the correct algorithm
    correct(poly);

    // 自己交差を解消するためには、出力先はマルチポリゴンである必要があります。
    multi_polygon_2d solved;
    // ポリゴンを入れて、自己交差を解消し、分解して solved に入れます。
    dissolve(poly, solved);
  
  
    // Polygons can be streamed as text
    // (or more precisely: as DSV (delimiter separated values))
    std::cout << dsv(poly) << std::endl;
  
    multi_polygon_2d v;

    try {
      // intersection(poly, poly, v); では例外が発生しますが…
      intersection(solved, solved, v);
    } catch(const std::exception& e) {
      std::cerr << e.what() << std::endl;
    }
    // 大丈夫!

    std::cout << "Clipped output polygons" << std::endl;
    for (multi_polygon_2d::const_iterator it = v.begin(); it != v.end(); ++it)
    {
        std::cout << dsv(*it) << std::endl;
    }
  
    return 0;
}

2016年1月28日木曜日

subversion svnsync お引越し備忘録

subversion で svnsync コマンドを使って、バックアップ構成を構築していますが、日本語ファイルが不味いのか、たまーに invalid XML なんたらとか吐いて同期が取れない場合があります。 そんな時の対処法。 まずは、元のリポジトリからダンプを取ります。
$ svnadmin dump /var/srv/svn/foo_project > foo_project.svndump
自分の環境だと面倒なんで
$ mv foo_project.svndump /var/www/html
とかしておいて、パソコンから
Z:\svn_back> c:\usr\bin\wget http://svnserv/foo_project.svndump
とファイルをコピーしてきて
Z:\svn_back> svnadmin create foo_project
Z:\svn_back> copy pre-revprop-change.bat foo_project\hooks
Z:\svn_back> svndmin load foo_project < foo_project.svndump
Z:\svn_back> svnsync init file:///foo_project http://svnserv/foo_project --allow-non-empty 
ってやれば、引っ越し完了です。 foo_project はプロジェクト名に svnserv は subversion のサーバ名に 置き換えてやってみてください。 関連項目: Subversion バックアップ構成

2016年1月19日火曜日

ウィンドウズのバッチファイルで曜日を取得する

参考:バッチで日付の操作 Linux でシェルスクリプトを書くよりも、Windows のバッチファイルは曲者で苦労します。 今回は、定期で PostgreSQL のバックアップファイルをとりたいので、曜日でローテションする事を考えました。
@echo off
REM 日付の曜日を求める
REM 日付はYYYY/MM/DD 形式とする。結果は環境変数 yobi へ返す。
REM 引数がないときは本日とする。
if "%1"=="" (  
    set orgdate=%date:~-10,10%
) else (
    set orgdate=%1
)

:年月日の分割
set yy=%orgdate:~-10,4%
set mm=%orgdate:~-5,2%
set dd=%orgdate:~-2,2%
set dayfile=%yy%%mm%%dd%

:月日の数値化(8進数対策)
set /a mm=1%mm%-100
set /a dd=1%dd%-100
if "%mm%" LEQ "2" (set /a yy=yy-1&&set /a mm=mm+12)
set /a ans=yy + yy/4 - yy/100 + yy/400 + (13*mm+8)/5 + dd
set /a wday=ans %% 7
if %wday%==0 (
 set youbi=日曜日
 set syoubi=日
) else if %wday%==1 (
 set youbi=月曜日
 set syoubi=月
) else if %wday%==2 (
 set youbi=火曜日
 set syoubi=火
) else if %wday%==3 (
 set youbi=水曜日
 set syoubi=水
) else if %wday%==4 (
 set youbi=木曜日
 set syoubi=木
) else if %wday%==5 (
 set youbi=金曜日
 set syoubi=金
) else if %wday%==6 (
 set youbi=土曜日
 set syoubi=土
)
:echo %wday%
:echo %youbi%
バックアップは、こんな感じ
REM 環境変数のスコープをバッチ内に限定
Setlocal
set PGPASSWORD=%1%
set CURPATH=%~dp0
REM PostgreSQL インストール・ディレクトリ
set PGPATH=C:\Program Files\PostgreSQL\9.4\bin
REM バックアップ先ディレクトリ
set BKDIR=C:\DatabaseBackup
call %CURPATH%youbi.bat
REM mydb のバックアップを取る
"%PGPATH%\pg_dump.exe" -h localhost -p 5432 -U postgres -Fc -v -f%BKDIR%\%youbi%backup.dmp mydb 2> %BKDIR%\%youbi%backup.log
:"%PGPATH%\pg_dump.exe" -h localhost -p 5432 -U postgres -Fc -v -f%BKDIR%\%dayfile%backup.dmp mydb 2> %BKDIR%\%dayfile%backup.log
古いファイルを削除する手段がわかった
set BKDIR=C:\DatabaseBackup
forfiles /p %BKDIR% /m "*.dmp" /d -30 /c "cmd /c del /Q @file"
forfiles /p %BKDIR% /m "*.log" /d -30 /c "cmd /c del /Q @file"

2015年12月30日水曜日

Android Library の生産性の悪さ

年末に小ネタを Android 開発、生産性が悪いですね〜。自分は Java を生産性の低い言語だと考えてるのもあって、イライラもマックスですね。 Androidライブラリにリソースを組み込めないのも、生産性を下げる大きな要因だと思いませんか? DRY の原則を適応できない。 小ネタで、ログイン・ダイアログをライブラリ用として書いてみました。 Activity からは、下のような感じで呼出ます。
  showLoginDialog(this, new OnLoginListener() {
    @override
    public void onLogin(String name, String pass, int which) {
       if( DialogInterface.BUTTON_POSITIVE == which ) {
          if( validPassword(name, pass ) {
          } else {
          }
       } else {
          finish();
       }
    }
  });
import を略してすみませんが、以下の感じです。
  public interface OnLoginListener {
    public void onLogin(String name, String pass, final int which);
  }

  public static AlertDialog.Builder createLoginDialog(final Context context, final OnLoginListener l ) {
    final LinearLayout ll = new LinearLayout(context);
    final EditText userEditView = new EditText(context);
    final EditText passEditView = new EditText(context);
    final TextView tv1 = new TextView(context);
    final TextView tv2 = new TextView(context);
    final DialogInterface.OnClickListener ocl = new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialogInterface, int which) {
        l.onLogin(userEditView.getText().toString(), passEditView.getText().toString(), which);
      }
    };
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
    ll.setLayoutParams(params);
    ll.setOrientation(LinearLayout.VERTICAL);
    tv1.setText("USER:");
    userEditView.setInputType(android.text.InputType.TYPE_CLASS_TEXT);
    tv2.setText("PASSWORD:");
    passEditView.setInputType(android.text.InputType.TYPE_CLASS_TEXT);
    ll.addView(tv1);
    ll.addView(userEditView);
    ll.addView(tv2);
    ll.addView(passEditView);
    return new AlertDialog.Builder(context)
            .setIcon(android.R.drawable.ic_dialog_info)
            .setTitle("login")
            .setView(ll)
            .setPositiveButton(android.R.string.ok, ocl)
            .setNegativeButton(android.R.string.cancel, ocl);
  }

  public static void showLoginDialog(final Context context, final OnLoginListener l) {
    createLoginDialog(context,l).show();
  }
  
  

2015年12月15日火曜日

Windows版 PostGIS x64版の shp2pgsql が動かない

PostgreSQL は、x86 版のサーバを使用するよりも x64 版のサーバを使った方が良いんじゃないかなー?と思って、x64版をインストールしたんですわ。

そしたら、shp2pgsql が 0xc000007b とかエラー吐いて動かないとか言われました。
ググってみたら、この問題は、もう、かれこれ3年以上前から放置されています。
しかも回答者の認識も「 libiconv-2 は windows では使われてないから無くても大丈夫あるよ」てな感じで、脱力感が半端ない。
その他、あちこちで、この問題に関して質問されているけども、ほぼ放置プレー。

はいはい、またかよっ。

って、事で libiconv-2.dll の x64 版を、どこかから入手しなくては!
検索したら、dll のダウンロードサイトが軒並み引っかかりますが、この手のサイトから dll をダウンロードする勇気は、私にはありません。マルウェア配布の巣窟なんじゃないか?と思うのが普通の感覚でしょう。

はい、QGIS Lyon x64 版をインストールして

C:\Program Files\QGIS Lyon\apps\grass\grass-6.4.3\bin\libiconv-2.dll

を

C:\Program Files\PostgreSQL\9.4\bin

にコピーしましょう。


Postgis のメンテナーさんは、grass のメンテナーさんにコンタクトを取って、PostGISのインストーラに libiconv-2.dll をちゃんとバンドルした方が良いです。

2015年12月13日日曜日

MVNOを検討していてわかった事

自分の携帯は、ガラケーです。スマートフォンにすると通信料が高くつくので敬遠していました。 しかし、
  • ガラケーの端末が、強く閉じると電源OFFになってしまい、今にも壊れそう
  • 今時スマートフォンにしないとコミュニケーションにも支障をきたす
  • MVNOというサービスが出てきて通信費が手頃になってきた
というように、移行する条件が揃ってきたので、これを期にフリーSIMの使える端末について調べてみました。

 自分のライフスタイルに合ったスマートフォンというと、京セラのTORQUE G01, G02 あたりになります。ところが、こいつのフリーSIMの入手が厄介です。

 この機種は au から販売されていますが、フリーSIM化するためには、総務省の指針により購入後6ヶ月経過しないとダメです。auと契約しないで端末を購入できれば良いのですが、契約しないで端末を買う事はできません。

 中古の携帯が流通していて、その中で購入後6ヶ月以上経ってフリーSIM化されているものを買えば良い事になりますが、これがまたリスクが高い。フリーSIM化されていても、様々な要因で後から通信ロックを食らってしまう状況がある事がわかってきました。通信ロックを食らう状況は、以下のようなもの
  • 元の持ち主が手放した携帯がオレオレサギに利用され、その持ち主の携帯がブラックリスト扱いにされてしまう。
  • 元の持ち主が料金滞納をしてしまったため、巻き添えで通信制限を食らってしまう。
  • 元の持ち主が紛失したと嘘をついて携帯を売約したため、実はリモートロックがかかって外せない状態のまま
見ればわかるように、中古販売店からフリーSIM化された状態で買っても、いつ巻き添えを食って携帯が使えなくなってしまうか、予測できません。確率は低いにせよ、常に使えなくなる可能性があるわけです。
 こうやって考えて行くと、
  • 最初からフリーSIM化された機種を買う
  • 元の持ち主が判明していて、信頼できる携帯
の2択で行くのがリスクが無くて良いです。
スマートフォン、高いけど、リスクを考えたらフリーSIMの端末を選択するのが良さそうですね!
 Zenfone 2 なんか、コスパが良いなぁと思ってたんですが、日本の家電製品として販売するために取っておかないといけない「技適」マークを取得していないという理由で、MINEO の au プランで使えないんだとか…(使えるけど、使うと違反になる)

いやー、悶々としますね。

2015年10月25日日曜日

grep 拡張子を指定して検索 忘備録

自分用。 拡張子を指定して、今のディレクトリから hoge を再帰的に検索したい場合
$ grep hoge --include = "*.java" -r -n .