Google Maps AndroidのPolylineに輪郭線をつける


Google Maps AndroidのPolylineはその他のShapeとは違い、strokeをサポートしていません。

このため、MapsアプリケーションのDirectionのようなものをPolylineで表現しようとすると「ここもう少しなんとかなりませんか？」という感じの見栄えになってしまいます。

![device-2016-01-08-195146 copy 3.png](https://qiita-image-store.s3.amazonaws.com/0/28822/94ad8739-d84a-2737-8775-da72636dbcef.png)



こんな感じにできませんか？と。

![device-2016-01-08-195349 copy 3.png](https://qiita-image-store.s3.amazonaws.com/0/28822/e91c7358-9692-981b-d062-4ed149445dac.png)


これを手軽に実現する方法があります。
以下のようにstrokeの色で塗ったpolylineを描画し、その上にfillの色で塗ったすこし細いpolylineを重ねることでstrokeを描画しているように見せかけます。

```java
void drawPolyline(GoogleMap googleMap, List<LatLng> positions) {
    int fillColor = ContextCompat.getColor(this, R.color.polylineFillColor);
    int strokeColor = ContextCompat.getColor(this, R.color.polylineStrokeColor);

    // strokeに見せかけるpolylineを描画する
    PolylineOptions strokeOptions = new PolylineOptions()
            .width(POLYLINE_WIDTH_IN_PIXELS)
            .color(strokeColor)
            .addAll(positions);
    googleMap.addPolyline(strokeOptions);

    // fillに見せかけるpolylineを描画する
    PolylineOptions fillOptions = new PolylineOptions()
            // strokeのwidth分細らせて、strokeに見せかけるpolylineが見えるようにする
            .width(POLYLINE_WIDTH_IN_PIXELS - POLYLINE_STROKE_WIDTH_IN_PIXELS * 2)
            .color(fillColor)
            .addAll(positions);

    googleMap.addPolyline(fillOptions);
}
```

毎度こういうことを書くのも匂い立つものがありますし、以下のようなstrokeをサポートするpolylineクラスをつくるのが良いでしょう。
こうしておけば公式にstrokeがサポートされた際のマイグレーションも容易でしょう。


```java
public class StrokedPolylineOptions implements Parcelable {

    private final PolylineOptions fill;
    private final PolylineOptions stroke;

    public StrokedPolylineOptions() {
        fill = new PolylineOptions();
        stroke = new PolylineOptions();
    }

    public StrokedPolylineOptions add(LatLng point) {
        fill.add(point);
        stroke.add(point);
        return this;
    }

    public StrokedPolylineOptions width(float width) {
        float strokeWidth = getStrokeWidth();
        fill.width(width - strokeWidth * 2);
        stroke.width(width);
        return this;
    }

    public StrokedPolylineOptions fillColor(int color) {
        fill.color(color);
        return this;
    }

    ... 省略

    public StrokedPolyline addPolylineTo(GoogleMap googleMap) {
        Polyline strokePolyline = googleMap.addPolyline(stroke);
        Polyline fillPolyline = googleMap.addPolyline(fill);
        return new StrokedPolyline(fillPolyline, strokePolyline);
    }
}
```

StrokedPolylineOptionsのようなクラスをつくっておけば、上述のdrawPolylineは直感的になります。

```java
void drawPolyline(GoogleMap googleMap, List<LatLng> positions) {
    int fillColor = ContextCompat.getColor(this, R.color.polylineFillColor);
    int strokeColor = ContextCompat.getColor(this, R.color.polylineStrokeColor);

    StrokedPolylineOptions options = new StrokedPolylineOptions()
            .width(POLYLINE_WIDTH_IN_PIXELS)
            .strokeColor(strokeColor)
            .strokeWidth(POLYLINE_STROKE_WIDTH_IN_PIXELS)
            .fillColor(fillColor)
            .width(POLYLINE_WIDTH_IN_PIXELS)
            .addAll(positions);
    options.addPolylineTo(googleMap);
}
```


以上。
サンプルコードは以下のGithubリポジトリを参照してください。

https://github.com/uPhyca/StrokedPolyline