<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Infinity Code Forum — Getting correct optimal zoom to fit all points within visible map area]]></title>
	<link rel="self" href="https://forum.infinity-code.com/extern.php?action=feed&amp;tid=2265&amp;type=atom" />
	<updated>2024-05-16T12:18:27Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.infinity-code.com/viewtopic.php?id=2265</id>
		<entry>
			<title type="html"><![CDATA[Re: Getting correct optimal zoom to fit all points within visible map area]]></title>
			<link rel="alternate" href="https://forum.infinity-code.com/viewtopic.php?pid=9537#p9537" />
			<content type="html"><![CDATA[<p>Ok, so the previous solution wasnt quite working for all resolutions and aspect ratios. I&#039;ve expanded the GetCenterPointAndZoom method to include both bottomLeft offset and topRight offset. And the condition looks like this:<br /></p><div class="codebox"><pre><code>if (px &lt; xLeftTileOffset || py &lt; yBottomTileOffset || px &gt; width - xRightTileOffset || py &gt; height - yTopTileOffset)
{
    success = false;
    break;
}</code></pre></div><p>And in my code I&#039;ve included another call to set position when I calculate the offset as in the <a href="https://forum.infinity-code.com/viewtopic.php?id=2209:">https://forum.infinity-code.com/viewtopic.php?id=2209:</a></p><div class="codebox"><pre><code>private void SetMapPositionAndZoom(List&lt;Vector2&gt; positions)
{
    Vector2 bottomLeftCrop = Vector2.zero;
    Vector2 topRightCrop = Vector2.zero;
    GameObject uiCanvas = GameObject.FindGameObjectWithTag(Global.Tags.UI_CANVAS);
    GameObject sidebarGO = GameObject.FindGameObjectWithTag(Global.Tags.SIDEBAR_PANEL);
    GameObject timelineGO = GameObject.FindGameObjectWithTag(Global.Tags.TIMELINE_PANEL);
    GameObject topPanelGO = GameObject.FindGameObjectWithTag(Global.Tags.TOP_PANEL);

    if (sidebarGO != null &amp;&amp; timelineGO != null &amp;&amp; uiCanvas != null &amp;&amp; topPanelGO != null)
    {
        SidebarController sc = sidebarGO.GetComponentInChildren&lt;SidebarController&gt;(true);
        TimelineController tc = timelineGO.GetComponentInChildren&lt;TimelineController&gt;(true);
        TopPanelController tpc = topPanelGO.GetComponentInChildren&lt;TopPanelController&gt;(true);
        RectTransform canvasRT = uiCanvas.GetComponent&lt;RectTransform&gt;();

        if (sc != null &amp;&amp; tc != null &amp;&amp; canvasRT != null)
        {
            Vector2 bottomLeftOffset = new Vector2(
               1.0f * (sc.expanded ? Global.Values.SIDEBAR_WIDTH_EXPANDED : Global.Values.SIDEBAR_WIDTH_COLLAPSED),
               1.0f * tc.myRT.sizeDelta.y);

            Vector2 topRightOffset = new Vector2(0f, tpc.GetComponent&lt;RectTransform&gt;().sizeDelta.y);

            Vector2 mapSize = new Vector2(OnlineMaps.instance.width, OnlineMaps.instance.height);

            bottomLeftCrop = (((mapSize - (canvasRT.sizeDelta * canvasRT.localScale)) / 2) + (bottomLeftOffset * canvasRT.localScale)) / mapSize;
            topRightCrop = (((mapSize - (canvasRT.sizeDelta * canvasRT.localScale)) / 2) + (topRightOffset * canvasRT.localScale)) / mapSize;
        }
    }

    OnlineMapsUtils.GetCenterPointAndZoom(positions.ToArray(), out Vector2 center, out int zoom, bottomLeftCrop, topRightCrop);
    OnlineMapsControlBase.instance.map.SetPositionAndZoom(center.x, center.y, zoom);

    SetMapPosition(bottomLeftCrop, topRightCrop);
}

private void SetMapPosition(Vector2 bottomLeftCrop, Vector2 topRightCrop)
{
    OnlineMaps.instance.projection.CoordinatesToTile(OnlineMaps.instance.position.x, OnlineMaps.instance.position.y, OnlineMaps.instance.zoom, out double tx, out double ty);
    tx -= (bottomLeftCrop.x - topRightCrop.x) * 0.5d * OnlineMaps.instance.width / OnlineMapsUtils.tileSize * OnlineMaps.instance.zoomFactor;
    ty += (bottomLeftCrop.y - topRightCrop.y) * 0.5d * OnlineMaps.instance.height / OnlineMapsUtils.tileSize * OnlineMaps.instance.zoomFactor;

    OnlineMaps.instance.SetTilePosition(tx, ty);
}</code></pre></div><p>This is still not working perfectly, sometimes it returns smaller zoom than it could (6 instead of 7). The reason is that the map position for the zoom calculation is just (min+max)/2, which is not correct in my application. The side offsets should be calculated into that. </p><p>If you have any idea if this can be done simpler/better please let me know. Thanks.</p>]]></content>
			<author>
				<name><![CDATA[mikli1]]></name>
				<uri>https://forum.infinity-code.com/profile.php?id=2745</uri>
			</author>
			<updated>2024-05-16T12:18:27Z</updated>
			<id>https://forum.infinity-code.com/viewtopic.php?pid=9537#p9537</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Getting correct optimal zoom to fit all points within visible map area]]></title>
			<link rel="alternate" href="https://forum.infinity-code.com/viewtopic.php?pid=9502#p9502" />
			<content type="html"><![CDATA[<p>Ok, I&#039;ve managed to get it working. </p><p>I&#039;ve added AdjustToScreen component, this way the tileset always covers my whole screen. I&#039;ve fixed the calculations and I&#039;m using the inset parameter to crop to view of the map. Unfortunately it crops the same ammount on left as on the right, but it is acceptable for me.</p><p>My code right now:</p><div class="codebox"><pre><code>if (sidebarGO != null &amp;&amp; uiCanvas != null)
{
    SidebarController sc = sidebarGO.GetComponentInChildren&lt;SidebarController&gt;(true);
    RectTransform canvasRT = uiCanvas.GetComponent&lt;RectTransform&gt;();

    if (sc != null &amp;&amp; canvasRT != null)
    {
        Vector2 offset = new Vector2(
            1.0f * (sc.expanded ? Global.Values.SIDEBAR_WIDTH_EXPANDED : Global.Values.SIDEBAR_WIDTH_COLLAPSED),
            1.0f * Global.Values.TIMELINE_HEIGHT_COLLAPSED);

        Vector2 mapSize = new Vector2(OnlineMaps.instance.width, OnlineMaps.instance.height);

        crop = (((mapSize - canvasRT.sizeDelta) / 2) + offset) / mapSize;
    }
}

OnlineMapsUtils.GetCenterPointAndZoom(positions.ToArray(), out Vector2 center, out int zoom, crop);
OnlineMapsControlBase.instance.map.SetPositionAndZoom(center.x, center.y, zoom);</code></pre></div><p>If you know how can I do it better (to use the space on the right, please let me know. Thanks.</p>]]></content>
			<author>
				<name><![CDATA[mikli1]]></name>
				<uri>https://forum.infinity-code.com/profile.php?id=2745</uri>
			</author>
			<updated>2024-04-26T06:33:12Z</updated>
			<id>https://forum.infinity-code.com/viewtopic.php?pid=9502#p9502</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Getting correct optimal zoom to fit all points within visible map area]]></title>
			<link rel="alternate" href="https://forum.infinity-code.com/viewtopic.php?pid=9501#p9501" />
			<content type="html"><![CDATA[<p>Hey, this problem is similar to the <a href="https://forum.infinity-code.com/viewtopic.php?id=2209">https://forum.infinity-code.com/viewtopic.php?id=2209</a></p><p>I have in my app top panel, sidebar and timeline panel, which take away some space of the screen - see the attached image. The sidebar can change width. </p><p>The map takes the remaining part of the screen. I&#039;m trying to center the map and calculate optimal zoom value to nicely see all of given points. </p><p>My map size is 2048x1536. In the tileset component size on the scene is also 2048x1536 - maybe that&#039;s a mistake? Can I change it in runtime?</p><p>My canvas is a screen space overlay canvas, with canvas scaler set to &quot;Scale with screen size + reference resolution is 1920x1080&quot;. </p><p>How can I make it work on all canvas/screen sizes and different aspect ratios? I&#039;ve noticed there is a Vector2 inset parametr in the OnlineMapsUtils.GetCenterPointAndZoom method, but I cannot make it work perfectly.</p><p>My current code:</p><div class="codebox"><pre><code>Vector2 crop = Vector2.zero;
GameObject uiCanvas = GameObject.FindGameObjectWithTag(Global.Tags.UI_CANVAS);
GameObject sidebarGO = GameObject.FindGameObjectWithTag(Global.Tags.SIDEBAR_PANEL);
if (sidebarGO != null &amp;&amp; uiCanvas != null)
{
    SidebarController sc = sidebarGO.GetComponentInChildren&lt;SidebarController&gt;(true);
    RectTransform canvasRT = uiCanvas.GetComponent&lt;RectTransform&gt;();

    if (sc != null &amp;&amp; canvasRT != null)
    {
        crop = new Vector2(
            1.0f * (sc.expanded ? SIDEBAR_WIDTH_EXPANDED : SIDEBAR_WIDTH_COLLAPSED) / canvasRT.sizeDelta.x,
            1.0f * TIMELINE_HEIGHT_COLLAPSED / canvasRT.sizeDelta.y);

        crop /= canvasRT.localScale.x;
    }
}

OnlineMapsUtils.GetCenterPointAndZoom(positions.ToArray(), out Vector2 center, out int zoom, crop);
OnlineMapsControlBase.instance.map.SetPositionAndZoom(center.x, center.y, zoom);</code></pre></div><p>How is the map positioned in the screen? Is the center of the map in the center of the screen? </p><p>Thanks for help.</p>]]></content>
			<author>
				<name><![CDATA[mikli1]]></name>
				<uri>https://forum.infinity-code.com/profile.php?id=2745</uri>
			</author>
			<updated>2024-04-25T12:20:46Z</updated>
			<id>https://forum.infinity-code.com/viewtopic.php?pid=9501#p9501</id>
		</entry>
</feed>
