Question

I'm using this store locator extension in my 2.3.1 local. I have 1000 stores in the backend imported by using CSV.

On the frontend, while I search that store address it should find the stores from that 1000 store which is working fine but it's taking a very long time to show on google map.

Here is the screenshot of my 1000 stores.

screenshot 2

Here is the screenshot of after I search the address It will load so much and then later it will show a map.

screenshot1

This is my Map.php Block file, I have this getRangeStoreCollection() to filter the entered address.I'm calling this function from .phtml file.

Map.php

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Vendor\CustomStoreLocator\Model\ManageStore $storeCollection,
) {
    $this->_storeCollection = $storeCollection;
    $this->_storeManager = $context->getStoreManager();
    parent::__construct($context);
}

public function getStoreId()
{
    return $this->_storeManager->getStore()->getId();
}

/**
 * Get store collection within range
 *
 * @return $collection
 */
public function getRangeStoreCollection($current, $distance)
{
    unset($collection);
    unset($StoreCollection);
    $storeId=$this->getStoreId();
    $storeIds=['0' =>'0','1'=>$storeId];
    $StoreCollection = $this->_storeCollection->getCollection()
                    ->addFieldToSelect(
                        array("store_id","storeId","latitude","longitude")
                    )
                    ->addFieldToFilter('storeId', ['in'=>$storeIds])
                    ->setOrder('position', 'ASC');
    // echo '<pre>';
    // var_dump($StoreCollection->getSize());
    $point = [];
    foreach ($StoreCollection as $store) {
        $point1='1';
        $point1=$this->getDistance($current, $store['latitude'], $store['longitude'], "K", $distance);
        if ($point1!='') {
            $point[]=$store['store_id'];
        }
    }
    if ($point instanceof Countable > 0) {
        $collection = $this->_storeCollection->getCollection()
                    ->addFieldToSelect(
                        array("store_id","sname","type","storeId","user_id","position","address","city","country","postcode","region","email","phone","link","storeurl","image","icon","latitude","longitude","sstatus")
                    )
                    ->addFieldToFilter('storeId', ['in'=>$storeIds])
                    ->addFieldToFilter('sstatus', 'Enabled')
                    ->addFieldToFilter('store_id', ['in' => [$point]])
                    ->setOrder('position', 'ASC');
        return $collection;
    } else {
        $point[] = 0;
        $collection = $this->_storeCollection->getCollection()
                    ->addFieldToSelect(
                        array("store_id","sname","type","storeId","user_id","position","address","city","country","postcode","region","email","phone","link","storeurl","image","icon","latitude","longitude","sstatus")
                    )
                    ->addFieldToFilter('sstatus', 'Enabled')
                    ->addFieldToFilter('storeId', ['in'=>$storeIds])
                    ->addFieldToFilter('store_id', ['in' => [$point]])
                    ->setOrder('position', 'ASC');
        return $collection;
    }
}

/**
 * return distance from current location to store location
 *
 * @return $km
 */
public function getDistance($addressFrom, $latitudeTo, $longitudeTo, $unit, $distance)
{
    unset($geocodeFrom);
    unset($formattedAddrFrom);
    //Change address format
    $formattedAddrFrom = str_replace(' ', '+', $addressFrom);
   
    //Send request and receive json data
    //@codingStandardsIgnoreStart
    $geocodeFrom=file_get_contents('https://maps.googleapis.com/maps/api/geocode/json?address='.$formattedAddrFrom.'&key='."MY_API_KEY");
    //@codingStandardsIgnoreEnd
    $outputFrom = json_decode($geocodeFrom);
    
    $latitudeFrom = $outputFrom->results[0]->geometry->location->lat;
    $longitudeFrom = $outputFrom->results[0]->geometry->location->lng;
    
    //Calculate distance from latitude and longitude
    $theta = $longitudeFrom - $longitudeTo;
    $dist = sin(
        deg2rad($latitudeFrom)
    )
        * sin(deg2rad($latitudeTo))
        +  cos(deg2rad($latitudeFrom)) * cos(deg2rad($latitudeTo))
        * cos(
            deg2rad($theta)
        );
    $dist = acos($dist);
    $dist = rad2deg($dist);
    $miles = $dist * 60 * 1.1515;
    $unit = strtoupper($unit);
    $km=($miles * 1.609344);
    if ($km<$distance) {
        return round($km);
    }
}

If anyone has any ideas, please let me know.

Was it helpful?

Solution

Finally, I figured out that the I was calling getDistance() every time in the collection as shown below code,

foreach ($StoreCollection as $store) {
        $point1='1';
        $point1=$this->getDistance($current, $store['latitude'], $store['longitude'], "K", $distance);
        if ($point1!='') {
            $point[]=$store['store_id'];
        }
    }

And this getDistance() is requesting the current address to google on every records in foreach() as shown below code,

$geocodeFrom=file_get_contents('https://maps.googleapis.com/maps/api/geocode/json?address='.$formattedAddrFrom.'&key='."MY_API_KEY");
    $outputFrom = json_decode($geocodeFrom);

so I moved this code to outside of foreach ($StoreCollection as $store) and checked then it was working fine.

public function getLatLngFromCurrentAddress($current)
{
    unset($geocodeFrom);
    unset($formattedAddrFrom);
    //Change address format
    $formattedAddrFrom = str_replace(' ', '+', $current);

    //Send request and receive json data
    //@codingStandardsIgnoreStart
    $geocodeFrom=file_get_contents('https://maps.googleapis.com/maps/api/geocode/json?address='.$formattedAddrFrom.'&key='.$this->getApiKey());
    //@codingStandardsIgnoreEnd
    $outputFrom = json_decode($geocodeFrom);
    $latlong = [];
    $latlong['latitudeFrom'] = $outputFrom->results[0]->geometry->location->lat;
    $latlong['longitudeFrom'] = $outputFrom->results[0]->geometry->location->lng;

    return $latlong;
}
/**
 * Get store collection within range
 *
 * @return $collection
 */
public function getRangeStoreCollection($current, $distance)
{
    unset($collection);
    unset($StoreCollection);
    $storeId=$this->getStoreId();
    $storeIds=['0' =>'0','1'=>$storeId];
    $StoreCollection = $this->_storeCollection->getCollection()
                    ->addFieldToFilter('storeId', ['in'=>$storeIds])
                    ->setOrder('position', 'ASC');
    $latlng = $this->getLatLngFromCurrentAddress($current); // I made this function to get the latlng from current address
    $point = [];
    foreach ($StoreCollection as $store) {
        $point1='1';
        $point1=$this->getDistance($latlng['latitudeFrom'], $latlng['longitudeFrom'], $store['latitude'], $store['longitude'], "K", $distance);
        if ($point1!='') {
            $point[]=$store['store_id'];
        }
    }
    if (count($point) > 0) {
        $collection = $this->_storeCollection->getCollection()
                    ->addFieldToFilter('storeId', ['in'=>$storeIds])
                    ->addFieldToFilter('sstatus', 'Enabled')
                    ->addFieldToFilter('store_id', ['in' => [$point]])
                    ->setOrder('position', 'ASC');
        return $collection;
    } else {
        $point[] = 0;
        $collection = $this->_storeCollection->getCollection()
                ->addFieldToFilter('sstatus', 'Enabled')
                ->addFieldToFilter('storeId', ['in'=>$storeIds])
                ->addFieldToFilter('store_id', ['in' => [$point]])
                ->setOrder('position', 'ASC');
        return $collection;
    }
}
public function getDistance($latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $unit, $distance)
{
    //Calculate distance from latitude and longitude
    $theta = $longitudeFrom - $longitudeTo;
    $dist = sin(
        deg2rad($latitudeFrom)
    )
        * sin(deg2rad($latitudeTo))
        +  cos(deg2rad($latitudeFrom)) * cos(deg2rad($latitudeTo))
        * cos(
            deg2rad($theta)
        );
    $dist = acos($dist);
    $dist = rad2deg($dist);
    $miles = $dist * 60 * 1.1515;
    $unit = strtoupper($unit);
    $km=($miles * 1.609344);
    if ($km<$distance) {
        return round($km);
    }
}

No more site loading. It showed me instant results. Hope it help.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top