org.onepf.opfmaps.osmdroid.model.BitmapDescriptor.java Source code

Java tutorial

Introduction

Here is the source code for org.onepf.opfmaps.osmdroid.model.BitmapDescriptor.java

Source

/*
 * Copyright 2012-2015 One Platform Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.onepf.opfmaps.osmdroid.model;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;

import org.onepf.opfmaps.osmdroid.R;
import org.onepf.opfmaps.utils.CompareUtils;
import org.onepf.opfutils.OPFLog;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author Roman Savin
 * @since 17.08.2015
 */
public final class BitmapDescriptor implements Parcelable {

    private static final float DEFAULT_HUE = 3F;
    private static final float SATURATION = 0.73F;
    private static final float VALUE = 0.96F;

    public static final Creator<BitmapDescriptor> CREATOR = new Creator<BitmapDescriptor>() {
        @Override
        public BitmapDescriptor createFromParcel(final Parcel source) {
            return new BitmapDescriptor(source);
        }

        @Override
        public BitmapDescriptor[] newArray(final int size) {
            return new BitmapDescriptor[size];
        }
    };

    enum BitmapSource {
        DEFAULT, DEFAULT_HUE, ASSET, BITMAP, FILE_NAME, ABS_PATH, RES_ID
    }

    @NonNull
    private final BitmapSource source;
    @Nullable
    private final Bitmap image;
    @Nullable
    private final String path;
    private final float hue;
    private final int resourceId;

    BitmapDescriptor(@NonNull final BitmapSource source, @Nullable final Bitmap image, @Nullable final String path,
            final float hue, final int resourceId) {
        this.source = source;
        this.image = image;
        this.path = path;
        this.hue = hue;
        this.resourceId = resourceId;
    }

    private BitmapDescriptor(@NonNull final Parcel parcel) {
        this.source = BitmapSource.valueOf(parcel.readString());
        this.image = parcel.readParcelable(Bitmap.class.getClassLoader());
        this.path = parcel.readString();
        this.hue = parcel.readFloat();
        this.resourceId = parcel.readInt();
    }

    @NonNull
    public Drawable createDrawable(@NonNull final Context context) {
        Drawable drawable = null;
        switch (source) {
        case DEFAULT:
            drawable = createDefault(context, DEFAULT_HUE);
            break;
        case DEFAULT_HUE:
            drawable = createDefault(context, hue);
            break;
        case BITMAP:
            drawable = image == null ? null : new BitmapDrawable(context.getResources(), image);
            break;
        case ASSET:
        case FILE_NAME:
            drawable = createFromStream(context);
            break;
        case ABS_PATH:
            drawable = Drawable.createFromPath(path);
            break;
        case RES_ID:
            drawable = ContextCompat.getDrawable(context, resourceId);
            break;
        }

        return drawable == null ? createDefault(context, DEFAULT_HUE) : drawable;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(final Parcel dest, final int flags) {
        dest.writeString(source.name());
        dest.writeParcelable(image, flags);
        dest.writeString(path);
        dest.writeFloat(hue);
        dest.writeInt(resourceId);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        } else if (obj == null) {
            return false;
        } else if (this.getClass() != obj.getClass()) {
            return false;
        } else {
            BitmapDescriptor other = (BitmapDescriptor) obj;

            return this.source == other.source && CompareUtils.isEquals(this.image, other.image)
                    && CompareUtils.isEquals(this.source, other.source) && this.hue == other.hue
                    && this.resourceId == other.resourceId;
        }
    }

    @Override
    public int hashCode() {
        int result = source.hashCode();
        result = 31 * result + (image != null ? image.hashCode() : 0);
        result = 31 * result + (path != null ? path.hashCode() : 0);
        result = 31 * result + (hue != +0.0f ? Float.floatToIntBits(hue) : 0);
        result = 31 * result + resourceId;
        return result;
    }

    @NonNull
    private Drawable createDefault(@NonNull final Context context, final float hue) {
        final Drawable drawable = ContextCompat.getDrawable(context, R.drawable.ic_marker).mutate();
        drawable.setColorFilter(new PorterDuffColorFilter(Color.HSVToColor(new float[] { hue, SATURATION, VALUE }),
                PorterDuff.Mode.MULTIPLY));

        return drawable;
    }

    @Nullable
    private Drawable createFromStream(@NonNull final Context context) {
        OPFLog.logMethod();
        if (path == null) {
            return null;
        }

        InputStream inputStream = null;
        try {
            inputStream = createStream(context);
            return Drawable.createFromStream(inputStream, null);
        } catch (IOException e) {
            OPFLog.e(e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    OPFLog.e(e.getMessage());
                }
            }
        }
        return null;
    }

    @NonNull
    private InputStream createStream(@NonNull final Context context) throws IOException {
        if (path == null) {
            throw new IllegalArgumentException("Path can't be null");
        }

        switch (source) {
        case ASSET:
            return context.getAssets().open(path);
        case FILE_NAME:
            return context.openFileInput(path);
        }

        throw new IllegalArgumentException("Wrong source : " + source);
    }
}