Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Changing CRS Does Not Rebuild Other Children #1322

Closed
5 tasks done
yang6626 opened this issue Jul 29, 2022 · 23 comments · Fixed by #1333
Closed
5 tasks done

[BUG] Changing CRS Does Not Rebuild Other Children #1322

yang6626 opened this issue Jul 29, 2022 · 23 comments · Fixed by #1333
Labels
bug This issue reports broken functionality or another error needs triage This new bug report needs reproducing and prioritizing

Comments

@yang6626
Copy link

What is the bug?

hi there

flutter_map: 2.0.0

in my case, i have 2 diffenert crs epsg4490 and epsg3857 , let's say we set it as 4490 in the first time and has a polyline on map. when i press a button to switch crs to 3857, the polyline disappear untill i move the map.

What is the expected behaviour?

the polyline still there when change crs.

How can we reproduce this issue?

FlutterMap(
              mapController: _mapController,
              options: MapOptions(
                  crs: _currentMapIndex == 0 ? epsg4490 : const Epsg3857(),
                  center: LatLng(23.388149672864074, 116.7156679026907),
                  interactiveFlags:
                      InteractiveFlag.all & ~InteractiveFlag.rotate,
                  zoom: 14,
                  minZoom: 0,
                  maxZoom: 22),
              children: [
                ..._buildBaseMap(),
                PolylineLayerWidget(
                    options: PolylineLayerOptions(polylines: [
                  Polyline(strokeWidth: 4, color: Colors.red, points: [
                    LatLng(23.3884495, 116.7191143),
                    LatLng(23.3806962, 116.7124767),
                    LatLng(23.3799523, 116.7246074),
                    LatLng(23.3716553, 116.7208881),
                  ])
                ])),
                Positioned(
                  bottom: 20,
                  left: 20,
                  child: TextButton(
                    onPressed: () {
                      _currentMapIndex = _currentMapIndex == 0 ? 1 : 0;
                      setState(() {});
                    },
                    child: const Text("切换"),
                  ),
                )
              ],
            )

Do you have a potential solution?

No response

Can you provide any other information?

No response

Platforms Affected

Android, iOS

Severity

Erroneous: Prevents normal functioning and causes errors in the console

Frequency

Consistently: Always occurs at the same time and location

Requirements

  • I agree to follow this project's Code of Conduct
  • My Flutter/Dart installation is unaltered, and flutter doctor finds no relevant issues
  • I am using the latest stable version of this package
  • I have checked the FAQs section on the documentation website
  • I have checked for similar issues which may be duplicates
@yang6626 yang6626 added bug This issue reports broken functionality or another error needs triage This new bug report needs reproducing and prioritizing labels Jul 29, 2022
@JaffaKetchup
Copy link
Member

Hi there, and thanks for your report.

This might be because the PolylineLayerWidget will not rebuild unless it is needs to, like all other Flutter widgets. To do this, you'll need to change the state of a property inside the widget.

May I suggest using a variable for the strokeWidth, and when you change the CRS, set the state of that variable to 3, then back to 4.

Let me know what happens!

@JaffaKetchup JaffaKetchup changed the title [BUG] dynamic crs [BUG] Changing CRS Does Not Rebuild Other Children Jul 29, 2022
@yang6626
Copy link
Author

yang6626 commented Aug 1, 2022

@JaffaKetchup sorry for being late;
i change the storkwidth when i press the switch button, polyline still not been rebuilded untill i move the map

@ibrierley
Copy link
Collaborator

You could probably just call mapController move with a 0.00001 different value instead of setState or something I would imagine (I feel like we should be able to force a mapController move, whatever, but it does for the moment have a check if it's not moved, not to do anything).

@JaffaKetchup
Copy link
Member

@ibrierley's suggestion will probably work, but I'm not sure that's fixing the underlying issue? If that's good enough for you, then that's great, if not, can you post your code from my suggestion.

@yang6626
Copy link
Author

yang6626 commented Aug 1, 2022

@ibrierley yes, i has tried this way at the first time but no luck;

@JaffaKetchup
Copy link
Member

Hmm that is strange. Can you post your code from your attempt at my suggestion please?

@yang6626
Copy link
Author

yang6626 commented Aug 1, 2022

@JaffaKetchup here is my code

FlutterMap(
              mapController: _mapController,
              options: MapOptions(
                  crs: _currentMapIndex == 0 ? epsg4490 : const Epsg3857(),
                  center: LatLng(23.388149672864074, 116.7156679026907),
                  interactiveFlags:
                      InteractiveFlag.all & ~InteractiveFlag.rotate,
                  zoom: 14,
                  minZoom: 0,
                  maxZoom: 22),
              children: [
                ..._buildBaseMap(),
                PolylineLayerWidget(
                    options: PolylineLayerOptions(polylines: [
                  Polyline(
                      strokeWidth: _strokeWidth,
                      color: Colors.red,
                      points: [
                        LatLng(23.3884495, 116.7191143),
                        LatLng(23.3806962, 116.7124767),
                        LatLng(23.3799523, 116.7246074),
                        LatLng(23.3716553, 116.7208881),
                      ])
                ])),
                Positioned(
                  bottom: 20,
                  left: 20,
                  child: TextButton(
                    onPressed: () {
                      _currentMapIndex = _currentMapIndex == 0 ? 1 : 0;
                      _strokeWidth = _currentMapIndex == 0 ? 6.0 : 3.0;
                      // _mapController.move(
                      //     LatLng(_mapController.center.latitude + 0.001,
                      //         _mapController.center.longitude + 0.001),
                      //     _mapController.zoom);
                      setState(() {});
                    },
                    child: const Text("切换"),
                  ),
                )
              ],
            )

flutter_map

@JaffaKetchup
Copy link
Member

Ok I see. Using the IDE tools, can you get your map to a situation where the polylines aren't showing, then manually use the hot reload button. What happens? Can you try this with none of our suggestions, my suggestion, and @ibrierley's suggestion.

@yang6626
Copy link
Author

yang6626 commented Aug 1, 2022

@JaffaKetchup
the same when press hot reload button
image

@ibrierley
Copy link
Collaborator

Can you paste a minimal example others can run (i.e _baseBuildMap etc is all missing)

@yang6626
Copy link
Author

yang6626 commented Aug 1, 2022

@mootw
Copy link
Collaborator

mootw commented Aug 3, 2022

#1333

using setState should now build all children correctly and may fix this issue as long as you setState the entire map when switching which looks like what you are doing

@yang6626
Copy link
Author

Hi @moonag, i had tried 3.0.0-beta.1 and the polyline still not shown when i changing the crs untill i move the map.

@ibrierley
Copy link
Collaborator

Out of interest, what happens if you call setState on the widget flutter_map is in ?

@yang6626
Copy link
Author

Out of interest, what happens if you call setState on the widget flutter_map is in ?

hi @ibrierley here is the example https://github.com/yang6626/flutter_map_crs.git, could you help to look at it. thanks a lot.

@ibrierley
Copy link
Collaborator

Interesting, and good spot.

I'm a bit baffled on this one. I can see the polyline rebuild paint get called each time (and interestingly paint gets called several tiles, even without any tilelayers, but that may well be normal). But yes, indeed it doesn't display, even with a setState, but a move does make it appear, so can confirm the issue.

Looking at the flutter inspector all looks ok, and interestingly if you remove the tileLayers it doesn't display either. Can't figure if I'm missing something obvious, but it's something we should certainly understand before 3.0

@ibrierley
Copy link
Collaborator

Looks a bit like map.getOffsetFromOrigin(point) gets strange y values before the move...so maybe its something like an old pixelOrigin being used in these circumstances...

I note if I do _pixelOrigin = getNewPixelOrigin(_center); inside getOffsetFromOrigin it fixes the issue...however, thats likely just papering over the issue of at what times that should get reset ?

@ibrierley
Copy link
Collaborator

Thinking out loud about this a bit more, I'm wondering if we should have a kind of "reset()" method... eg

Eg a soft reset
_pixelBounds = getPixelBounds(zoom);
_bounds = _calculateBounds();

Full reset (basically call those things that are in initState()) ?

@mootw
Copy link
Collaborator

mootw commented Aug 16, 2022

I have a fix for this issue. I wasn't updating pixel origin in setState of the map. It did get updated with the layout builder through updateSizeAndRotation, which (only gets called when the layout changes? I tested and it does fix the layer when I rotate the device).

I added the update to pixel origin to build of the map and the issue is now fixed. I think a recalculate method might make sense.

@JaffaKetchup
Copy link
Member

Maybe a reset stream, like is available on the TileLayer would be good, for the sake of consistency?

@mootw
Copy link
Collaborator

mootw commented Aug 16, 2022

Um not so much a reset stream, just inside of flutter map have a function with all of the values that need to update when the state of the map changes (setState, move, rotate, etc) and call that function whenever the values need to be updated. This way if new values are added or changed it only needs to happen in one spot.

@JaffaKetchup
Copy link
Member

Ah, sorry, I misunderstood the context. Yeah, this makes sense - reducing spaghetti and duplication is always a good idea!

@yang6626
Copy link
Author

@ibrierley @moonag @JaffaKetchup guys, i have try it from @moonag 's version and it works great. thanks all of you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue reports broken functionality or another error needs triage This new bug report needs reproducing and prioritizing
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants