moagrius / TileView

TileView is a subclass of android.view.ViewGroup that asynchronously displays, pans and zooms tile-based images. Plugins are available for features like markers, hotspots, and path drawing.
MIT License
1.46k stars 337 forks source link

I am Able to Zoom tileview but tileview gets hidden after full zoom #487

Closed shriharsha-bhagwat closed 6 years ago

shriharsha-bhagwat commented 6 years ago

I am using single image of size 1825 * 1650 in order to display my floorplan inside tileview like this. I have set tileview size also as 1825, 1650. I can zoom in and zoom out tileview. But when i fully zoom tileview, sometimes image inside tileview gets hidden and only markers remain. Again i have to zoom out in order to bring back image in tileview.

tileView = new TileView(this); ((RelativeLayout) findViewById(R.id.main_tile_layout)).addView(tileView); tileView.setId(R.id.tile_view); tileView.setBackgroundColor(getResources().getColor(R.color.chat_sender)); tileView.setSize(1825, 1650); tileView.setScale(0,2); tileView.addDetailLevel( 1.000f, "tiles/floorplan0/125/%d%d.png");

This is my activity layout code.

<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/chat_sender" android:fitsSystemWindows="true">

<RelativeLayout
    android:id="@+id/relative_Layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="40dp">

        <ImageView
            android:id="@+id/imgBack"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:layout_marginEnd="10dp"
            android:layout_marginStart="10dp"
            android:background="@drawable/ic_arrow_back_black_24dp"
            android:contentDescription="@string/app_name" />

        <TextView
            android:id="@+id/txtMember"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toEndOf="@+id/imgBack"
            android:text="@string/active_employees"
            android:textColor="@color/white"
            android:textSize="@dimen/mediumTextSize"
            android:textStyle="bold"
            tools:ignore="RelativeOverlap" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/main_tile_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/toolbar">

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/zoom_layout"
        android:layout_width="@dimen/dimen_45dp"
        android:layout_height="@dimen/dimen_90dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_marginBottom="@dimen/dimen_10dp"
        android:layout_marginEnd="@dimen/dimen_10dp">

        <ImageButton
            android:id="@+id/zoom_in"
            style="@style/StateButton"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_above="@+id/zoom_out"
            android:layout_centerHorizontal="true"
            android:contentDescription="@string/app_name"
            android:padding="@dimen/dimen_7dp"
            app:srcCompat="@drawable/ic_zoom_in" />

        <ImageButton
            android:id="@+id/zoom_out"
            style="@style/StateButton"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:contentDescription="@string/app_name"
            android:padding="@dimen/dimen_10dp"
            app:srcCompat="@drawable/ic_subtract" />

    </RelativeLayout>

</RelativeLayout>

</android.support.design.widget.CoordinatorLayout>

I am able to use pinch zoom, pan zoom or scale tileview. What am i doing wrong as image gets hidden and only markers remain in tileview sometimes?

screenshot_20180829-190241 screenshot_20180829-190248

moagrius commented 6 years ago

your bitmaps may be too large. instead of having scale 0 to 2 (which forces upsizing), keep scale 0 to 1, and try to double the size of your tiled image (but keep the tile size the same - so the number of tiles would increase).

if that doesn't work, post the project somewhere i can clone it and i'll take a look

shriharsha-bhagwat commented 6 years ago

Thanks for your reply. I tried out what u said. But it did not work for me. I would require your help. Can you please take a look at this project? http://androidbash.com/floorplan/FloorPlan.zip

shriharsha-bhagwat commented 6 years ago

I could solve it by using this class and loading image from byte Array.

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import com.qozix.tileview.graphics.BitmapProvider;
import com.qozix.tileview.tiles.Tile;
import com.wrkspot.employee.widget.media.utils.Utils;

public class BitmapProviderInternalStorage implements BitmapProvider {
private static final BitmapFactory.Options OPTIONS = new BitmapFactory.Options();

static {
    OPTIONS.inPreferredConfig = Bitmap.Config.RGB_565;
}

@Override
public Bitmap getBitmap(Tile tile, Context context) {
    byte[] data = (byte[]) tile.getData();
    if (data != null) {
        try {
            try {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;

                options.inSampleSize = Utils.calculateInSampleSize(options, tile.getWidth(), tile.getHeight());
                options.inJustDecodeBounds = false;

                return BitmapFactory.decodeByteArray(data, 0, data.length, options);
            } catch (OutOfMemoryError | Exception e) {
                // this is probably an out of memory error - you can try sleeping (this method won't be called in the UI thread) or try again (or give up)
                Log.e("BitmapProviderIntStrg", "Out of memory: " + e);
            }
        } catch (Exception e) {
            // this is probably an IOException, meaning the file can't be found
            Log.e("BitmapProviderIntStrg", "Error loading file: " + e);
        }
    }
    return null;
  }
}

private void generateTileView(int floorNumber) {
    byte[] decodedString = null;
    try {
        FloorPlanImageModel floorPlanImageModel = RealmManager.getInstance().getFloorPlanData();

        for (FloorPlanImageData imageData : floorPlanImageModel.getData()) {
            if (imageData.getFloorNumber().equalsIgnoreCase(String.valueOf(floorNumber))) {
                String encodedImage = imageData.getFile().getBody();
                decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
                break;
            }
        }
    } catch (Exception e) {
        Log.e(getLocalClassName(), "Could not decode bitmap");
    }

    tileView = new TileView(this);

    ((RelativeLayout) findViewById(R.id.main_tile_layout)).addView(tileView);
    tileView.setId(R.id.tile_view);
    tileView.setBackgroundColor(getResources().getColor(R.color.chat_sender));
    tileView.setSaveEnabled( true );
    tileView.setSize(1825, 1368);
    tileView.addDetailLevel(1.000f, decodedString, 1825, 1368);
    tileView.setMarkerAnchorPoints(-0.5f, -0.5f);
    tileView.setBitmapProvider(new BitmapProviderInternalStorage());
    tileView.setScaleLimits(0,2f);
    //tileView.setShouldRenderWhilePanning(true);

    tileView.setMarkerTapListener(mMarkerTapListener);

    tileView.setOnTouchListener(new View.OnTouchListener() {
        private static final int MAX_CLICK_DURATION = 200;
        private long startClickTime;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    startClickTime = Calendar.getInstance().getTimeInMillis();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
                    if (clickDuration < MAX_CLICK_DURATION) {
                        if (mTimePickerLayout.getVisibility() != View.VISIBLE) {
                            fadeInView(mFloorLayout);
                            fadeInView(mTimePickerLayout);
                        }
                    }
                }
            }
            return false;
        }
    });

}
shriharsha-bhagwat commented 6 years ago

Thank you for your amazing library. And i could solve all my issues except generating heatmap. Any help from your side for generating heatmap? Can you provide sample?

moagrius commented 6 years ago

i'll try to take a look at the project you posted this weekend (no promises though, it's a very busy time for me).

can you define what you mean by "heatmap"? do you want to place bitmaps (markers)? do you want to draw on the canvas? what specifically do you want to do? there are innumerable ways to define or implement that...

shriharsha-bhagwat commented 6 years ago

I can understand. Thanks for that you have told me that you will give a try. Any chance you can drop a mail for srbhagwatsrb@gmail.com ? I am extremely dependent on this library for my project. Basically i have loaded a single image in version 2.7.7. It works great. I could place markers. I could draw paths. Now for I need to generate a heatmap mostly similar to this link for any given list of (x,y) : https://img.gadgethacks.com/img/30/78/63548728113997/0/make-interactive-heat-maps-from-your-android-devices-location-history.1280x600.jpg

shriharsha-bhagwat commented 6 years ago

HI Mike, Let me know if you need anything from my side. In the above comment i have mentioned my email. Hope you get some time today or tomorrow. I would really need help of generating heatmap. http://androidbash.com/floorplan/FloorPlan.zip

moagrius commented 6 years ago

sorry, i haven't had a chance to get to this.

if you have the disappearing tile thing resolved, that's probably all i would be able to help with. there's definitely nothing built in for heatmaps. i'd use the drawing plugin which gives you access to the underlying tiled canvas, then just manage the heatmap graphic generation yourself

shriharsha-bhagwat commented 6 years ago

I will also try that. Do you know anyone who can help me with this? You can try whenever it is possible for you.

moagrius commented 6 years ago

No, I don't know anyone that could help you with that. I'd figure out how to draw it first, then try to adopt to the library.

shriharsha-bhagwat commented 6 years ago

Yeah i tried to draw from this. But i am not able to draw the same on to tileview. This is the same code as how Google map draws heatmap. Can you please try once in your free time?? That would be really helpful as i am not able to do this.
https://github.com/ChristianFF/HeatMapForAndroid/tree/master/app/src/main/java/com/ff/heatmap/heatmap

moagrius commented 6 years ago

Sorry this isn't really related to the library. You have access to the drawing canvas, which is should be sufficient. Good luck!

shriharsha-bhagwat commented 5 years ago

Any help on this issue? I am still stuck only with the heatmap part. Even i tried to integrate https://github.com/HeartlandSoftware/AndroidHeatMap with tileview. But somehow i am unable to get the result.

moagrius commented 5 years ago

sorry, this is not a feature that i'd include in the library