dat-ng / ar-location-based-android

This AR app generally show where things are in the real-world by indicating where the app thinks they are over the camera view when the user holds the phone up and moves it about.
MIT License
206 stars 85 forks source link

onTouch() on AROverlayView for Multiple Markers not working #2

Open SyedKabeer opened 7 years ago

SyedKabeer commented 7 years ago

onTouch() on AROverlayView for Multiple Markers not working. I am adding multiple markers and trying to show different data on clicking the marker.

idrisbohra commented 7 years ago

hello @SyedKabeer, i also implemented multiple marker but they are collapsing with each other. Can you please help me out on this. Thank you.

dat-ng commented 7 years ago

Currently, I create AROverlayView extends View. In order to implement multiple marker and click for showing detail. You guys shoud extend from ViewGroup and use customizing view to replace for canvas

jxpx91 commented 7 years ago

Hi guys, I had the same issue and I solved with onTouchEvent method. First I create a global float array where I will storage the point X and Y location, then I fill it in onDraw method and finally in onTouchEvent I read touch X and Y and I compare those with the array with a little margin:


private float[][] pointsXY; // global variable
...

@Override
    protected void onDraw(Canvas canvas) {
        // Inicialize pointsXY 
        pointsXY = new float[arPoints.size()][2];
        ...
            pointsXY[i][0] = x;
            pointsXY[i][1] = y;
        ...
}

@Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        float x = event.getX();
        float y = event.getY();
        //Toast.makeText(context, "X: " + x + "\nY: " + y, Toast.LENGTH_SHORT).show();

        for(int i = 0; i < pointsXY.length; i++){
            float xPoint = pointsXY[i][0];
            float yPoint = pointsXY[i][1];
            if(x > xPoint - 100 && x < xPoint + 100){
                if(y > yPoint - 100 && y < yPoint + 100){
                    Toast.makeText(context, "Point clicked!", Toast.LENGTH_SHORT).show();
                }
            }
        }
        return false;
    }
idrisbohra commented 7 years ago

Thanks @jxpx91. My problem is my marker view is quiet big and the coordinates difference between them is too less which makes them collide with each other. I wish if the two coordinates are two close to each other one will come down and another come above it. For reference please see the images. Thank you.

Image without problem: img_0107

Image With problem: screenshot_20170715-172443

lancelopez commented 7 years ago

@idrisbohra Sir can you help me how to edit my marker? Or send the code of your marker. Please help me. Thanks

idrisbohra commented 7 years ago

Hi @lancelopez, in the onDraw(Canvas canvas) method of AROverlayView you can define your own canvas like canvas.drawLine, canvas.drawBitmap, canvas.drawText with respect to x and y coordinates. For more reference Please check this link :

https://drive.google.com/open?id=0Bzo_m-z-czi7c2pFTnZDY195SEk

Thanks,

lancelopez commented 7 years ago

Hi @idrisbohra, Thank you for your help. Can I ask where do you get this functions? getTime() getDistance() Does this functions are from ARPoint.class? Can you share also the class where this functions are created. Thank you in advance sir.

idrisbohra commented 7 years ago

Hi @lancelopez, getTime and getDistance are not the functions from this library. Those are my own to calculate time and distance. Please have a look below :

to calculate distance public String getDistance(){

float[] results = new float[2];
 android.location.Location.distanceBetween(currentLatitude, currentLongitude, objectLatitude, objectLongitude, results); 

float distanceFloat = Float.parseFloat(new DecimalFormat("##.##").format(results[0]));

if (distanceFloat > 1000) { Float final_distance = Float.parseFloat(new DecimalFormat("##.#").format(distanceFloat / 1000)); distanceStr = Float.toString(final_distance) + " kms"; } else { distanceStr = Float.toString(Math.round(distanceFloat)) + " m"; } return distanceStr;

}

to calculate time public String getTime(float distanceFloat){

//as per 3 kms per hour walking public static final double speed = 50.0;

if((int)(distanceFloat/speed)>60){


int timeInt = (int)(distanceFloat/speed)/60;

int remainingMinuteInt = (int) (distanceFloat / speed) % 60;

if (remainingMinuteInt != 0) {

timeStr = Integer.toString(timeInt) + " HRS" + " " + Integer.toString(remainingMinuteInt) + " MINS";
 } else {

timeStr = Integer.toString(timeInt) + " HRS";
 } 

}else {

 if (distanceFloat != 0) {

if ((int) ((distanceFloat / speed)) == 0) {

timeStr = "1 MINS";

} else { 
 timeStr = Integer.toString((int) ((distanceFloat / speed))) + " MINS";

}

} else {

timeStr = Integer.toString((int) ((distanceFloat / speed))) + " MINS";
 }
}

return timeStr;

}

candidobugarin commented 6 years ago

Hello, I'm finishing an application and sometimes the points I put are running on the screen, has anyone ever suffered from this?

NainalChauhan commented 6 years ago

Hi @idrisbohra , I am also having the problem of collapsing views. Did you find any solution for that?

HLneoh commented 6 years ago

@idrisbohra @SyedKabeer @dat-ng Does anyone know how to draw canvas in onTouch event? Thanks in advance.

NainalChauhan commented 6 years ago

@dat-ng How to use ViewGroup use customizing view to replace for canvas for multiple marker. Can you please give some example?

salime45 commented 6 years ago

you can inflate a xml view

        LinearLayout myView = (LinearLayout) factory.inflate(R.layout.card_layout, null);
        myView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("TAAAAG", "Click");

            }
        });

        this.addView(myView);
OmarShehe commented 5 years ago

Hi, Did you find any solution for collapsing views?

FhikarZul commented 4 years ago

Terima kasih @ jxpx91 . Masalah saya adalah tampilan penanda saya cukup besar dan perbedaan koordinat di antara keduanya terlalu sedikit sehingga membuat mereka saling bertabrakan. Saya berharap jika dua koordinat dua dekat satu sama lain akan turun dan satu lagi di atasnya. Untuk referensi silakan lihat gambar. Terima kasih.

Gambar tanpa masalah: img_0107

Gambar dengan masalah: tangkapan layar_20170715-172443

FhikarZul commented 4 years ago

sir can you explain how to make a marker like that ?? please help me sir. thank you

OmarShehe commented 4 years ago

sir can you explain how to make a marker like that ?? please help me sir. thank you

@FhikarZul Did you able to solve your issues, if no try this

//1  Initialize your view first    
private View initView(YourDataModel data) {
    View view = LayoutInflater.from(context).inflate(R.layout.ar_view, null, false);
    view.tvText.setText(data.getDescription());
    view.setOnClickListener(v -> {
        // do some thing
    });
    return view.getRoot();
}

** 2 Convert view to bitmap**
public static Bitmap getBitmapFromView(View view) {
    view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
    Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    view.draw(canvas);
    return bitmap;
}

**//3  On your constructor, bind your view first to your data model**
 for (YourDataModel data : YourDataModelList){
    data.setBitmap( getBitmapFromView(initView(data)));
}

**// 4 onDraw** 
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (currentLocation == null) {
        return;
    }

    for (YourDataModel data : YourDataModelList){
        float[] currentLocationInECEF = LocationHelper.WSG84toECEF(currentLocation);
        float[] pointInECEF = LocationHelper.WSG84toECEF(data.getLocation());
        float[] pointInENU = LocationHelper.ECEFtoENU(currentLocation, currentLocationInECEF, pointInECEF);

        float[] cameraCoordinateVector = new float[4];
        Matrix.multiplyMV(cameraCoordinateVector, 0, rotatedProjectionMatrix, 0, pointInENU, 0);

        if (cameraCoordinateVector[2] < 0) {
            float x  = (0.5f + cameraCoordinateVector[0]/cameraCoordinateVector[3]) * getWidth();
            float y = (0.5f - cameraCoordinateVector[1]/cameraCoordinateVector[3]) * getHeight();
            try {

                **// access your view and add X and Y coordinate** 
                canvas.drawBitmap(data.getView(),x,y,null);
            }catch (NullPointerException e){
                Log.d("AROverlayViewA",e.getMessage());
            }

        }
    }
}