0

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.

1 Answer 1

0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.