explooosion / Agm-Direction

This is the directive for @agm/core (not official)
https://robby570.tw/Agm-Direction-Docs/
MIT License
75 stars 26 forks source link

Is there an option to render a existing direction without doing the API request? #24

Closed MichFe closed 6 years ago

MichFe commented 6 years ago

Hello Robby,

Your directive is just what I was looking for, thank you very much for sharing with us your work.

My question is if there is a way to give as an input to the directive a previously stored direction for it to render, so we don't have to make an API request for a route/direction that we have already done and stored in a database at some point.

Thank you in advance for your support, MF

explooosion commented 6 years ago

Glad to help. 🙂

Sorry, I don't fully understand. You mean you want to get the previous direction request?

For Example:

TS

const dir = this.direction.getPrev()
this.direction.render(dir) 
MichFe commented 6 years ago

May be I was a little vague, sorry.

I'm getting the response of the request by (onChange) event like this:

<agm-direction  *ngFor="let route of routes"
                    (onChange)="displayDirection($event)"
                    .....
                    }"></agm-direction>

After that I get the overview path from the returned object from the event:


displayDirection(evento){
 let inputPath=event.routes[0].overview_path;
//and iterate over the positions to save the lat and lng in a variable that I store on a data base service:

  let newPath:any[]=[];
    inputPath.forEach(point => {

      let lat=point.lat();
      let lng=point.lng();

      let coord={
        'lat':lat,
        'lng':lng
      }

      newPath.push(coord);

    });

   this.storeRoute(newPath);

And whenever I need to render again a route that I already requested before, I get the points of the route from my databade and use the agm-polyline and agm-polyline-point to render the rout on the map and avoid providing again the origin and destination to the agm-direction directive (To save some requests... damn request limits... XD)

 <agm-polyline [strokeWeight]=3
                  [visible]=true>

      <agm-polyline-point *ngFor="let point of path"
                          [latitude]="point.lat"
                          [longitude]="point.lng"></agm-polyline-point>

    </agm-polyline>

But I was thinking that it would be nice if I could just save the returned object from the (onChange) event of the agm-direction directive and give that object to the template by using an input attribute something like this:

<agm-direction *ngFor="let ruta of rutas" (onChange)="displayDirection($event)" [renderRoute]="ruta.routeObject" ........ }">

So we have both options to provide an origin and destination and normally do the request and render or provide the "[renderAttribute]" and skip the request and just render that direction object. This is to render stored routes and not just the previous route (I don't know if it is how it works or if even to just render an element you need to do a call to the google API).

explooosion commented 6 years ago

Oh, I see. let me think about it.

PS. Directions API Usage Limits 🤣

Here is an example without angular: https://codepen.io/ta7382/pen/RJNbPP?editors=0011

This is a good issue, I'll add.

MichFe commented 6 years ago

Thank you very much Robby,

Let me know if I can help in any way, I'm not any expert but I'm willing to learn and help 😄.

explooosion commented 6 years ago

Hi! @MichFe

Now you can install the latest version(0.7.3).

Example

Render from memory

HTML

<agm-map [latitude]="lat" [longitude]="lng">
<agm-direction
  [origin]="origin"
  [destination]="destination"
  [renderRoute]="renderRoute"
  (onResponse)="onResponse($event)"
>
</agm-direction>
</agm-map>

<button type="button" (click)="renderfromMemory(1)">Render1</button>
<button type="button" (click)="renderfromMemory(2)">Render2</button>

TypeScript

  public origin: any = 'Taichung Main Station';
  public destination: any = 'Taichung City Government';

  public renderRoute: object = null;

  public dir = [];

  async ngOnInit() {
    setTimeout(() => this.direction2(), 300);
  }

  private direction2() {
    this.origin = 'Taichung University of Science and Technology';
    this.destination = 'Taichung Main Station';
  }

  public onResponse(event: any) {
    this.dir.push(event);
  }

  public renderfromMemory(index: number) {
    // Render from memory
    this.renderRoute = this.dir[index];
  }

Render from json file

You can save the render result from [onResponse], and converting to JSON file. Finally, use http service to render the direction.

👉 Sample: JSON file

📌 Make sure you have already imported HttpModule

HTML

<agm-map [latitude]="lat" [longitude]="lng">
  <agm-direction
    [origin]="origin"
    [destination]="destination"
    [renderRoute]="renderRoute"
    (onResponse)="onResponse($event)"
  >
  </agm-direction>
</agm-map>

<button type="button" (click)="renderfromData(1)">Render1</button>
<button type="button" (click)="renderfromData(2)">Render2</button>
<button type="button" (click)="renderNew()">RenderNew</button>

TypeScript

import { Http } from '@angular/http';
  public renderRoute: object = null;

  public datas = [];

  constructor(private http: Http) {
    this.http.get('assets/data1.json').subscribe(result => { this.datas.push(result.json()); });
    this.http.get('assets/data2.json').subscribe(result => { this.datas.push(result.json()); });
  }

  public renderfromData(index: number) {
    // Render from json file (build from direction response)
    this.renderRoute = this.datas[index - 1];
  }

  public renderNew() {
    this.origin = 'Taichung Main Station';
    this.destination = 'Taichung University of Science and Technology';
    this.renderRoute = null;
  }
MichFe commented 6 years ago

Awesome,

Thank you very much for this feature @explooosion !!!

😄 🍻

dayvidkelly commented 4 years ago

Hello @explooosion , i was looking for the JSON file, but could not find it. Could you please show how to save the route even if the path is dragged?