{"id":18000369,"url":"https://github.com/amanjeetsingh150/ubercaranimation","last_synced_at":"2025-04-04T17:08:27.458Z","repository":{"id":61486668,"uuid":"98056782","full_name":"amanjeetsingh150/UberCarAnimation","owner":"amanjeetsingh150","description":"A demo app showing movement of car on map like in Uber.","archived":false,"fork":false,"pushed_at":"2019-12-07T11:32:23.000Z","size":1775,"stargazers_count":677,"open_issues_count":7,"forks_count":243,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-03-28T16:08:22.358Z","etag":null,"topics":["android","android-animation","animations","uber","value-animator"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amanjeetsingh150.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-22T20:40:51.000Z","updated_at":"2025-02-04T13:10:10.000Z","dependencies_parsed_at":"2022-10-19T22:15:24.421Z","dependency_job_id":null,"html_url":"https://github.com/amanjeetsingh150/UberCarAnimation","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amanjeetsingh150%2FUberCarAnimation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amanjeetsingh150%2FUberCarAnimation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amanjeetsingh150%2FUberCarAnimation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amanjeetsingh150%2FUberCarAnimation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amanjeetsingh150","download_url":"https://codeload.github.com/amanjeetsingh150/UberCarAnimation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247217184,"owners_count":20903009,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-animation","animations","uber","value-animator"],"created_at":"2024-10-29T23:11:34.990Z","updated_at":"2025-04-04T17:08:27.433Z","avatar_url":"https://github.com/amanjeetsingh150.png","language":"Java","funding_links":["https://www.paypal.me/amanjeetsingh150"],"categories":[],"sub_categories":[],"readme":"# UberCarAnimation\nA demo application which demonstrates movement of car on map developed after inspiration from Uber.\n\u003cbr\u003e\u003cbr\u003e\n# Demo\n\u003cimg src=\"https://user-images.githubusercontent.com/12881364/29244386-7f164cd6-7fd4-11e7-9d1a-13af7ee237ba.gif\"/\u003e\n\u003cbr\u003e\nYoutube Link: https://www.youtube.com/watch?v=JIs4kLZ8qQI\n\u003cbr\u003e\u003cbr\u003e\nAPIs and Libraries used\n\u003cUL\u003e\n\u003cLI\u003eGoogle Maps Api\u003c/LI\u003e\n\u003cLI\u003eGoogle Maps Directions API\u003c/LI\u003e\n\u003cLI\u003eVolley\u003c/LI\u003e\n\u003c/UL\u003e\n\n\u003cbr\u003e\u003cbr\u003e\n# Explained Logic\nSteps:\n\u003cUL\u003e\n\u003cLI\u003eParse the \"overview_polyline\" from the JSON by providing the appropriate GET parameters. For eg:\n\u003cpre\u003e\n\u003ccode\u003e\n\"https://maps.googleapis.com/maps/api/directions/json?\" +\n                    \"mode=driving\u0026\"\n                    + \"transit_routing_preference=less_driving\u0026\"\n                    + \"origin=\" + latitude + \",\" + longitude + \"\u0026\"\n                    + \"destination=\" + destination + \"\u0026\"\n                    + \"key=\" + getResources().getString(R.string.google_directions_key)\n\u003c/code\u003e\n\u003c/pre\u003e\n\u003c/LI\u003e\n\u003cLI\u003eDecode the polyline which will provide you with list of latitudes and longitudes that is List\u0026ltLatLng\u0026gt to be apt.\u003c/LI\u003e\n\u003cLI\u003eSetting up of Value animator:Create a value animator by providing the ofFloatValue, setting duration and adding update listener in Handler\n\u003cpre\u003e\n\u003ccode\u003e\nValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);\nvalueAnimator.setDuration(3000);\nvalueAnimator.setInterpolator(new LinearInterpolator());\nvalueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n  @Override\n  public void onAnimationUpdate(ValueAnimator valueAnimator) {\n    //CODE\n    \n});\n\u003c/code\u003e\n\u003c/pre\u003e\n\u003c/LI\u003e\n\u003cLI\u003eIn the value animator Update listener get the Animation fraction and evaluate the latitudes and longitudes as shown:\n\u003cpre\u003e\n\u003ccode\u003e\nv=valueAnimator.getAnimatedFraction();\nlng = v * endPosition.longitude + (1 - v)* startPosition.longitude;\nlat = v * endPosition.latitude + (1 - v)* startPosition.latitude;\n\u003c/code\u003e\n\u003c/pre\u003e\nwhere v is animation fraction\nand startposition and endPostion refer to each pair of LatLng from the decoded list from polyline for eg (0,1) then (1,2) then(2,3)\nand so on.\u003cbr\u003e\nAccording to linear interpolation:\nThe parameter 'v' defines where to estimate the value on the interpolated line, it is 0 at the first point and 1 and the second point. \nFor interpolated values between the two points v ranges between 0 and 1.\nWe evaluate values one by one between each pair of LatLng by traversing through the list.\n\u003c/LI\u003e\n\u003cLI\u003e\nFinally  set position of marker to the new position, also evaluating the bearing between the consecutive points so that it seems car is turning literally\nand finally update camera as:\n\u003cpre\u003e\n\u003ccode\u003e\nmarker.setPosition(newPos);\nmarker.setAnchor(0.5f, 0.5f);\nmarker.setRotation(getBearing(startPosition, newPos));\nmMap.moveCamera(CameraUpdateFactory\n                .newCameraPosition\n                (new CameraPosition.Builder()\n                target(newPos)\n                .zoom(15.5f)\n                .build()));\n\u003c/code\u003e\n\u003c/pre\u003e\n\u003c/LI\u003e\n\u003c/UL\u003e\n\n\n\u003cbr\u003e\u003cbr\u003e\n# Running the project\nThe application uses \u003cb\u003eGoogle Maps Api Key\u003c/b\u003e and \u003cb\u003eGoogle Map Directions key\u003c/b\u003e. Get these api key on google developers console after enabling them for your project. Replace your google maps directions api key in \u003ca href=\"https://github.com/amanjeetsingh150/UberCarAnimation/blob/master/app/src/main/res/values/strings.xml\"\u003estrings.xml\u003c/a\u003e and google maps key in \u003ca href=\"https://github.com/amanjeetsingh150/UberCarAnimation/blob/master/app/src/debug/res/values/google_maps_api.xml\"\u003egoogle_maps_api.xml\u003c/a\u003e. For convenience a TODO has been added there just follow them.\n\u003cbr\u003e\u003cbr\u003e\n\n# Driver mode\n\u003cimg src=\"https://user-images.githubusercontent.com/12881364/45456295-d4f0b900-b707-11e8-8067-e1adb9c98716.gif\" /\u003e\nThe driver mode is the real world example of the situation where the driver app is communicating with user app and the car is animating accordingly.\n\u003cbr\u003e\nYoutube Link: https://www.youtube.com/watch?v=-gTGJF7mZQI\n\u003cbr\u003e\nHere the \u003cb\u003epython script\u003c/b\u003e is acting like a driver for the user app.\n\u003cbr\u003e\u003cbr\u003e\n\n\n# Explained Logic\n\n\u003cUL\u003e\n\u003cLI\u003eEstablish a MQTT broker by logging into one of the MQTT providers. I used \u003ca href=\"https://customer.cloudmqtt.com/login\"\u003eCloudMQTT\u003c/a\u003e.\u003c/LI\u003e\n\u003cLI\u003eCreate the instance for MQTT and generate credentials.\u003c/LI\u003e\n\u003cLI\u003eIntegrate the \u003cb\u003eMQTT Paho Client\u003c/b\u003e for android by including following in your app module \u003ccode\u003ebuild.gradle\u003c/code\u003e:\n\u003cpre\u003e\nimplementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'\nimplementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'\n\u003c/pre\u003e\n\u003c/LI\u003e\n\u003cLI\u003eFill your credentials in \u003ccode\u003eMQTTHelper\u003c/code\u003e class. The username, password and the server URI which is of form tcp://uri:port.\u003c/LI\u003e\n\u003cLI\u003eSimilarly add them in \u003ccode\u003eUberMQTT.py\u003c/code\u003e file.\u003c/LI\u003e\n\u003cLI\u003eThe Python script will be acting as driver and publishing the location on MQTT server in \u003cb\u003eflex interval\u003c/b\u003e of 1 seconds using topic of \u003ccode\u003elocation/track\u003c/code\u003e.\nThe android app will connect to the broker and subscribe to the topic of kind \u003ccode\u003elocation/+\u003c/code\u003e. As soon as the MQTT server receives the location it will push it to the android client.\u003c/LI\u003e\n\u003cLI\u003eWe will receive location in form of String which will be converted to LatLng type by function \u003ccode\u003econvertStringToLatLng\u003c/code\u003e.\u003c/LI\u003e\n\u003cLI\u003eThen RxRelay is used to create stream of the LatLng's. Now as we need pair of LatLng for dispatching animation we will be taking \u003cb\u003ebuffer\u003c/b\u003e operator with count 2. This is shown below:\nIn \u003ccode\u003emessageReceived\u003c/code\u003e callback:\n\u003cpre\u003e\n@Override\npublic void messageArrived(String topic, MqttMessage message) throws Exception {\n String payload = new String(message.getPayload());\n LatLng currentLatLng = convertStringToLatLng(payload);\n Log.d(TAG, topic + \" \" + currentLatLng);\n latLngPublishRelay.accept(currentLatLng);\n}\n\u003c/pre\u003e\nAnd subscribing to this relay with buffer 2:\n\u003cpre\u003e\nlatLngPublishRelay\n   .buffer(2)\n   .observeOn(AndroidSchedulers.mainThread())\n   .subscribe(new Consumer\u003cList\u003cLatLng\u003e\u003e() {\n\n     @Override\n     public void accept(List\u003cLatLng\u003e latLngs) throws Exception {\n      emission++;\n      animateCarOnMap(latLngs);\n     }\n\n   });\n\u003c/pre\u003e\n\u003c/LI\u003e\n\u003cLI\u003eAs soon as the Relay will emit two LatLng the \u003ccode\u003eanimateCarOnMap\u003c/code\u003e function will dispatch animation through ValueAnimator. This animation will be based on same logic as was explained above.\u003c/LI\u003e\n\u003c/UL\u003e\n\n \n\n# Developers\n\u003cUL\u003e\n\u003cLI\u003e\u003ca href=\"https://github.com/amanjeetsingh150\"\u003eAmanjeet Singh\u003c/a\u003e\n\u003c/UL\u003e\n\u003cblockquote\u003e\nIf you found this code demo helpful or you learned something today and want to thank me, consider buying me a cup of :coffee: at\n\u003ca href=\"https://www.paypal.me/amanjeetsingh150\"\u003ePayPal\u003c/a\u003e\n\u003c/blockquote\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famanjeetsingh150%2Fubercaranimation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famanjeetsingh150%2Fubercaranimation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famanjeetsingh150%2Fubercaranimation/lists"}